{
 "$schema": "https://json-schema.org/draft/2020-12/schema",
 "$id": "https://peakpassvpn.github.io/sail/schema.json",
 "title": "sail configuration",
 "description": "sail's native configuration format (sing-box v1.14.2 JSON and sail's extensions)",
 "type": "object",
 "properties": {
  "$schema": {
   "type": "string"
  },
  "log": {
   "$ref": "#/$defs/log"
  },
  "dns": {
   "$ref": "#/$defs/dns"
  },
  "ntp": {
   "$ref": "#/$defs/ntp",
   "description": "The time the protocols that check it go by, and certificates are verified at, measured against an NTP server; the system's clock is never set."
  },
  "certificate": {
   "$ref": "#/$defs/certificate",
   "description": "The root certificates servers are checked against; the system's when unset."
  },
  "certificate_providers": {
   "not": {},
   "description": "sail refuses this field: Certificates from ACME and other providers: the inbounds would serve none"
  },
  "http_clients": {
   "type": "array",
   "items": {
    "$ref": "#/$defs/http_clients%5B%5D"
   },
   "description": "How sail fetches over HTTP, rule-sets for one, by tag."
  },
  "network_namespaces": {
   "not": {},
   "description": "sail refuses this field: Linux network namespaces to listen and dial in"
  },
  "endpoints": {
   "type": "array",
   "items": {
    "type": "object",
    "properties": {
     "type": {
      "enum": [
       "wireguard"
      ]
     }
    },
    "allOf": [
     {
      "if": {
       "properties": {
        "type": {
         "const": "wireguard"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/endpoints%5Bwireguard%5D"
      }
     }
    ],
    "required": [
     "type"
    ]
   },
   "description": "Both an inbound and an outbound under one tag, as sing-box's endpoints: connections routed to the tag go out through it, and what comes in through it is routed with the tag as its inbound."
  },
  "inbounds": {
   "type": "array",
   "items": {
    "type": "object",
    "properties": {
     "type": {
      "enum": [
       "anytls",
       "direct",
       "hc",
       "http",
       "hysteria2",
       "mixed",
       "mptp",
       "nf",
       "redirect",
       "shadowsocks",
       "shadowtls",
       "socks",
       "tproxy",
       "trojan",
       "tuic",
       "tun",
       "vless",
       "vmess"
      ]
     }
    },
    "allOf": [
     {
      "if": {
       "properties": {
        "type": {
         "const": "anytls"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Banytls%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "direct"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bdirect%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "hc"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bhc%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "http"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bhttp%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "hysteria2"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bhysteria2%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "mixed"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bmixed%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "mptp"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bmptp%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "nf"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bnf%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "redirect"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bredirect%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "shadowsocks"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bshadowsocks%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "shadowtls"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bshadowtls%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "socks"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bsocks%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "tproxy"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Btproxy%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "trojan"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Btrojan%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "tuic"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Btuic%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "tun"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Btun%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "vless"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bvless%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "vmess"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/inbounds%5Bvmess%5D"
      }
     }
    ],
    "required": [
     "type"
    ]
   }
  },
  "outbounds": {
   "type": "array",
   "items": {
    "type": "object",
    "properties": {
     "type": {
      "enum": [
       "anytls",
       "block",
       "direct",
       "fallback",
       "http",
       "hysteria2",
       "load-balance",
       "mptp",
       "network",
       "pass",
       "plugin",
       "redirect",
       "selector",
       "shadowsocks",
       "shadowtls",
       "smart",
       "socks",
       "trojan",
       "tryall",
       "tuic",
       "urltest",
       "vless",
       "vmess"
      ]
     }
    },
    "allOf": [
     {
      "if": {
       "properties": {
        "type": {
         "const": "anytls"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Banytls%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "block"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bblock%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "direct"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bdirect%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "fallback"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bfallback%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "http"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bhttp%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "hysteria2"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bhysteria2%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "load-balance"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bload-balance%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "mptp"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bmptp%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "network"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bnetwork%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "pass"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bpass%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "plugin"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bplugin%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "redirect"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bredirect%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "selector"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bselector%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "shadowsocks"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bshadowsocks%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "shadowtls"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bshadowtls%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "smart"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bsmart%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "socks"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bsocks%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "trojan"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Btrojan%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "tryall"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Btryall%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "tuic"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Btuic%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "urltest"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Burltest%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "vless"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bvless%5D"
      }
     },
     {
      "if": {
       "properties": {
        "type": {
         "const": "vmess"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "$ref": "#/$defs/outbounds%5Bvmess%5D"
      }
     }
    ],
    "required": [
     "type"
    ]
   }
  },
  "route": {
   "$ref": "#/$defs/route"
  },
  "services": {
   "type": "array",
   "items": {
    "type": "object",
    "properties": {
     "type": {
      "enum": [
       "api"
      ]
     }
    },
    "allOf": [
     {
      "if": {
       "properties": {
        "type": {
         "const": "api"
        }
       },
       "required": [
        "type"
       ]
      },
      "then": {
       "deprecated": true,
       "description": "sail ignores this type, with a warning: sing-box's gRPC API, for its clients and dashboard to watch and control the instance"
      }
     }
    ],
    "required": [
     "type"
    ]
   }
  },
  "experimental": {
   "$ref": "#/$defs/experimental"
  },
  "api": {
   "$ref": "#/$defs/api",
   "description": "The control API"
  },
  "clash_api": {
   "$ref": "#/$defs/clash_api",
   "description": "The Clash API, which dashboards (yacd, metacubexd) and clients control the instance through. sing-box has it under `experimental`, which is read too, as the same."
  },
  "outbound_providers": {
   "type": "array",
   "items": {
    "$ref": "#/$defs/outbound_providers%5B%5D"
   },
   "description": "A sail extension: outbounds given together, downloaded, read from a file or written in place, that groups take as members, as Mihomo's proxy groups take a proxy-provider's proxies."
  },
  "user_limits": {
   "type": "object",
   "additionalProperties": {
    "$ref": "#/$defs/user_limits"
   },
   "description": "A sail extension: what each user, by name, may do across every inbound it is in."
  }
 },
 "additionalProperties": false,
 "$defs": {
  "api": {
   "type": "object",
   "properties": {
    "path": {
     "type": "string",
     "description": "The unix socket the API is served on, in the data directory unless absolute; `api.sock` there when neither it nor `listen` is set."
    },
    "listen": {
     "type": "string",
     "description": "A loopback address the API is served on too, as `127.0.0.1:9091`; it takes `secret`."
    },
    "secret": {
     "type": "string",
     "description": "What every call carries, as `Authorization: Bearer <secret>`: one `sail generate secret` makes. Needed with `listen`; on the unix socket, checked when set."
    }
   },
   "additionalProperties": false
  },
  "certificate": {
   "type": "object",
   "properties": {
    "store": {
     "type": "string",
     "enum": [
      "system",
      "mozilla",
      "chrome",
      "none"
     ]
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Inline PEM, its lines one to an entry or all in one."
    },
    "certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "certificate_directory_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Directories, every file of which holds certificates."
    }
   },
   "additionalProperties": false
  },
  "clash_api": {
   "type": "object",
   "properties": {
    "external_controller": {
     "type": "string",
     "description": "Where it listens, `host:port`; an empty host is every address, as in Mihomo. Unset, it is not served, though `default_mode` still sets the mode rules match."
    },
    "secret": {
     "type": "string",
     "description": "What callers authenticate with, `Authorization: Bearer`, or a WebSocket's `?token=`. The API is served only with a strong one (at least 32 characters, 10 distinct): `sail generate secret` makes one."
    },
    "external_ui": {
     "type": "string",
     "description": "A directory of a dashboard's files, served at `/ui/`; relative to the data directory."
    },
    "external_ui_download_url": {
     "type": "string",
     "description": "Where the dashboard is downloaded from, a ZIP, when `external_ui` is empty. The core has none of its own: unset, nothing is downloaded, and a warning says so; a host, such as sail-cli, may give one."
    },
    "external_ui_download_detour": {
     "type": "string",
     "description": "The outbound the download goes through; the default one when unset."
    },
    "access_control_allow_origin": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The origins browsers may call it from (CORS); any when empty."
    },
    "access_control_allow_private_network": {
     "type": "boolean",
     "description": "Pages on public addresses may call it on a private one (Private Network Access)."
    },
    "default_mode": {
     "type": "string",
     "description": "The mode rules match at the start, `Rule` when unset."
    }
   },
   "additionalProperties": false
  },
  "dns": {
   "type": "object",
   "properties": {
    "servers": {
     "type": "array",
     "items": {
      "type": "object",
      "properties": {
       "type": {
        "enum": [
         "fakeip",
         "h3",
         "hosts",
         "https",
         "local",
         "mdns",
         "quic",
         "race",
         "sequential",
         "tcp",
         "tls",
         "udp"
        ],
        "description": "`udp`, `tcp`, `tls`, `https`, `quic`, `h3`, `local`, `hosts`, or sail's `race` and `sequential`."
       }
      },
      "allOf": [
       {
        "if": {
         "properties": {
          "type": {
           "const": "fakeip"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Bfakeip%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "h3"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Bh3%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "hosts"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Bhosts%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "https"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Bhttps%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "local"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Blocal%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "mdns"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Bmdns%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "quic"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Bquic%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "race"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Brace%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "sequential"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Bsequential%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "tcp"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Btcp%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "tls"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Btls%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "udp"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.servers%5Budp%5D"
        }
       }
      ],
      "required": [
       "type"
      ]
     },
     "description": "The servers, each by its tag. None is the system's resolver alone."
    },
    "rules": {
     "type": "array",
     "items": {
      "type": "object",
      "properties": {
       "type": {
        "enum": [
         "logical",
         "default"
        ],
        "description": "`default`, or `logical`."
       }
      },
      "allOf": [
       {
        "if": {
         "properties": {
          "type": {
           "const": "logical"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/dns.rules%5Blogical%5D%2Bactions"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "enum": [
            "logical"
           ]
          }
         },
         "required": [
          "type"
         ]
        },
        "else": {
         "$ref": "#/$defs/dns.rules%5B%5D%2Bactions"
        }
       }
      ]
     },
     "description": "Which server a query goes to, matched in order."
    },
    "final": {
     "type": "string",
     "description": "The server of the queries no rule matches; the first one when unset."
    },
    "reverse_mapping": {
     "type": "boolean",
     "description": "Remembers the domain of each address the DNS answers that pass through carry, so that connections to the address are routed by the domain."
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "Which address families names resolve to, and in what order."
    },
    "timeout": {
     "type": "string",
     "description": "How long one query to one server may take; 10s when unset, as in sing-box."
    },
    "disable_cache": {
     "type": "boolean",
     "description": "No answer is kept: each query goes to its server."
    },
    "disable_expire": {
     "type": "boolean",
     "description": "Answers kept are used however old they are, until the cache is full or cleared."
    },
    "cache_capacity": {
     "type": "number",
     "description": "How many answers are kept; 1024 when unset, and at least that, as in sing-box."
    },
    "optimistic": {
     "anyOf": [
      {
       "type": "boolean"
      },
      {
       "$ref": "#/$defs/dns.optimistic"
      }
     ],
     "description": "An answer that has expired is still given, for up to its timeout, while the server is asked again in the background."
    },
    "client_subnet": {
     "type": "string",
     "description": "The EDNS Client Subnet each query carries, unless a rule says otherwise."
    },
    "independent_cache": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Each server's answers are kept apart, always: what this asks for"
    },
    "client_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "A sail extension: the address families the answers to clients' queries (hijack-dns, a DNS listener) carry, besides what `strategy` and the rules leave out: a family either leaves out is answered with no records. The instance's own lookups keep `strategy`. As Mihomo's `dns.ipv6: false` answers clients, while its connections still resolve IPv6."
    }
   },
   "additionalProperties": false
  },
  "dns.optimistic": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "timeout": {
     "type": "string",
     "description": "How long after it expired an answer may still be given; 3d when unset, as in sing-box."
    }
   },
   "additionalProperties": false
  },
  "dns.rules[][conditions]": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string",
     "enum": [
      "default",
      "logical"
     ],
     "description": "`default`, or `logical`."
    },
    "inbound": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of the inbounds the connection that needs the name came in through."
    },
    "ip_version": {
     "type": "number",
     "examples": [
      4,
      6
     ]
    },
    "query_type": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      {
       "type": "array",
       "items": {
        "anyOf": [
         {
          "type": "number"
         },
         {
          "type": "string"
         }
        ]
       }
      }
     ],
     "description": "Record types, by name (`A`, `AAAA`, `HTTPS`) or number."
    },
    "query_client_subnet": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "query_dnssec": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ]
    },
    "auth_user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Names of the users an inbound authenticated."
    },
    "protocol": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tls",
      "http",
      "quic",
      "dns",
      "stun",
      "bittorrent",
      "dtls",
      "ssh",
      "rdp",
      "ntp"
     ]
    },
    "domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_suffix": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_keyword": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_is_private": {
     "type": "boolean"
    },
    "source_port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "source_port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "user_id": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "clash_mode": {
     "type": "string",
     "description": "The mode of Clash's API, as in a routing rule."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ],
     "description": "The kind of network: `wifi`, `cellular`, `ethernet`, `other`."
    },
    "network_is_expensive": {
     "type": "boolean",
     "description": "The network is metered, as the system says."
    },
    "network_is_constrained": {
     "type": "boolean",
     "description": "The network is in a low data mode, as the system says."
    },
    "wifi_ssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The network the host is on, as the routing rules match it."
    },
    "wifi_bssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The address of the Wi-Fi access point, `aa:bb:cc:dd:ee:ff`, in any case, with `:` or `-`, or as 12 hex digits."
    },
    "interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "network_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "default_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "source_mac_address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "MAC addresses of the LAN device the query comes from, as the neighbor table and DHCP leases know it."
    },
    "source_hostname": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Host names of the LAN device the query comes from, as its DHCP lease has it."
    },
    "preferred_by": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of DNS servers: matches a name one of them prefers, one it answers for itself, as sing-box's `preferred_by`."
    },
    "rule_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of rule-sets, any of whose rules matching matches. Their `ip_cidr` rules match no query, which has no address yet."
    },
    "rule_set_ip_cidr_match_source": {
     "type": "boolean",
     "description": "The rule-sets' `ip_cidr` match the source address."
    },
    "match_response": {
     "anyOf": [
      {
       "type": "boolean"
      },
      {
       "type": "string"
      }
     ],
     "description": "The response of an `evaluate` rule before it, which the rule then matches: its addresses are what `ip_cidr`, `ip_is_private`, `ip_accept_any` and the rule-sets' `ip_cidr` match. With none, the rule matches only inverted."
    },
    "ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "ip_is_private": {
     "type": "boolean"
    },
    "ip_accept_any": {
     "type": "boolean",
     "description": "The response has an address."
    },
    "response_rcode": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ]
    },
    "response_answer": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Records the response has among its answers, as `answer` writes them: any of them."
    },
    "response_ns": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Records the response has among its name servers."
    },
    "response_extra": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Records the response has among its additional records."
    },
    "invert": {
     "type": "boolean"
    },
    "outbound": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of the outbounds that dial the name; of the rule itself, not of a rule a logical one combines.",
     "deprecated": true
    },
    "rule_set_ip_cidr_accept_empty": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "geosite": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as in a routing rule."
    },
    "external": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as in a routing rule: `site:<file>:<code>`."
    },
    "process_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as Mihomo's `PROCESS-NAME-REGEX`: regular expressions the program's name, its path's last part, matches."
    },
    "wifi_ssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `SSID:`: regular expressions found in the Wi-Fi network's name, with case."
    },
    "wifi_bssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `BSSID:`: regular expressions found in the access point's address as `aa:bb:cc:dd:ee:ff`, whatever the case."
    },
    "network_gateway": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `ROUTER:`: the address of the default gateway."
    },
    "network_mcc_mnc": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `MCCMNC:` and `CELLULAR-CARRIER`: the cellular carrier, its MCC and MNC as 5 or 6 digits; only off Wi-Fi."
    },
    "ip_match_all": {
     "type": "boolean",
     "description": "A sail extension: the rule's conditions on the response's addresses hold for every one of them, rather than for any; a response without one they hold for none. Mihomo's fallback filter keeps an answer so."
    }
   },
   "additionalProperties": false
  },
  "dns.rules[]+actions": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string",
     "enum": [
      "default",
      "logical"
     ],
     "description": "`default`, or `logical`."
    },
    "inbound": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of the inbounds the connection that needs the name came in through."
    },
    "ip_version": {
     "type": "number",
     "examples": [
      4,
      6
     ]
    },
    "query_type": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      {
       "type": "array",
       "items": {
        "anyOf": [
         {
          "type": "number"
         },
         {
          "type": "string"
         }
        ]
       }
      }
     ],
     "description": "Record types, by name (`A`, `AAAA`, `HTTPS`) or number."
    },
    "query_client_subnet": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "query_dnssec": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ]
    },
    "auth_user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Names of the users an inbound authenticated."
    },
    "protocol": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tls",
      "http",
      "quic",
      "dns",
      "stun",
      "bittorrent",
      "dtls",
      "ssh",
      "rdp",
      "ntp"
     ]
    },
    "domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_suffix": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_keyword": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_is_private": {
     "type": "boolean"
    },
    "source_port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "source_port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "user_id": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "clash_mode": {
     "type": "string",
     "description": "The mode of Clash's API, as in a routing rule."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ],
     "description": "The kind of network: `wifi`, `cellular`, `ethernet`, `other`."
    },
    "network_is_expensive": {
     "type": "boolean",
     "description": "The network is metered, as the system says."
    },
    "network_is_constrained": {
     "type": "boolean",
     "description": "The network is in a low data mode, as the system says."
    },
    "wifi_ssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The network the host is on, as the routing rules match it."
    },
    "wifi_bssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The address of the Wi-Fi access point, `aa:bb:cc:dd:ee:ff`, in any case, with `:` or `-`, or as 12 hex digits."
    },
    "interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "network_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "default_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "source_mac_address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "MAC addresses of the LAN device the query comes from, as the neighbor table and DHCP leases know it."
    },
    "source_hostname": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Host names of the LAN device the query comes from, as its DHCP lease has it."
    },
    "preferred_by": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of DNS servers: matches a name one of them prefers, one it answers for itself, as sing-box's `preferred_by`."
    },
    "rule_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of rule-sets, any of whose rules matching matches. Their `ip_cidr` rules match no query, which has no address yet."
    },
    "rule_set_ip_cidr_match_source": {
     "type": "boolean",
     "description": "The rule-sets' `ip_cidr` match the source address."
    },
    "match_response": {
     "anyOf": [
      {
       "type": "boolean"
      },
      {
       "type": "string"
      }
     ],
     "description": "The response of an `evaluate` rule before it, which the rule then matches: its addresses are what `ip_cidr`, `ip_is_private`, `ip_accept_any` and the rule-sets' `ip_cidr` match. With none, the rule matches only inverted."
    },
    "ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "ip_is_private": {
     "type": "boolean"
    },
    "ip_accept_any": {
     "type": "boolean",
     "description": "The response has an address."
    },
    "response_rcode": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ]
    },
    "response_answer": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Records the response has among its answers, as `answer` writes them: any of them."
    },
    "response_ns": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Records the response has among its name servers."
    },
    "response_extra": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Records the response has among its additional records."
    },
    "invert": {
     "type": "boolean"
    },
    "outbound": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of the outbounds that dial the name; of the rule itself, not of a rule a logical one combines.",
     "deprecated": true
    },
    "rule_set_ip_cidr_accept_empty": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "action": {
     "type": "string",
     "enum": [
      "route",
      "evaluate",
      "respond",
      "route-options",
      "reject",
      "predefined"
     ],
     "description": "`route` when unset."
    },
    "geosite": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as in a routing rule."
    },
    "external": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as in a routing rule: `site:<file>:<code>`."
    },
    "process_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as Mihomo's `PROCESS-NAME-REGEX`: regular expressions the program's name, its path's last part, matches."
    },
    "wifi_ssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `SSID:`: regular expressions found in the Wi-Fi network's name, with case."
    },
    "wifi_bssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `BSSID:`: regular expressions found in the access point's address as `aa:bb:cc:dd:ee:ff`, whatever the case."
    },
    "network_gateway": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `ROUTER:`: the address of the default gateway."
    },
    "network_mcc_mnc": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `MCCMNC:` and `CELLULAR-CARRIER`: the cellular carrier, its MCC and MNC as 5 or 6 digits; only off Wi-Fi."
    },
    "ip_match_all": {
     "type": "boolean",
     "description": "A sail extension: the rule's conditions on the response's addresses hold for every one of them, rather than for any; a response without one they hold for none. Mihomo's fallback filter keeps an answer so."
    },
    "race": {
     "type": "boolean",
     "description": "`route`, `respond`, `reject` and `predefined`, on a response: the rules after it are matched while its responses are still coming, and the first race rule to match, once they have, decides; the others' actions wait until none of the race rules before them matched. As sing-box 1.14's."
    },
    "server": {
     "type": "string",
     "description": "`route`: the server a matching query goes to."
    },
    "tag": {
     "type": "string",
     "description": "`evaluate`: the name of its response, which `match_response` gives."
    },
    "speculative": {
     "type": "boolean",
     "description": "`route` and `evaluate`: the query is sent as soon as the rule matches, while race rules before it are still pending, rather than once none of them matched; its response is used only then."
    },
    "timeout": {
     "type": "string",
     "description": "How long the query may take, instead of `dns.timeout`."
    },
    "disable_cache": {
     "type": "boolean",
     "description": "`route`, `evaluate` and `route-options`: the query neither comes from the cache nor goes into it."
    },
    "disable_optimistic_cache": {
     "type": "boolean",
     "description": "An expired answer is not given while it is asked for again, though `dns.optimistic` is enabled."
    },
    "rewrite_ttl": {
     "type": "number",
     "description": "The TTL the answer's records carry, in seconds."
    },
    "client_subnet": {
     "type": "string",
     "description": "The EDNS Client Subnet the query carries, instead of `dns.client_subnet`."
    },
    "remove_client_subnet": {
     "type": "boolean",
     "description": "The query carries no EDNS Client Subnet, whatever it or `dns.client_subnet` has."
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "`route`: the address families, instead of `dns.strategy`.",
     "deprecated": true
    },
    "rcode": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`predefined`: the code of the answer, NOERROR when unset."
    },
    "answer": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`predefined`: the answer's records, as a zone file writes them (`localhost. IN A 127.0.0.1`, TTL 3600 unless given), or the base64 of their wire form; one named `*.suffix.` takes the name asked for when it ends so."
    },
    "ns": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`predefined`: its name server records."
    },
    "extra": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`predefined`: its additional records."
    },
    "method": {
     "type": "string",
     "examples": [
      "default",
      "drop",
      "reply"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How a rejected query is answered: it is rejected all the same"
    },
    "no_drop": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How a rejected query is answered: it is rejected all the same"
    }
   },
   "additionalProperties": false
  },
  "dns.rules[logical][nested]": {
   "type": "object",
   "properties": {
    "mode": {
     "type": "string",
     "enum": [
      "and",
      "or"
     ],
     "description": "`logical`: `and` or `or`."
    },
    "rules": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/dns.rules%5Bnested%5D"
     },
     "description": "`logical`: the rules combined."
    },
    "invert": {
     "type": "boolean"
    },
    "type": {
     "const": "logical"
    }
   },
   "additionalProperties": false,
   "required": [
    "mode",
    "rules"
   ]
  },
  "dns.rules[logical]+actions": {
   "type": "object",
   "properties": {
    "mode": {
     "type": "string",
     "enum": [
      "and",
      "or"
     ],
     "description": "`logical`: `and` or `or`."
    },
    "rules": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/dns.rules%5Bnested%5D"
     },
     "description": "`logical`: the rules combined."
    },
    "invert": {
     "type": "boolean"
    },
    "action": {
     "type": "string",
     "enum": [
      "route",
      "evaluate",
      "respond",
      "route-options",
      "reject",
      "predefined"
     ],
     "description": "`route` when unset."
    },
    "race": {
     "type": "boolean",
     "description": "`route`, `respond`, `reject` and `predefined`, on a response: the rules after it are matched while its responses are still coming, and the first race rule to match, once they have, decides; the others' actions wait until none of the race rules before them matched. As sing-box 1.14's."
    },
    "server": {
     "type": "string",
     "description": "`route`: the server a matching query goes to."
    },
    "tag": {
     "type": "string",
     "description": "`evaluate`: the name of its response, which `match_response` gives."
    },
    "speculative": {
     "type": "boolean",
     "description": "`route` and `evaluate`: the query is sent as soon as the rule matches, while race rules before it are still pending, rather than once none of them matched; its response is used only then."
    },
    "timeout": {
     "type": "string",
     "description": "How long the query may take, instead of `dns.timeout`."
    },
    "disable_cache": {
     "type": "boolean",
     "description": "`route`, `evaluate` and `route-options`: the query neither comes from the cache nor goes into it."
    },
    "disable_optimistic_cache": {
     "type": "boolean",
     "description": "An expired answer is not given while it is asked for again, though `dns.optimistic` is enabled."
    },
    "rewrite_ttl": {
     "type": "number",
     "description": "The TTL the answer's records carry, in seconds."
    },
    "client_subnet": {
     "type": "string",
     "description": "The EDNS Client Subnet the query carries, instead of `dns.client_subnet`."
    },
    "remove_client_subnet": {
     "type": "boolean",
     "description": "The query carries no EDNS Client Subnet, whatever it or `dns.client_subnet` has."
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "`route`: the address families, instead of `dns.strategy`.",
     "deprecated": true
    },
    "rcode": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`predefined`: the code of the answer, NOERROR when unset."
    },
    "answer": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`predefined`: the answer's records, as a zone file writes them (`localhost. IN A 127.0.0.1`, TTL 3600 unless given), or the base64 of their wire form; one named `*.suffix.` takes the name asked for when it ends so."
    },
    "ns": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`predefined`: its name server records."
    },
    "extra": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`predefined`: its additional records."
    },
    "method": {
     "type": "string",
     "examples": [
      "default",
      "drop",
      "reply"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How a rejected query is answered: it is rejected all the same"
    },
    "no_drop": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How a rejected query is answered: it is rejected all the same"
    },
    "type": {
     "const": "logical"
    }
   },
   "additionalProperties": false,
   "required": [
    "mode",
    "rules"
   ]
  },
  "dns.rules[nested]": {
   "type": "object",
   "properties": {
    "type": {
     "enum": [
      "default",
      "logical"
     ]
    }
   },
   "allOf": [
    {
     "if": {
      "properties": {
       "type": {
        "const": "logical"
       }
      },
      "required": [
       "type"
      ]
     },
     "then": {
      "$ref": "#/$defs/dns.rules%5Blogical%5D%5Bnested%5D"
     },
     "else": {
      "$ref": "#/$defs/dns.rules%5B%5D%5Bconditions%5D"
     }
    }
   ]
  },
  "dns.servers[fakeip]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "inet4_range": {
     "type": "string"
    },
    "inet6_range": {
     "type": "string"
    },
    "type": {
     "const": "fakeip"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[h3]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Bh3%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "tls": {
     "$ref": "#/$defs/dns.servers%5Bh3%5D.tls",
     "description": "`tls`, `https`, `quic` and `h3`."
    },
    "path": {
     "type": "string",
     "description": "`https` and `h3`."
    },
    "method": {
     "type": "string",
     "description": "`https` and `h3`: `POST`, the default, or `GET` (RFC 8484 §4.1)."
    },
    "headers": {
     "type": "object",
     "description": "`https` and `h3`: sent with each request; a `Host` one is the host the requests name."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "respect_rules": {
     "type": "boolean",
     "description": "A sail extension, as Mihomo's `respect-rules`: the connections go through the outbound the routing rules pick for them, as for a connection from the inbound `dnsclient` to the server, its domain known."
    },
    "client_subnet": {
     "$ref": "#/$defs/dns.servers%5Bh3%5D.client_subnet",
     "description": "A sail extension: the EDNS Client Subnet its queries carry, over any they have, as Mihomo's `ecs` with `ecs-override`."
    },
    "type": {
     "const": "h3"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[h3].client_subnet": {
   "type": "object",
   "properties": {
    "addr": {
     "type": "string"
    },
    "len": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[h3].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "dns.servers[h3].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: A h3 server offers its own"
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only for fragmenting the TLS handshake, which sail does not do"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: Not for a h3 server"
    },
    "reality": {
     "$ref": "#/$defs/dns.servers%5Bh3%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "dns.servers[h3].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[h3].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[h3].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Not for a h3 server"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: Not for a h3 server"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[hosts]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Files in the hosts format; the system's own when neither these nor `predefined` are given."
    },
    "predefined": {
     "type": "object",
     "description": "Names, and their addresses. A sail extension, as Mihomo's `hosts` has it: a name may be a pattern, `+.a` for a and the names under it, `.a` for those under it alone, a `*` label for any one label; and it may be given another name, whose addresses it takes."
    },
    "type": {
     "const": "hosts"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[https]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Bhttps%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "tls": {
     "$ref": "#/$defs/dns.servers%5Bhttps%5D.tls",
     "description": "`tls`, `https`, `quic` and `h3`."
    },
    "path": {
     "type": "string",
     "description": "`https` and `h3`."
    },
    "method": {
     "type": "string",
     "description": "`https` and `h3`: `POST`, the default, or `GET` (RFC 8484 §4.1)."
    },
    "headers": {
     "type": "object",
     "description": "`https` and `h3`: sent with each request; a `Host` one is the host the requests name."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "respect_rules": {
     "type": "boolean",
     "description": "A sail extension, as Mihomo's `respect-rules`: the connections go through the outbound the routing rules pick for them, as for a connection from the inbound `dnsclient` to the server, its domain known."
    },
    "client_subnet": {
     "$ref": "#/$defs/dns.servers%5Bhttps%5D.client_subnet",
     "description": "A sail extension: the EDNS Client Subnet its queries carry, over any they have, as Mihomo's `ecs` with `ecs-override`."
    },
    "prefer_h3": {
     "type": "boolean",
     "description": "`https`: a sail extension, as Mihomo's `prefer-h3`: queries go over HTTP/3 beside HTTP/2, and over HTTP/3 alone once it answers; over HTTP/2 for a while once it fails."
    },
    "type": {
     "const": "https"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[https].client_subnet": {
   "type": "object",
   "properties": {
    "addr": {
     "type": "string"
    },
    "len": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[https].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "dns.servers[https].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: A https server offers its own"
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only for fragmenting the TLS handshake, which sail does not do"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "utls": {
     "$ref": "#/$defs/dns.servers%5Bhttps%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/dns.servers%5Bhttps%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "dns.servers[https].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[https].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[https].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "dns.servers[local]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Blocal%5D.domain_resolver"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve. The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "prefer_go": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go's own resolver rather than the system's: sail is not Go"
    },
    "neighbor_domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Suffixes, each starting with `.`, of the single-label names the LAN devices' addresses answer for, as sing-box's local server has them; `.` for bare single-label names."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve. sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before."
    },
    "type": {
     "const": "local"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[local].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve"
    },
    "timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve"
    },
    "disable_cache": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve"
    },
    "disable_optimistic_cache": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve"
    },
    "rewrite_ttl": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve"
    },
    "client_subnet": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: A local server's servers are the system's, addresses: it has no name to resolve"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[mdns]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "bind_interface": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "inet4_bind_address": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "inet6_bind_address": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "bind_address_no_port": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "protect_path": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "tcp_fast_open": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "tcp_keep_alive": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "udp_fragment": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Bmdns%5D.domain_resolver"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "prefer_go": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go's own resolver rather than the system's: sail is not Go"
    },
    "neighbor_domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "interface": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The interfaces to ask on; all that are up and take multicast when none are named."
    },
    "domain_strategy": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "type": {
     "const": "mdns"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[mdns].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "strategy": {
     "type": "string",
     "examples": [
      "as_is",
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "disable_cache": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "disable_optimistic_cache": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "rewrite_ttl": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    },
    "client_subnet": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: An mDNS server asks on each interface itself, as sing-box's, which dials nothing"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[quic]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Bquic%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "tls": {
     "$ref": "#/$defs/dns.servers%5Bquic%5D.tls",
     "description": "`tls`, `https`, `quic` and `h3`."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "respect_rules": {
     "type": "boolean",
     "description": "A sail extension, as Mihomo's `respect-rules`: the connections go through the outbound the routing rules pick for them, as for a connection from the inbound `dnsclient` to the server, its domain known."
    },
    "client_subnet": {
     "$ref": "#/$defs/dns.servers%5Bquic%5D.client_subnet",
     "description": "A sail extension: the EDNS Client Subnet its queries carry, over any they have, as Mihomo's `ecs` with `ecs-override`."
    },
    "type": {
     "const": "quic"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[quic].client_subnet": {
   "type": "object",
   "properties": {
    "addr": {
     "type": "string"
    },
    "len": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[quic].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "dns.servers[quic].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: A quic server offers its own"
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only for fragmenting the TLS handshake, which sail does not do"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: Not for a quic server"
    },
    "reality": {
     "$ref": "#/$defs/dns.servers%5Bquic%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "dns.servers[quic].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[quic].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[quic].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Not for a quic server"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: Not for a quic server"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[race]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "servers": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A server that asks its members at once and takes the first good answer"
    },
    "type": {
     "const": "race"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[sequential]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "servers": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The servers, by tag, in the order they are asked; two or more, none a `race` or `sequential` server. The next is asked only when one gives no answer at all (a timeout, a connection that fails); any answer, SERVFAIL and REFUSED too, ends the query, unlike `race`, which takes those for failures: asked in order, a server's plain answer is not to be passed on to the next. Each goes out as its own `detour` says."
    },
    "attempt_timeout": {
     "type": "string",
     "description": "How long each server has to answer; the last has what the budget leaves. A kept connection that does not answer in half of it is left for a new one to the same server, with the whole time again, once a query. 3s when unset."
    },
    "budget": {
     "type": "string",
     "description": "How long a whole query may take, under `dns.timeout`; once it is spent the query fails, and a client is answered SERVFAIL. 8s when unset."
    },
    "prefer_for": {
     "type": "string",
     "description": "How long a server that answered, not being the first, is asked first (the next ones after it in turn); `0s` keeps the order. 10m when unset."
    },
    "type": {
     "const": "sequential"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tcp]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Btcp%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "respect_rules": {
     "type": "boolean",
     "description": "A sail extension, as Mihomo's `respect-rules`: the connections go through the outbound the routing rules pick for them, as for a connection from the inbound `dnsclient` to the server, its domain known."
    },
    "client_subnet": {
     "$ref": "#/$defs/dns.servers%5Btcp%5D.client_subnet",
     "description": "A sail extension: the EDNS Client Subnet its queries carry, over any they have, as Mihomo's `ecs` with `ecs-override`."
    },
    "type": {
     "const": "tcp"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tcp].client_subnet": {
   "type": "object",
   "properties": {
    "addr": {
     "type": "string"
    },
    "len": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tcp].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "dns.servers[tls]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Btls%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "tls": {
     "$ref": "#/$defs/dns.servers%5Btls%5D.tls",
     "description": "`tls`, `https`, `quic` and `h3`."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "respect_rules": {
     "type": "boolean",
     "description": "A sail extension, as Mihomo's `respect-rules`: the connections go through the outbound the routing rules pick for them, as for a connection from the inbound `dnsclient` to the server, its domain known."
    },
    "client_subnet": {
     "$ref": "#/$defs/dns.servers%5Btls%5D.client_subnet",
     "description": "A sail extension: the EDNS Client Subnet its queries carry, over any they have, as Mihomo's `ecs` with `ecs-override`."
    },
    "type": {
     "const": "tls"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tls].client_subnet": {
   "type": "object",
   "properties": {
    "addr": {
     "type": "string"
    },
    "len": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tls].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "dns.servers[tls].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: A tls server offers its own"
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only for fragmenting the TLS handshake, which sail does not do"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "utls": {
     "$ref": "#/$defs/dns.servers%5Btls%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/dns.servers%5Btls%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tls].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tls].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: Not for a dns server"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[tls].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "dns.servers[udp]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/dns.servers%5Budp%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "respect_rules": {
     "type": "boolean",
     "description": "A sail extension, as Mihomo's `respect-rules`: the connections go through the outbound the routing rules pick for them, as for a connection from the inbound `dnsclient` to the server, its domain known."
    },
    "client_subnet": {
     "$ref": "#/$defs/dns.servers%5Budp%5D.client_subnet",
     "description": "A sail extension: the EDNS Client Subnet its queries carry, over any they have, as Mihomo's `ecs` with `ecs-override`."
    },
    "type": {
     "const": "udp"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[udp].client_subnet": {
   "type": "object",
   "properties": {
    "addr": {
     "type": "string"
    },
    "len": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "dns.servers[udp].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "endpoints[wireguard]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "system": {
     "type": "boolean",
     "description": "A system interface instead of the userspace stack: not supported."
    },
    "name": {
     "not": {},
     "description": "sail refuses this field: Names a system interface, which sail does not create"
    },
    "mtu": {
     "type": "number"
    },
    "address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The endpoint's own addresses in the tunnel, as prefixes."
    },
    "private_key": {
     "type": "string"
    },
    "listen_port": {
     "type": "number"
    },
    "peers": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/endpoints%5Bwireguard%5D.peers%5B%5D"
     }
    },
    "udp_timeout": {
     "type": "string",
     "description": "How long a UDP session coming in through this endpoint lives without traffic; 5m when unset, as for an inbound."
    },
    "udp_mapping": {
     "type": "string",
     "examples": [
      "endpoint_independent",
      "address_dependent",
      "address_and_port_dependent"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How UDP mappings are made and how many are kept: the same traffic"
    },
    "udp_filtering": {
     "not": {},
     "description": "sail refuses this field: Which remote addresses may answer through a UDP mapping: others would"
    },
    "udp_nat_max": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How UDP mappings are made and how many are kept: the same traffic"
    },
    "workers": {
     "type": "number",
     "description": "sing-box's worker count; sail has no use for it."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/endpoints%5Bwireguard%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Choosing among the host's networks (Wi-Fi, cellular) here: it would go out as the route's defaults say"
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "type": {
     "const": "wireguard"
    }
   },
   "additionalProperties": false
  },
  "endpoints[wireguard].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "endpoints[wireguard].peers[]": {
   "type": "object",
   "properties": {
    "address": {
     "type": "string",
     "description": "Where the peer is: an address or a domain. Without it, it is learnt from the peer's handshake, as a server's peers are."
    },
    "port": {
     "type": "number"
    },
    "public_key": {
     "type": "string"
    },
    "pre_shared_key": {
     "type": "string"
    },
    "allowed_ips": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "persistent_keepalive_interval": {
     "type": "number",
     "description": "Seconds; 0 or unset is off."
    },
    "reserved": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "Three bytes, or their base64: Cloudflare WARP's client identifier."
    }
   },
   "additionalProperties": false
  },
  "experimental": {
   "type": "object",
   "properties": {
    "cache_file": {
     "$ref": "#/$defs/experimental.cache_file"
    },
    "clash_api": {
     "$ref": "#/$defs/experimental.clash_api",
     "description": "sing-box's place for the Clash API: taken to `clash_api` when the configuration is validated."
    },
    "v2ray_api": {
     "$ref": "#/$defs/experimental.v2ray_api",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: V2Ray's statistics API, for watching the instance"
    },
    "debug": {
     "$ref": "#/$defs/experimental.debug",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    }
   },
   "additionalProperties": false
  },
  "experimental.cache_file": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "path": {
     "type": "string",
     "description": "`cache.db` when unset. A relative path is in the host's cache directory, or the data directory."
    },
    "cache_id": {
     "type": "string",
     "description": "What this configuration keeps is kept apart, under this name, from what others sharing the file keep."
    },
    "store_fakeip": {
     "type": "boolean"
    },
    "rdrc_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The cache of the legacy address filter's rejected responses, which sail does not have; deprecated in sing-box 1.14"
    },
    "store_dns": {
     "type": "boolean",
     "description": "The DNS answers kept are kept in the file too, and outlive a restart."
    },
    "store_rdrc": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The cache of the legacy address filter's rejected responses, which sail does not have; deprecated in sing-box 1.14"
    }
   },
   "additionalProperties": false
  },
  "experimental.clash_api": {
   "type": "object",
   "properties": {
    "external_controller": {
     "type": "string",
     "description": "Where it listens, `host:port`; an empty host is every address, as in Mihomo. Unset, it is not served, though `default_mode` still sets the mode rules match."
    },
    "external_ui": {
     "type": "string",
     "description": "A directory of a dashboard's files, served at `/ui/`; relative to the data directory."
    },
    "external_ui_download_url": {
     "type": "string",
     "description": "Where the dashboard is downloaded from, a ZIP, when `external_ui` is empty. The core has none of its own: unset, nothing is downloaded, and a warning says so; a host, such as sail-cli, may give one."
    },
    "external_ui_download_detour": {
     "type": "string",
     "description": "The outbound the download goes through; the default one when unset."
    },
    "secret": {
     "type": "string",
     "description": "What callers authenticate with, `Authorization: Bearer`, or a WebSocket's `?token=`. The API is served only with a strong one (at least 32 characters, 10 distinct): `sail generate secret` makes one."
    },
    "default_mode": {
     "type": "string",
     "description": "The mode rules match at the start, `Rule` when unset."
    },
    "access_control_allow_origin": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The origins browsers may call it from (CORS); any when empty."
    },
    "access_control_allow_private_network": {
     "type": "boolean",
     "description": "Pages on public addresses may call it on a private one (Private Network Access)."
    }
   },
   "additionalProperties": false
  },
  "experimental.debug": {
   "type": "object",
   "properties": {
    "listen": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    },
    "gc_percent": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    },
    "max_stack": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    },
    "max_threads": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    },
    "panic_on_fault": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    },
    "trace_back": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    },
    "memory_limit": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Go runtime tuning and debugging: sail is not Go"
    },
    "oom_killer": {
     "not": {},
     "description": "sail refuses this field: Removed in sing-box 1.13, which refuses it: the oom-killer service took its place"
    }
   },
   "additionalProperties": false
  },
  "experimental.v2ray_api": {
   "type": "object",
   "properties": {
    "listen": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: V2Ray's statistics API, for watching the instance"
    },
    "stats": {
     "$ref": "#/$defs/experimental.v2ray_api.stats",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: V2Ray's statistics API, for watching the instance"
    }
   },
   "additionalProperties": false
  },
  "experimental.v2ray_api.stats": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: V2Ray's statistics API, for watching the instance"
    },
    "inbounds": {
     "type": "array",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: V2Ray's statistics API, for watching the instance"
    },
    "outbounds": {
     "type": "array",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: V2Ray's statistics API, for watching the instance"
    },
    "users": {
     "type": "array",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: V2Ray's statistics API, for watching the instance"
    }
   },
   "additionalProperties": false
  },
  "http_clients[]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Of one in `http_clients`; none inline."
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple"
     ],
     "description": "Whose client sing-box downloads with: `go`, its own, when unset, or `apple`, NSURLSession. sail downloads with its own either way, and warns of `apple`."
    },
    "version": {
     "type": "number",
     "examples": [
      0,
      1,
      2,
      3
     ],
     "description": "The HTTP version sing-box asks for, 1, 2 or 3; 2 when unset (or 0). sail downloads over HTTP/1.1 whichever, as sing-box does from a server that speaks no other: a download is the same download."
    },
    "disable_version_fallback": {
     "type": "boolean",
     "description": "`version` alone, never HTTP/1.1 in its place: warned of with 2 or 3, as sail downloads over HTTP/1.1."
    },
    "headers": {
     "type": "object",
     "description": "Sent with each request, over sail's own of the same name."
    },
    "tls": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/http_clients%5B%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "idle_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "keep_alive_period": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "stream_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "connection_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "max_concurrent_streams": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "initial_packet_size": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "disable_path_mtu_discovery": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    }
   },
   "additionalProperties": false
  },
  "http_clients[].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "http_clients[].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "engine": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "disable_sni": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "server_name": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "insecure": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "min_version": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "max_version": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "certificate": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "certificate_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "certificate_public_key_sha256": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_certificate": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_certificate_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_key": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_key_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "kernel_tx": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "kernel_rx": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "handshake_timeout": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "reality": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "http_clients[].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "http_clients[].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "short_id": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "http_clients[].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "tls": {
     "$ref": "#/$defs/inbounds%5Banytls%5D.tls"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Banytls%5D.users%5B%5D"
     }
    },
    "padding_scheme": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The padding scheme, as lines. Unset, the default. A scheme that pads past write 1024, gives a write more than 64 sizes or asks for more than 1 MiB of padding in all is refused."
    },
    "fallback": {
     "$ref": "#/$defs/inbounds%5Banytls%5D.fallback",
     "description": "Where a connection that fails to authenticate is relayed."
    },
    "fallback_for_alpn": {
     "type": "object",
     "additionalProperties": {
      "$ref": "#/$defs/inbounds%5Banytls%5D.fallback_for_alpn"
     },
     "description": "The same, by the ALPN the connection's TLS negotiated; the ones it does not name go to `fallback`."
    },
    "type": {
     "const": "anytls"
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls].fallback": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls].fallback_for_alpn": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "server_name": {
     "type": "string"
    },
    "insecure": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only relaxes checks a server's TLS does not make"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ]
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ]
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "certificate_path": {
     "type": "string"
    },
    "client_authentication": {
     "type": "string",
     "examples": [
      "no",
      "request",
      "require-any",
      "verify-if-given",
      "require-and-verify"
     ]
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "client_certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "client_certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ]
    },
    "key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "key_path": {
     "type": "string"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "reality": {
     "$ref": "#/$defs/inbounds%5Banytls%5D.tls.reality"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "client_certificate_sha256": {
     "description": "sing-box 1.15's, read ahead: clients' certificates taken by the SHA-256 of the whole leaf (its DER), standard base64 or hex, with a verifying `client_authentication`; looked at before `client_certificate_public_key_sha256`, either list passing"
    },
    "self_signed": {
     "description": "With no certificate or key, a self-signed one made at start for `tls.server_name` (or `sail.invalid`), kept across reloads that leave the inbound in place, as Mihomo's Hysteria2 and TUIC listeners make one; clients need `insecure` or a pin, which changes with each new certificate; an error with a certificate, a key or REALITY"
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Banytls%5D.tls.reality.handshake"
    },
    "private_key": {
     "type": "string"
    },
    "short_id": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "max_time_difference": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour to the REALITY handshake server: it would be reached otherwise"
    },
    "bind_interface": {
     "type": "string"
    },
    "inet4_bind_address": {
     "type": "string"
    },
    "inet6_bind_address": {
     "type": "string"
    },
    "bind_address_no_port": {
     "type": "boolean"
    },
    "protect_path": {
     "type": "string"
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ]
    },
    "reuse_addr": {
     "type": "boolean"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string"
    },
    "tcp_fast_open": {
     "type": "boolean"
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string"
    },
    "tcp_keep_alive_interval": {
     "type": "string"
    },
    "udp_fragment": {
     "type": "boolean"
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Banytls%5D.tls.reality.handshake.domain_resolver"
      }
     ]
    },
    "network_strategy": {
     "type": "string",
     "examples": [
      "default",
      "fallback",
      "hybrid"
     ]
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ]
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ]
    },
    "fallback_delay": {
     "type": "string"
    },
    "domain_strategy": {
     "type": "string",
     "deprecated": true
    }
   },
   "additionalProperties": false
  },
  "inbounds[anytls].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "examples": [
      "as_is",
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[anytls].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[direct]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "network": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "tcp",
        "udp"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "tcp",
         "udp"
        ]
       }
      }
     ],
     "description": "Only `tcp`, or only `udp`; both when unset."
    },
    "override_address": {
     "type": "string",
     "description": "Where what comes in goes, instead of the listener's address."
    },
    "override_port": {
     "type": "number",
     "description": "The port it goes to, instead of the listener's."
    },
    "type": {
     "const": "direct"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hc]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "path": {
     "type": "string"
    },
    "request": {
     "type": "string"
    },
    "response": {
     "type": "string"
    },
    "type": {
     "const": "hc"
    }
   },
   "additionalProperties": false
  },
  "inbounds[http]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bhttp%5D.users%5B%5D"
     },
     "description": "Clients must authenticate as one of these with `Proxy-Authorization: Basic`; anyone may connect when there are none."
    },
    "domain_resolver": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "set_system_proxy": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The platform proxy is the host's to set"
    },
    "tls": {
     "$ref": "#/$defs/inbounds%5Bhttp%5D.tls"
    },
    "realm": {
     "type": "string",
     "description": "The realm a `407` names, which clients show when asking for credentials: a sail extension; `sail` when unset."
    },
    "skip_auth_prefixes": {
     "type": "array",
     "description": "The clients that go in without credentials, by the IP prefixes they connect from: Mihomo's `skip-auth-prefixes`, a sail extension."
    },
    "version": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array"
      }
     ],
     "description": "The HTTP versions served, sing-box 1.15's: 1 and 2 when unset. HTTP/2 is told by its preface, over TLS or not. 3 is warned of and not served: sail speaks no HTTP/3."
    },
    "idle_timeout": {
     "type": "string",
     "description": "HTTP/2's, sing-box 1.15's: how long a ping may go unanswered, and how long a connection with no tunnel is kept."
    },
    "keep_alive_period": {
     "type": "string",
     "description": "HTTP/2's: a ping after this long with nothing received."
    },
    "stream_receive_window": {
     "type": "number",
     "description": "HTTP/2's: a tunnel's receive window."
    },
    "connection_receive_window": {
     "type": "number",
     "description": "HTTP/2's: a connection's receive window."
    },
    "max_concurrent_streams": {
     "type": "number",
     "description": "HTTP/2's: the most tunnels a client may have open on one connection."
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "inbounds[http].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "strategy": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "disable_cache": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "disable_optimistic_cache": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "rewrite_ttl": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "client_subnet": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    }
   },
   "additionalProperties": false
  },
  "inbounds[http].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "server_name": {
     "type": "string",
     "description": "The name REALITY clients must ask for, or the one a `self_signed` certificate is for; otherwise it is ignored with a warning, as sing-box ignores it."
    },
    "insecure": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only relaxes checks a server's TLS does not make"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to accept, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate."
    },
    "certificate_path": {
     "type": "string"
    },
    "client_authentication": {
     "type": "string",
     "examples": [
      "no",
      "request",
      "require-any",
      "verify-if-given",
      "require-and-verify"
     ],
     "description": "What is asked of clients' certificates, as sing-box takes it: `no` (none is asked for), `request` or `require-any` (one is taken unchecked; `require-any` refuses a client without), `verify-if-given` or `require-and-verify` (one is checked, by the CAs or the pins; `require-and-verify` refuses a client without). Unset is `no`, or `require-and-verify` with CAs set. Pins without a verifying mode, and CAs or pins with `request` or `require-any`, are errors, where sing-box checks no certificate."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs clients' certificates are verified by, inline PEM: chained to one of them, by the intermediates the client sends, valid, and for client authentication. With `client_certificate_path` too, the files are ignored with a warning, as sing-box ignores them."
    },
    "client_certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs, from PEM (or DER) files, as `client_certificate`. The files are followed as the certificate's are: CAs written to them are taken for the connections that come next."
    },
    "client_certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "Clients' certificates taken by the SHA-256 of their public key (SubjectPublicKeyInfo), standard base64, in place of CAs: the leaf alone, no CA or validity period. With `client_certificate_sha256`, either list passing is enough. Beside CAs, ignored with a warning, as sing-box ignores them."
    },
    "key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM key."
    },
    "key_path": {
     "type": "string"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "reality": {
     "$ref": "#/$defs/inbounds%5Bhttp%5D.tls.reality"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "client_certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, read ahead: clients' certificates taken by the SHA-256 of the whole leaf (its DER), standard base64 or hex, looked at before `client_certificate_public_key_sha256`, as that is."
    },
    "self_signed": {
     "type": "boolean",
     "description": "A sail extension: with no certificate or key set, a self-signed one the instance makes, for `server_name` if set, as Mihomo's Hysteria2 and TUIC listeners serve one without a certificate. It is made once and kept across reloads that rebuild the inbound in place; clients take it as `insecure` or by a pin. With a certificate or key, or REALITY, an error."
    }
   },
   "additionalProperties": false
  },
  "inbounds[http].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    }
   },
   "additionalProperties": false
  },
  "inbounds[http].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Bhttp%5D.tls.reality.handshake"
    },
    "private_key": {
     "type": "string",
     "description": "X25519, hex or base64url."
    },
    "short_id": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "max_time_difference": {
     "type": "string",
     "description": "How far a client's clock may be from ours, e.g. `1m`. Unset, any time is accepted, as in sing-box."
    },
    "server_names": {
     "type": "array",
     "description": "A sail extension, Xray's `serverNames` and Mihomo's `server-names`: more names clients may ask for, beside `tls.server_name`."
    }
   },
   "additionalProperties": false
  },
  "inbounds[http].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour to the REALITY handshake server: it would be reached otherwise"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Bhttp%5D.tls.reality.handshake.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    }
   },
   "additionalProperties": false
  },
  "inbounds[http].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[http].users[]": {
   "type": "object",
   "properties": {
    "username": {
     "type": "string"
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "up_mbps": {
     "type": "number",
     "description": "What the server may send at, at most, to each client."
    },
    "down_mbps": {
     "type": "number",
     "description": "What the server can receive at, told to clients."
    },
    "obfs": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "gecko",
        "salamander"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "gecko"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bhysteria2%5D.obfs%5Bgecko%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "salamander"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bhysteria2%5D.obfs%5Bsalamander%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bhysteria2%5D.users%5B%5D"
     }
    },
    "ignore_client_bandwidth": {
     "type": "boolean",
     "description": "Ignores the rate clients say they receive at, and has them find their own: BBR both ways."
    },
    "tls": {
     "$ref": "#/$defs/inbounds%5Bhysteria2%5D.tls"
    },
    "idle_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "keep_alive_period": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "stream_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "connection_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "max_concurrent_streams": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "initial_packet_size": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "disable_path_mtu_discovery": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "masquerade": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "object"
      }
     ],
     "description": "What anyone without a password is served: an `http://` or `https://` site behind, or a fixed response; 404 when unset."
    },
    "bbr_profile": {
     "type": "string",
     "examples": [
      "standard",
      "conservative",
      "aggressive"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Hysteria's congestion tuning and debugging, the longest hop interval, and its QUIC fingerprint: the same traffic"
    },
    "brutal_debug": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Hysteria's congestion tuning and debugging, the longest hop interval, and its QUIC fingerprint: the same traffic"
    },
    "realm": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "type": {
     "const": "hysteria2"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].obfs[gecko]": {
   "type": "object",
   "properties": {
    "password": {
     "type": "string"
    },
    "min_packet_size": {
     "not": {},
     "description": "sail refuses this field: The packet sizes of the gecko obfuscation: the packets would look otherwise"
    },
    "max_packet_size": {
     "not": {},
     "description": "sail refuses this field: The packet sizes of the gecko obfuscation: the packets would look otherwise"
    },
    "type": {
     "const": "gecko"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].obfs[salamander]": {
   "type": "object",
   "properties": {
    "password": {
     "type": "string"
    },
    "type": {
     "const": "salamander"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm": {
   "type": "object",
   "properties": {
    "server_url": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "token": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "realm_id": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "stun_servers": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "ip_version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "port_mapping": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "http_client": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "stun_domain_resolver": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.http_client": {
   "type": "object",
   "properties": {
    "engine": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_version_fallback": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tls": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "inet4_bind_address": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "inet6_bind_address": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "bind_address_no_port": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "protect_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "reuse_addr": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "connect_timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_fast_open": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_multi_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_tcp_keep_alive": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_keep_alive": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_keep_alive_interval": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "udp_fragment": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "domain_resolver": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "keep_alive_period": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "stream_receive_window": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "connection_receive_window": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "max_concurrent_streams": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "initial_packet_size": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_path_mtu_discovery": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "domain_strategy": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.http_client.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "strategy": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_cache": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_optimistic_cache": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "rewrite_ttl": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_subnet": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.http_client.tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "engine": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_sni": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "server_name": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "insecure": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "min_version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "max_version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "certificate": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "certificate_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "certificate_public_key_sha256": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_certificate": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_certificate_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_key": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_key_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "kernel_tx": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "kernel_rx": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "handshake_timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "reality": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.http_client.tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.http_client.tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "short_id": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.http_client.tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.port_mapping": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "lifetime": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].realm.stun_domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "strategy": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_cache": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_optimistic_cache": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "rewrite_ttl": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_subnet": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "server_name": {
     "type": "string",
     "description": "The name REALITY clients must ask for, or the one a `self_signed` certificate is for; otherwise it is ignored with a warning, as sing-box ignores it."
    },
    "insecure": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only relaxes checks a server's TLS does not make"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to accept, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate."
    },
    "certificate_path": {
     "type": "string"
    },
    "client_authentication": {
     "type": "string",
     "examples": [
      "no",
      "request",
      "require-any",
      "verify-if-given",
      "require-and-verify"
     ],
     "description": "What is asked of clients' certificates, as sing-box takes it: `no` (none is asked for), `request` or `require-any` (one is taken unchecked; `require-any` refuses a client without), `verify-if-given` or `require-and-verify` (one is checked, by the CAs or the pins; `require-and-verify` refuses a client without). Unset is `no`, or `require-and-verify` with CAs set. Pins without a verifying mode, and CAs or pins with `request` or `require-any`, are errors, where sing-box checks no certificate."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs clients' certificates are verified by, inline PEM: chained to one of them, by the intermediates the client sends, valid, and for client authentication. With `client_certificate_path` too, the files are ignored with a warning, as sing-box ignores them."
    },
    "client_certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs, from PEM (or DER) files, as `client_certificate`. The files are followed as the certificate's are: CAs written to them are taken for the connections that come next."
    },
    "client_certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "Clients' certificates taken by the SHA-256 of their public key (SubjectPublicKeyInfo), standard base64, in place of CAs: the leaf alone, no CA or validity period. With `client_certificate_sha256`, either list passing is enough. Beside CAs, ignored with a warning, as sing-box ignores them."
    },
    "key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM key."
    },
    "key_path": {
     "type": "string"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "reality": {
     "$ref": "#/$defs/inbounds%5Bhysteria2%5D.tls.reality"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "client_certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, read ahead: clients' certificates taken by the SHA-256 of the whole leaf (its DER), standard base64 or hex, looked at before `client_certificate_public_key_sha256`, as that is."
    },
    "self_signed": {
     "type": "boolean",
     "description": "A sail extension: with no certificate or key set, a self-signed one the instance makes, for `server_name` if set, as Mihomo's Hysteria2 and TUIC listeners serve one without a certificate. It is made once and kept across reloads that rebuild the inbound in place; clients take it as `insecure` or by a pin. With a certificate or key, or REALITY, an error."
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Bhysteria2%5D.tls.reality.handshake"
    },
    "private_key": {
     "type": "string",
     "description": "X25519, hex or base64url."
    },
    "short_id": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "max_time_difference": {
     "type": "string",
     "description": "How far a client's clock may be from ours, e.g. `1m`. Unset, any time is accepted, as in sing-box."
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour to the REALITY handshake server: it would be reached otherwise"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Bhysteria2%5D.tls.reality.handshake.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    }
   },
   "additionalProperties": false
  },
  "inbounds[hysteria2].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[hysteria2].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bmixed%5D.users%5B%5D"
     },
     "description": "Clients must authenticate as one of these, by SOCKS5 username/password or HTTP Basic; anyone may connect when there are none."
    },
    "domain_resolver": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "set_system_proxy": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The platform proxy is the host's to set"
    },
    "tls": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "realm": {
     "type": "string",
     "description": "The realm an HTTP `407` names: a sail extension; `sail` when unset."
    },
    "skip_auth_prefixes": {
     "type": "array",
     "description": "The clients that go in without credentials, by the IP prefixes they connect from: Mihomo's `skip-auth-prefixes`, a sail extension."
    },
    "type": {
     "const": "mixed"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "strategy": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "disable_cache": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "disable_optimistic_cache": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "rewrite_ttl": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "client_subnet": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "server_name": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "insecure": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "min_version": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "max_version": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "certificate": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "certificate_path": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "client_authentication": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "client_certificate": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "client_certificate_path": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "client_certificate_public_key_sha256": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "kernel_tx": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "kernel_rx": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "handshake_timeout": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "reality": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "handshake": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "private_key": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "short_id": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "max_time_difference": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "server_port": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "inet4_bind_address": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "inet6_bind_address": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "bind_address_no_port": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "protect_path": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "reuse_addr": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "connect_timeout": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "tcp_fast_open": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "tcp_multi_path": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "disable_tcp_keep_alive": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "tcp_keep_alive": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "tcp_keep_alive_interval": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "udp_fragment": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "domain_resolver": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "fallback_delay": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "domain_strategy": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "strategy": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "disable_cache": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "disable_optimistic_cache": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "rewrite_ttl": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    },
    "client_subnet": {
     "not": {},
     "description": "sail refuses this field: TLS on a mixed inbound: it would take plain connections"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mixed].users[]": {
   "type": "object",
   "properties": {
    "username": {
     "type": "string"
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[mptp]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "type": {
     "const": "mptp"
    }
   },
   "additionalProperties": false
  },
  "inbounds[nf]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "driver_name": {
     "type": "string"
    },
    "nfapi": {
     "type": "string"
    },
    "fake_dns_exclude": {
     "type": "array"
    },
    "fake_dns_include": {
     "type": "array"
    },
    "type": {
     "const": "nf"
    }
   },
   "additionalProperties": false
  },
  "inbounds[redirect]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "type": {
     "const": "redirect"
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowsocks]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "network": {
     "not": {},
     "description": "sail refuses this field: Which networks a Shadowsocks inbound serves: it would serve others"
    },
    "method": {
     "type": "string",
     "examples": [
      "none",
      "aes-128-gcm",
      "aes-192-gcm",
      "aes-256-gcm",
      "chacha20-ietf-poly1305",
      "xchacha20-ietf-poly1305",
      "2022-blake3-aes-128-gcm",
      "2022-blake3-aes-256-gcm",
      "2022-blake3-chacha20-poly1305"
     ]
    },
    "password": {
     "type": "string",
     "description": "The PSK with a 2022 method; with `users`, the server's identity PSK."
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bshadowsocks%5D.users%5B%5D"
     },
     "description": "Shadowsocks 2022 users, told apart by identity headers."
    },
    "destinations": {
     "not": {},
     "description": "sail refuses this field: Relaying to other Shadowsocks servers"
    },
    "multiplex": {
     "$ref": "#/$defs/inbounds%5Bshadowsocks%5D.multiplex"
    },
    "managed": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Users managed through the SSM API, a service sail does not run"
    },
    "type": {
     "const": "shadowsocks"
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowsocks].destinations[]": {
   "type": "object",
   "properties": {
    "name": {
     "not": {},
     "description": "sail refuses this field: Relaying to other Shadowsocks servers"
    },
    "password": {
     "not": {},
     "description": "sail refuses this field: Relaying to other Shadowsocks servers"
    },
    "server": {
     "not": {},
     "description": "sail refuses this field: Relaying to other Shadowsocks servers"
    },
    "server_port": {
     "not": {},
     "description": "sail refuses this field: Relaying to other Shadowsocks servers"
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowsocks].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "padding": {
     "type": "boolean",
     "description": "sing-mux: refuse connections that are not padded."
    },
    "brutal": {
     "$ref": "#/$defs/inbounds%5Bshadowsocks%5D.multiplex.brutal",
     "description": "sing-mux: TCP Brutal for clients that ask for it; Linux only."
    },
    "protocol": {
     "type": "string",
     "description": "`amux`; unset, sing-mux, which sing-box's block has no field for: its server takes smux, yamux and h2mux alike."
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowsocks].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowsocks].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "password": {
     "type": "string",
     "description": "The user's base64 PSK."
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowtls]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "type": "string",
     "description": "The inbound connections go to after the handshake, by tag: needed."
    },
    "version": {
     "type": "number",
     "examples": [
      1,
      2,
      3
     ],
     "description": "Must be 3: versions 1 and 2 are not supported. sing-box's default is 1."
    },
    "password": {
     "type": "string",
     "description": "Version 2's, and an error: version 3 takes `users`."
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bshadowtls%5D.users%5B%5D"
     },
     "description": "At least one."
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Bshadowtls%5D.handshake",
     "description": "The site whose handshake is relayed, for everyone the other fields do not send elsewhere. Needed unless `wildcard_sni` is on."
    },
    "handshake_for_server_name": {
     "type": "object",
     "description": "Handshake servers by the server name the ClientHello asks for."
    },
    "strict_mode": {
     "type": "boolean",
     "description": "Relays a ServerHello that does not pick TLS 1.3 as it would an unauthenticated client."
    },
    "wildcard_sni": {
     "type": "string",
     "enum": [
      "off",
      "authed",
      "all"
     ]
    },
    "type": {
     "const": "shadowtls"
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowtls].handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: The protocol's own check: not implemented yet"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: The protocol's own check: not implemented yet"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "not": {},
     "description": "sail refuses this field: The protocol's own check: not implemented yet"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Bshadowtls%5D.handshake.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    }
   },
   "additionalProperties": false
  },
  "inbounds[shadowtls].handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[shadowtls].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[socks]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bsocks%5D.users%5B%5D"
     },
     "description": "Clients must authenticate as one of these; anyone may connect when there are none."
    },
    "domain_resolver": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "skip_auth_prefixes": {
     "type": "array",
     "description": "The clients that go in without credentials, by the IP prefixes they connect from: Mihomo's `skip-auth-prefixes`, a sail extension."
    },
    "type": {
     "const": "socks"
    }
   },
   "additionalProperties": false
  },
  "inbounds[socks].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "strategy": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "disable_cache": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "disable_optimistic_cache": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "rewrite_ttl": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    },
    "client_subnet": {
     "not": {},
     "description": "sail refuses this field: Resolving requested names with a resolver of its own: another server would answer"
    }
   },
   "additionalProperties": false
  },
  "inbounds[socks].users[]": {
   "type": "object",
   "properties": {
    "username": {
     "type": "string"
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[tproxy]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "network": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "tcp",
        "udp"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "tcp",
         "udp"
        ]
       }
      }
     ],
     "description": "Only `tcp`, or only `udp`; both when unset."
    },
    "udp_mapping": {
     "type": "string",
     "examples": [
      "endpoint_independent",
      "address_dependent",
      "address_and_port_dependent"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How UDP mappings are made and how many are kept: the same traffic"
    },
    "udp_filtering": {
     "not": {},
     "description": "sail refuses this field: Which remote addresses may answer through a UDP mapping: others would"
    },
    "udp_nat_max": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How UDP mappings are made and how many are kept: the same traffic"
    },
    "type": {
     "const": "tproxy"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Btrojan%5D.users%5B%5D"
     }
    },
    "tls": {
     "$ref": "#/$defs/inbounds%5Btrojan%5D.tls"
    },
    "fallback": {
     "$ref": "#/$defs/inbounds%5Btrojan%5D.fallback",
     "description": "Where a connection that fails to authenticate is relayed."
    },
    "fallback_for_alpn": {
     "type": "object",
     "description": "The same, by the ALPN the connection's TLS negotiated; the ones it does not name go to `fallback`."
    },
    "multiplex": {
     "$ref": "#/$defs/inbounds%5Btrojan%5D.multiplex"
    },
    "transport": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "grpc",
        "http",
        "httpupgrade",
        "ws"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "grpc"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Btrojan%5D.transport%5Bgrpc%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "http"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Btrojan%5D.transport%5Bhttp%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "httpupgrade"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Btrojan%5D.transport%5Bhttpupgrade%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "ws"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Btrojan%5D.transport%5Bws%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "type": {
     "const": "trojan"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].fallback": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "padding": {
     "type": "boolean",
     "description": "sing-mux: refuse connections that are not padded."
    },
    "brutal": {
     "$ref": "#/$defs/inbounds%5Btrojan%5D.multiplex.brutal",
     "description": "sing-mux: TCP Brutal for clients that ask for it; Linux only."
    },
    "protocol": {
     "type": "string",
     "description": "`amux`; unset, sing-mux, which sing-box's block has no field for: its server takes smux, yamux and h2mux alike."
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "server_name": {
     "type": "string",
     "description": "The name REALITY clients must ask for, or the one a `self_signed` certificate is for; otherwise it is ignored with a warning, as sing-box ignores it."
    },
    "insecure": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only relaxes checks a server's TLS does not make"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to accept, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate."
    },
    "certificate_path": {
     "type": "string"
    },
    "client_authentication": {
     "type": "string",
     "examples": [
      "no",
      "request",
      "require-any",
      "verify-if-given",
      "require-and-verify"
     ],
     "description": "What is asked of clients' certificates, as sing-box takes it: `no` (none is asked for), `request` or `require-any` (one is taken unchecked; `require-any` refuses a client without), `verify-if-given` or `require-and-verify` (one is checked, by the CAs or the pins; `require-and-verify` refuses a client without). Unset is `no`, or `require-and-verify` with CAs set. Pins without a verifying mode, and CAs or pins with `request` or `require-any`, are errors, where sing-box checks no certificate."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs clients' certificates are verified by, inline PEM: chained to one of them, by the intermediates the client sends, valid, and for client authentication. With `client_certificate_path` too, the files are ignored with a warning, as sing-box ignores them."
    },
    "client_certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs, from PEM (or DER) files, as `client_certificate`. The files are followed as the certificate's are: CAs written to them are taken for the connections that come next."
    },
    "client_certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "Clients' certificates taken by the SHA-256 of their public key (SubjectPublicKeyInfo), standard base64, in place of CAs: the leaf alone, no CA or validity period. With `client_certificate_sha256`, either list passing is enough. Beside CAs, ignored with a warning, as sing-box ignores them."
    },
    "key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM key."
    },
    "key_path": {
     "type": "string"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "reality": {
     "$ref": "#/$defs/inbounds%5Btrojan%5D.tls.reality"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "client_certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, read ahead: clients' certificates taken by the SHA-256 of the whole leaf (its DER), standard base64 or hex, looked at before `client_certificate_public_key_sha256`, as that is."
    },
    "self_signed": {
     "type": "boolean",
     "description": "A sail extension: with no certificate or key set, a self-signed one the instance makes, for `server_name` if set, as Mihomo's Hysteria2 and TUIC listeners serve one without a certificate. It is made once and kept across reloads that rebuild the inbound in place; clients take it as `insecure` or by a pin. With a certificate or key, or REALITY, an error."
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Btrojan%5D.tls.reality.handshake"
    },
    "private_key": {
     "type": "string",
     "description": "X25519, hex or base64url."
    },
    "short_id": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "max_time_difference": {
     "type": "string",
     "description": "How far a client's clock may be from ours, e.g. `1m`. Unset, any time is accepted, as in sing-box."
    },
    "server_names": {
     "type": "array",
     "description": "A sail extension, Xray's `serverNames` and Mihomo's `server-names`: more names clients may ask for, beside `tls.server_name`."
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour to the REALITY handshake server: it would be reached otherwise"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Btrojan%5D.tls.reality.handshake.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[trojan].transport[grpc]": {
   "type": "object",
   "properties": {
    "service_name": {
     "type": "string"
    },
    "idle_timeout": {
     "type": "string",
     "description": "Unset, no keepalive pings. A client pings this often; a server after this long with nothing received, so give a server no shorter a time than its clients' interval."
    },
    "ping_timeout": {
     "type": "string"
    },
    "permit_without_stream": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Response headers and keepalive of a WebSocket or gRPC server: the same streams"
    },
    "type": {
     "const": "grpc"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].transport[http]": {
   "type": "object",
   "properties": {
    "host": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "path": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "method": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "ping_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].transport[httpupgrade]": {
   "type": "object",
   "properties": {
    "host": {
     "type": "string",
     "description": "The `Host` a request must carry; unset, any."
    },
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object",
     "description": "Added to the response."
    },
    "type": {
     "const": "httpupgrade"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].transport[ws]": {
   "type": "object",
   "properties": {
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Response headers and keepalive of a WebSocket or gRPC server: the same streams"
    },
    "max_early_data": {
     "type": "number",
     "description": "The most early data a client may send in its upgrade request."
    },
    "early_data_header_name": {
     "type": "string",
     "description": "The header it comes in; unset, it comes in the path."
    },
    "forwarded_header": {
     "type": "string",
     "description": "The header a trusted reverse proxy in front puts the client's address in, such as `X-Forwarded-For`. Unset, no header is believed: anyone can send one."
    },
    "type": {
     "const": "ws"
    }
   },
   "additionalProperties": false
  },
  "inbounds[trojan].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[tuic]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Btuic%5D.users%5B%5D"
     }
    },
    "congestion_control": {
     "type": "string",
     "enum": [
      "cubic",
      "new_reno",
      "bbr"
     ]
    },
    "auth_timeout": {
     "type": "string",
     "description": "How long a connection may go without authenticating. 3s, as in sing-box, when not set."
    },
    "zero_rtt_handshake": {
     "type": "boolean"
    },
    "heartbeat": {
     "type": "string"
    },
    "tls": {
     "$ref": "#/$defs/inbounds%5Btuic%5D.tls"
    },
    "idle_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "keep_alive_period": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "stream_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "connection_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "max_concurrent_streams": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "initial_packet_size": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "disable_path_mtu_discovery": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "type": {
     "const": "tuic"
    }
   },
   "additionalProperties": false
  },
  "inbounds[tuic].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "server_name": {
     "type": "string",
     "description": "The name REALITY clients must ask for, or the one a `self_signed` certificate is for; otherwise it is ignored with a warning, as sing-box ignores it."
    },
    "insecure": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only relaxes checks a server's TLS does not make"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to accept, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate."
    },
    "certificate_path": {
     "type": "string"
    },
    "client_authentication": {
     "type": "string",
     "examples": [
      "no",
      "request",
      "require-any",
      "verify-if-given",
      "require-and-verify"
     ],
     "description": "What is asked of clients' certificates, as sing-box takes it: `no` (none is asked for), `request` or `require-any` (one is taken unchecked; `require-any` refuses a client without), `verify-if-given` or `require-and-verify` (one is checked, by the CAs or the pins; `require-and-verify` refuses a client without). Unset is `no`, or `require-and-verify` with CAs set. Pins without a verifying mode, and CAs or pins with `request` or `require-any`, are errors, where sing-box checks no certificate."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs clients' certificates are verified by, inline PEM: chained to one of them, by the intermediates the client sends, valid, and for client authentication. With `client_certificate_path` too, the files are ignored with a warning, as sing-box ignores them."
    },
    "client_certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs, from PEM (or DER) files, as `client_certificate`. The files are followed as the certificate's are: CAs written to them are taken for the connections that come next."
    },
    "client_certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "Clients' certificates taken by the SHA-256 of their public key (SubjectPublicKeyInfo), standard base64, in place of CAs: the leaf alone, no CA or validity period. With `client_certificate_sha256`, either list passing is enough. Beside CAs, ignored with a warning, as sing-box ignores them."
    },
    "key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM key."
    },
    "key_path": {
     "type": "string"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "reality": {
     "$ref": "#/$defs/inbounds%5Btuic%5D.tls.reality"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "client_certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, read ahead: clients' certificates taken by the SHA-256 of the whole leaf (its DER), standard base64 or hex, looked at before `client_certificate_public_key_sha256`, as that is."
    },
    "self_signed": {
     "type": "boolean",
     "description": "A sail extension: with no certificate or key set, a self-signed one the instance makes, for `server_name` if set, as Mihomo's Hysteria2 and TUIC listeners serve one without a certificate. It is made once and kept across reloads that rebuild the inbound in place; clients take it as `insecure` or by a pin. With a certificate or key, or REALITY, an error."
    }
   },
   "additionalProperties": false
  },
  "inbounds[tuic].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    }
   },
   "additionalProperties": false
  },
  "inbounds[tuic].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Btuic%5D.tls.reality.handshake"
    },
    "private_key": {
     "type": "string",
     "description": "X25519, hex or base64url."
    },
    "short_id": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "max_time_difference": {
     "type": "string",
     "description": "How far a client's clock may be from ours, e.g. `1m`. Unset, any time is accepted, as in sing-box."
    }
   },
   "additionalProperties": false
  },
  "inbounds[tuic].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour to the REALITY handshake server: it would be reached otherwise"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Btuic%5D.tls.reality.handshake.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    }
   },
   "additionalProperties": false
  },
  "inbounds[tuic].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[tuic].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "uuid": {
     "type": "string"
    },
    "password": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "inbounds[tun]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "interface_name": {
     "type": "string",
     "description": "The device's name, used as it is: a start fails if it is taken. Without it, on macOS one past the highest utunN is chosen at start, as sing-box chooses, and kept across reloads (a host reads it back); one another program takes before the device opens is given up for the next free one, three at most. Elsewhere utun233."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "mtu": {
     "type": "number",
     "description": "9000 when omitted, as sing-box has it on Android."
    },
    "address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The device's addresses with their prefixes: one IPv4, one IPv6, or one of each."
    },
    "dns_mode": {
     "type": "string",
     "examples": [
      "disabled",
      "native",
      "hijack"
     ],
     "description": "sing-box 1.14's: whether the TUN's DNS is the system's, `native`, and its port 53 taken too, `hijack`, or neither, `disabled`. `hijack` with `auto_route`, `disabled` without, when unset. Port 53 is taken with auto_redirect on Linux and strict_route on Windows; on macOS `hijack` is `native`."
    },
    "dns_address": {
     "not": {},
     "description": "sail refuses this field: The TUN's own DNS handling: queries would be answered otherwise"
    },
    "auto_route": {
     "type": "boolean",
     "description": "Routes the system's traffic into the device."
    },
    "iproute2_table_index": {
     "type": "number",
     "description": "Linux: the routing table of the device's routes (2022). Elsewhere, or without `auto_route`, it changes nothing, and is ignored with a warning, as in sing-box; so is `iproute2_rule_index`."
    },
    "iproute2_rule_index": {
     "type": "number",
     "description": "Linux: the first of auto_route's and auto_redirect's ip rules (9000); the rules from it to 10 after it are sail's, and removed at start and stop."
    },
    "auto_redirect": {
     "type": "boolean",
     "description": "Linux: redirects TCP to sail with nftables and marks the rest into the device, and lets rules bypass sail before a connection is set up (sing-box 1.13). Without it, the fields of the redirect (its marks, NFQUEUE and fallback rule, and `exclude_mptcp`) change nothing, and are ignored with a warning, as in sing-box."
    },
    "auto_redirect_input_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "The mark that routes a packet into the device (0x2023). Marks are numbers, or strings of hexadecimal (\"0x2023\"); 0 is the default."
    },
    "auto_redirect_output_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "The mark sail's own sockets carry, and flows that bypass it (0x2024). `route.default_mark` and `routing_mark` conflict with it."
    },
    "auto_redirect_reset_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "The mark of a connection pre-match rejects, which the kernel resets (0x2025)."
    },
    "auto_redirect_nfqueue": {
     "type": "number",
     "description": "The NFQUEUE pre-match reads first packets from (100). If it cannot be bound, sail runs without pre-match: `bypass` rules are skipped."
    },
    "auto_redirect_iproute2_fallback_rule_index": {
     "type": "number",
     "description": "The ip rule that sends what the main table has no route for into the device (32768)."
    },
    "exclude_mptcp": {
     "type": "boolean",
     "description": "Lets MPTCP go past sail rather than dropping it, which makes clients fall back to TCP."
    },
    "loopback_address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Addresses whose TCP goes into the device rather than to the redirect listener: a destination sail's own listeners use, say."
    },
    "strict_route": {
     "type": "boolean",
     "description": "With `auto_route`, keeps traffic from going past sail. Linux: with one family on the device, the other is unreachable. Windows: firewall rules, as sing-tun's: DNS leaves only through the device, but for sail's own, and with no IPv6 on the device, none leaves. Elsewhere it changes nothing, as in sing-box."
    },
    "route_address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Only these destinations are taken..."
    },
    "route_address_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Rule-sets whose destination `ip_cidr` alone are taken, kept up to date as they are downloaded again."
    },
    "route_exclude_address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "...and not these."
    },
    "route_exclude_address_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Rule-sets whose destination `ip_cidr` are not taken."
    },
    "include_interface": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Linux, with `auto_route`: forwarded traffic is taken only from these interfaces..."
    },
    "exclude_interface": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "...or not from these. Naming `lo` in either leaves the host's own traffic out."
    },
    "include_uid": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ],
     "description": "Linux, with `auto_route`: the host's traffic is taken only from these users..."
    },
    "include_uid_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "...and from these ranges, as \"1000:2000\"."
    },
    "exclude_uid": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ],
     "description": "The host's traffic of these users is not taken..."
    },
    "exclude_uid_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "...nor of these ranges."
    },
    "include_android_user": {
     "not": {},
     "description": "sail refuses this field: Not supported; include_uid_range takes in an Android user's apps (user N's are uids N*100000 to N*100000+99999)"
    },
    "include_package": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Android: the apps the host's VPN takes in or leaves out, applied by the host."
    },
    "exclude_package": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "include_mac_address": {
     "not": {},
     "description": "sail refuses this field: Filtering LAN clients by MAC address"
    },
    "exclude_mac_address": {
     "not": {},
     "description": "sail refuses this field: Filtering LAN clients by MAC address"
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "udp_mapping": {
     "type": "string",
     "examples": [
      "endpoint_independent",
      "address_dependent",
      "address_and_port_dependent"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How UDP mappings are made and how many are kept: the same traffic"
    },
    "udp_filtering": {
     "type": "string",
     "examples": [
      "endpoint_independent",
      "address_dependent",
      "address_and_port_dependent"
     ],
     "description": "sing-box 1.14's: which remote addresses reach an app through the port it sent from. `endpoint_independent`: any (full cone, as P2P and some games need). `address_and_port_dependent`, the default: only an address and port the app sent to. `address_dependent` is not implemented, and is an error. An app's port is one mapping in every case."
    },
    "udp_nat_max": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: How UDP mappings are made and how many are kept: the same traffic"
    },
    "stack": {
     "type": "string",
     "examples": [
      "system",
      "gvisor",
      "mixed"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    },
    "platform": {
     "$ref": "#/$defs/inbounds%5Btun%5D.platform",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    },
    "endpoint_independent_nat": {
     "type": "boolean",
     "description": "sing-box's older name for `udp_filtering: endpoint_independent`, deprecated there; the two may not disagree.",
     "deprecated": true
    },
    "multi_queue": {
     "type": "boolean",
     "description": "sing-box 1.15's: Linux opens the device with `IFF_MULTI_QUEUE`, a queue and a netstack shard to each CPU, eight at most. Off, the default, one queue: measured faster in every case tried (Trojan over TUN, 2 and 4 cores, 2026-10-15: 2 queues 3-9% slower, 4 queues 4-9%). Elsewhere, and on a device the host opens, ignored with a warning."
    },
    "type": {
     "const": "tun"
    }
   },
   "additionalProperties": false
  },
  "inbounds[tun].platform": {
   "type": "object",
   "properties": {
    "http_proxy": {
     "$ref": "#/$defs/inbounds%5Btun%5D.platform.http_proxy",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    }
   },
   "additionalProperties": false
  },
  "inbounds[tun].platform.http_proxy": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    },
    "server": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    },
    "server_port": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    },
    "bypass_domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    },
    "match_domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: One stack serves every `stack`; the platform proxy is the host's to set"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bvless%5D.users%5B%5D"
     }
    },
    "tls": {
     "$ref": "#/$defs/inbounds%5Bvless%5D.tls"
    },
    "multiplex": {
     "$ref": "#/$defs/inbounds%5Bvless%5D.multiplex"
    },
    "transport": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "grpc",
        "http",
        "httpupgrade",
        "ws"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "grpc"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvless%5D.transport%5Bgrpc%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "http"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvless%5D.transport%5Bhttp%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "httpupgrade"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvless%5D.transport%5Bhttpupgrade%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "ws"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvless%5D.transport%5Bws%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "fallback": {
     "$ref": "#/$defs/inbounds%5Bvless%5D.fallback",
     "description": "Where a connection that fails to authenticate is relayed."
    },
    "fallback_for_alpn": {
     "type": "object",
     "additionalProperties": {
      "$ref": "#/$defs/inbounds%5Bvless%5D.fallback_for_alpn"
     },
     "description": "The same, by the ALPN the connection's TLS negotiated; the ones it does not name go to `fallback`."
    },
    "type": {
     "const": "vless"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].fallback": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].fallback_for_alpn": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "padding": {
     "type": "boolean",
     "description": "sing-mux: refuse connections that are not padded."
    },
    "brutal": {
     "$ref": "#/$defs/inbounds%5Bvless%5D.multiplex.brutal",
     "description": "sing-mux: TCP Brutal for clients that ask for it; Linux only."
    },
    "protocol": {
     "type": "string",
     "description": "`amux`; unset, sing-mux, which sing-box's block has no field for: its server takes smux, yamux and h2mux alike."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "server_name": {
     "type": "string",
     "description": "The name REALITY clients must ask for, or the one a `self_signed` certificate is for; otherwise it is ignored with a warning, as sing-box ignores it."
    },
    "insecure": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only relaxes checks a server's TLS does not make"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to accept, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate."
    },
    "certificate_path": {
     "type": "string"
    },
    "client_authentication": {
     "type": "string",
     "examples": [
      "no",
      "request",
      "require-any",
      "verify-if-given",
      "require-and-verify"
     ],
     "description": "What is asked of clients' certificates, as sing-box takes it: `no` (none is asked for), `request` or `require-any` (one is taken unchecked; `require-any` refuses a client without), `verify-if-given` or `require-and-verify` (one is checked, by the CAs or the pins; `require-and-verify` refuses a client without). Unset is `no`, or `require-and-verify` with CAs set. Pins without a verifying mode, and CAs or pins with `request` or `require-any`, are errors, where sing-box checks no certificate."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs clients' certificates are verified by, inline PEM: chained to one of them, by the intermediates the client sends, valid, and for client authentication. With `client_certificate_path` too, the files are ignored with a warning, as sing-box ignores them."
    },
    "client_certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs, from PEM (or DER) files, as `client_certificate`. The files are followed as the certificate's are: CAs written to them are taken for the connections that come next."
    },
    "client_certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "Clients' certificates taken by the SHA-256 of their public key (SubjectPublicKeyInfo), standard base64, in place of CAs: the leaf alone, no CA or validity period. With `client_certificate_sha256`, either list passing is enough. Beside CAs, ignored with a warning, as sing-box ignores them."
    },
    "key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM key."
    },
    "key_path": {
     "type": "string"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "reality": {
     "$ref": "#/$defs/inbounds%5Bvless%5D.tls.reality"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "client_certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, read ahead: clients' certificates taken by the SHA-256 of the whole leaf (its DER), standard base64 or hex, looked at before `client_certificate_public_key_sha256`, as that is."
    },
    "self_signed": {
     "type": "boolean",
     "description": "A sail extension: with no certificate or key set, a self-signed one the instance makes, for `server_name` if set, as Mihomo's Hysteria2 and TUIC listeners serve one without a certificate. It is made once and kept across reloads that rebuild the inbound in place; clients take it as `insecure` or by a pin. With a certificate or key, or REALITY, an error."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Bvless%5D.tls.reality.handshake"
    },
    "private_key": {
     "type": "string",
     "description": "X25519, hex or base64url."
    },
    "short_id": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "max_time_difference": {
     "type": "string",
     "description": "How far a client's clock may be from ours, e.g. `1m`. Unset, any time is accepted, as in sing-box."
    },
    "server_names": {
     "type": "array",
     "description": "A sail extension, Xray's `serverNames` and Mihomo's `server-names`: more names clients may ask for, beside `tls.server_name`."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour to the REALITY handshake server: it would be reached otherwise"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Bvless%5D.tls.reality.handshake.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[vless].transport[grpc]": {
   "type": "object",
   "properties": {
    "service_name": {
     "type": "string"
    },
    "idle_timeout": {
     "type": "string",
     "description": "Unset, no keepalive pings. A client pings this often; a server after this long with nothing received, so give a server no shorter a time than its clients' interval."
    },
    "ping_timeout": {
     "type": "string"
    },
    "permit_without_stream": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Response headers and keepalive of a WebSocket or gRPC server: the same streams"
    },
    "type": {
     "const": "grpc"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].transport[http]": {
   "type": "object",
   "properties": {
    "host": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "path": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "method": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "ping_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].transport[httpupgrade]": {
   "type": "object",
   "properties": {
    "host": {
     "type": "string",
     "description": "The `Host` a request must carry; unset, any."
    },
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object",
     "description": "Added to the response."
    },
    "type": {
     "const": "httpupgrade"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].transport[ws]": {
   "type": "object",
   "properties": {
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Response headers and keepalive of a WebSocket or gRPC server: the same streams"
    },
    "max_early_data": {
     "type": "number",
     "description": "The most early data a client may send in its upgrade request."
    },
    "early_data_header_name": {
     "type": "string",
     "description": "The header it comes in; unset, it comes in the path."
    },
    "forwarded_header": {
     "type": "string",
     "description": "The header a trusted reverse proxy in front puts the client's address in, such as `X-Forwarded-For`. Unset, no header is believed: anyone can send one."
    },
    "type": {
     "const": "ws"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vless].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "uuid": {
     "type": "string"
    },
    "flow": {
     "type": "string",
     "description": "`\"\"` or `xtls-rprx-vision`."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "listen": {
     "type": "string",
     "description": "The address to listen on; defaults to `127.0.0.1`."
    },
    "listen_port": {
     "type": "number",
     "description": "The port to listen on. An inbound without one does not listen, and is only useful as a part of another inbound."
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Where and how an inbound listens: it would take connections otherwise"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long an accepted TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open on the TCP port it listens on: what a client that has the server's cookie sends with its SYN is taken at once. On Linux, only with the server bit of `net.ipv4.tcp_fastopen` (2; 3 for client and server), which the default (1) leaves off."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether the datagrams it sends from its UDP sockets may be fragmented on the way: where not, they carry don't-fragment, and one larger than the path takes is refused rather than sent in pieces. Unset, as sing-box: they may for direct and hysteria2, and may not for the others."
    },
    "udp_timeout": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "How long a UDP session through this inbound lives without traffic; 5m when unset, as in sing-box. A number is of seconds."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Handing an inbound's connections to another inbound"
    },
    "users": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/inbounds%5Bvmess%5D.users%5B%5D"
     }
    },
    "tls": {
     "$ref": "#/$defs/inbounds%5Bvmess%5D.tls"
    },
    "multiplex": {
     "$ref": "#/$defs/inbounds%5Bvmess%5D.multiplex"
    },
    "transport": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "grpc",
        "http",
        "httpupgrade",
        "ws"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "grpc"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvmess%5D.transport%5Bgrpc%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "http"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvmess%5D.transport%5Bhttp%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "httpupgrade"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvmess%5D.transport%5Bhttpupgrade%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "ws"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/inbounds%5Bvmess%5D.transport%5Bws%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "type": {
     "const": "vmess"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "padding": {
     "type": "boolean",
     "description": "sing-mux: refuse connections that are not padded."
    },
    "brutal": {
     "$ref": "#/$defs/inbounds%5Bvmess%5D.multiplex.brutal",
     "description": "sing-mux: TCP Brutal for clients that ask for it; Linux only."
    },
    "protocol": {
     "type": "string",
     "description": "`amux`; unset, sing-mux, which sing-box's block has no field for: its server takes smux, yamux and h2mux alike."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "server_name": {
     "type": "string",
     "description": "The name REALITY clients must ask for, or the one a `self_signed` certificate is for; otherwise it is ignored with a warning, as sing-box ignores it."
    },
    "insecure": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Only relaxes checks a server's TLS does not make"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to accept, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate."
    },
    "certificate_path": {
     "type": "string"
    },
    "client_authentication": {
     "type": "string",
     "examples": [
      "no",
      "request",
      "require-any",
      "verify-if-given",
      "require-and-verify"
     ],
     "description": "What is asked of clients' certificates, as sing-box takes it: `no` (none is asked for), `request` or `require-any` (one is taken unchecked; `require-any` refuses a client without), `verify-if-given` or `require-and-verify` (one is checked, by the CAs or the pins; `require-and-verify` refuses a client without). Unset is `no`, or `require-and-verify` with CAs set. Pins without a verifying mode, and CAs or pins with `request` or `require-any`, are errors, where sing-box checks no certificate."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs clients' certificates are verified by, inline PEM: chained to one of them, by the intermediates the client sends, valid, and for client authentication. With `client_certificate_path` too, the files are ignored with a warning, as sing-box ignores them."
    },
    "client_certificate_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The CAs, from PEM (or DER) files, as `client_certificate`. The files are followed as the certificate's are: CAs written to them are taken for the connections that come next."
    },
    "client_certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "Clients' certificates taken by the SHA-256 of their public key (SubjectPublicKeyInfo), standard base64, in place of CAs: the leaf alone, no CA or validity period. With `client_certificate_sha256`, either list passing is enough. Beside CAs, ignored with a warning, as sing-box ignores them."
    },
    "key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM key."
    },
    "key_path": {
     "type": "string"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "certificate_provider": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "reality": {
     "$ref": "#/$defs/inbounds%5Bvmess%5D.tls.reality"
    },
    "acme": {
     "not": {},
     "description": "sail refuses this field: A certificate from a provider or ACME: the inbound would have none"
    },
    "client_certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, read ahead: clients' certificates taken by the SHA-256 of the whole leaf (its DER), standard base64 or hex, looked at before `client_certificate_public_key_sha256`, as that is."
    },
    "self_signed": {
     "type": "boolean",
     "description": "A sail extension: with no certificate or key set, a self-signed one the instance makes, for `server_name` if set, as Mihomo's Hysteria2 and TUIC listeners serve one without a certificate. It is made once and kept across reloads that rebuild the inbound in place; clients take it as `insecure` or by a pin. With a certificate or key, or REALITY, an error."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    },
    "key_path": {
     "not": {},
     "description": "sail refuses this field: Encrypted Client Hello on an inbound"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "handshake": {
     "$ref": "#/$defs/inbounds%5Bvmess%5D.tls.reality.handshake"
    },
    "private_key": {
     "type": "string",
     "description": "X25519, hex or base64url."
    },
    "short_id": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "max_time_difference": {
     "type": "string",
     "description": "How far a client's clock may be from ours, e.g. `1m`. Unset, any time is accepted, as in sing-box."
    },
    "server_names": {
     "type": "array",
     "description": "A sail extension, Xray's `serverNames` and Mihomo's `server-names`: more names clients may ask for, beside `tls.server_name`."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].tls.reality.handshake": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour to the REALITY handshake server: it would be reached otherwise"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/inbounds%5Bvmess%5D.tls.reality.handshake.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].tls.reality.handshake.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "inbounds[vmess].transport[grpc]": {
   "type": "object",
   "properties": {
    "service_name": {
     "type": "string"
    },
    "idle_timeout": {
     "type": "string",
     "description": "Unset, no keepalive pings. A client pings this often; a server after this long with nothing received, so give a server no shorter a time than its clients' interval."
    },
    "ping_timeout": {
     "type": "string"
    },
    "permit_without_stream": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Response headers and keepalive of a WebSocket or gRPC server: the same streams"
    },
    "type": {
     "const": "grpc"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].transport[http]": {
   "type": "object",
   "properties": {
    "host": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "path": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "method": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "ping_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].transport[httpupgrade]": {
   "type": "object",
   "properties": {
    "host": {
     "type": "string",
     "description": "The `Host` a request must carry; unset, any."
    },
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object",
     "description": "Added to the response."
    },
    "type": {
     "const": "httpupgrade"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].transport[ws]": {
   "type": "object",
   "properties": {
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Response headers and keepalive of a WebSocket or gRPC server: the same streams"
    },
    "max_early_data": {
     "type": "number",
     "description": "The most early data a client may send in its upgrade request."
    },
    "early_data_header_name": {
     "type": "string",
     "description": "The header it comes in; unset, it comes in the path."
    },
    "forwarded_header": {
     "type": "string",
     "description": "The header a trusted reverse proxy in front puts the client's address in, such as `X-Forwarded-For`. Unset, no header is believed: anyone can send one."
    },
    "type": {
     "const": "ws"
    }
   },
   "additionalProperties": false
  },
  "inbounds[vmess].users[]": {
   "type": "object",
   "properties": {
    "name": {
     "type": "string",
     "description": "Who the user is to routing (`auth_user`), statistics and logs."
    },
    "uuid": {
     "type": "string"
    },
    "alterId": {
     "type": "number",
     "description": "Only 0: AEAD headers. Legacy VMess is not served."
    }
   },
   "additionalProperties": false
  },
  "log": {
   "type": "object",
   "properties": {
    "disabled": {
     "type": "boolean",
     "description": "Logs nothing."
    },
    "level": {
     "type": "string",
     "enum": [
      "trace",
      "debug",
      "info",
      "warn",
      "error",
      "fatal",
      "panic"
     ]
    },
    "output": {
     "type": "string",
     "description": "A file to append to. Logs go to the console when it is not set."
    },
    "timestamp": {
     "type": "boolean",
     "description": "Starts each line with the time."
    },
    "format": {
     "type": "string",
     "enum": [
      "full",
      "compact"
     ],
     "description": "A sail extension: `compact` writes the message alone."
    },
    "redact": {
     "type": "array",
     "description": "A sail extension: what lines at INFO, WARN and ERROR leave out. DEBUG and TRACE lines are not redacted."
    }
   },
   "additionalProperties": false
  },
  "network_namespaces[]": {
   "type": "object",
   "properties": {
    "type": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces to listen and dial in"
    },
    "tag": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces to listen and dial in"
    },
    "path": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces to listen and dial in"
    }
   },
   "additionalProperties": false
  },
  "ntp": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "interval": {
     "type": "string",
     "description": "How often the offset is measured again; 30m when unset."
    },
    "write_to_system": {
     "type": "boolean",
     "description": "Setting the system's clock, which sail never does: an error."
    },
    "server": {
     "type": "string",
     "description": "The server's name or address."
    },
    "server_port": {
     "type": "number",
     "description": "123 when unset."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "type": "string",
     "description": "Not implemented yet."
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "description": "Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/ntp.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    }
   },
   "additionalProperties": false
  },
  "ntp.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbound_providers[]": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string",
     "enum": [
      "remote",
      "local",
      "inline"
     ]
    },
    "tag": {
     "type": "string",
     "description": "Its members' keys name it, and groups' `providers`."
    },
    "url": {
     "type": "string",
     "description": "`remote`: where it is downloaded from."
    },
    "path": {
     "type": "string",
     "description": "`local`: the file, in the data directory unless absolute."
    },
    "update_interval": {
     "type": "string",
     "description": "`remote`: how often it is downloaded again, 1d when unset. `local`: how often the file is read again, never when unset."
    },
    "download_detour": {
     "type": "string",
     "description": "`remote`: the outbound it is downloaded through, as a remote rule-set's."
    },
    "http_client": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "object"
      }
     ],
     "description": "`remote`: the HTTP client it is downloaded with, as a remote rule-set's."
    },
    "size_limit": {
     "type": "number",
     "description": "`remote`, a sail extension (Mihomo's `size-limit`): the most a download of it may be, in bytes; past it the download fails and the outbounds in use are kept. Unset, the download client's own cap."
    },
    "filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`remote`, `local`: regular expressions, as Mihomo's `filter`; only the outbounds whose names match one are taken, those of the first first."
    },
    "exclude_filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`remote`, `local`: regular expressions no name taken may match."
    },
    "exclude_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`remote`, `local`: the Clash types (`ss`, `vmess`, ...) not taken, without case."
    },
    "override": {
     "type": "object",
     "description": "`remote`, `local`: what is changed in every outbound taken, in the keys of Mihomo's `override` (`skip-cert-verify`, `additional-prefix`, `proxy-name`, ...)."
    },
    "detour": {
     "type": "string",
     "description": "`remote`, `local`: the outbound every outbound taken dials through, as Mihomo's `dialer-proxy`."
    },
    "outbounds": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/outbound_providers%5B%5D.outbounds%5B%5D"
     },
     "description": "`inline`: the outbounds, their tags their names as members."
    }
   },
   "additionalProperties": false
  },
  "outbound_providers[].outbounds[]": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string"
    },
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    }
   },
   "additionalProperties": false
  },
  "outbounds[anytls]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Banytls%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string",
     "description": "May be left out, with `server_port`, by an outbound with a `detour`: one over ShadowTLS, which dials its own server."
    },
    "server_port": {
     "type": "number"
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Banytls%5D.tls"
    },
    "password": {
     "type": "string"
    },
    "idle_session_check_interval": {
     "type": "string"
    },
    "idle_session_timeout": {
     "type": "string"
    },
    "min_idle_session": {
     "type": "number"
    },
    "client_metadata": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Metadata the client tells the server: the connection goes the same way without it"
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "type": {
     "const": "anytls"
    }
   },
   "additionalProperties": false
  },
  "outbounds[anytls].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[anytls].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Banytls%5D.tls.ech"
    },
    "utls": {
     "$ref": "#/$defs/outbounds%5Banytls%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Banytls%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[anytls].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[anytls].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[anytls].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[block]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "type": {
     "const": "block"
    }
   },
   "additionalProperties": false
  },
  "outbounds[direct]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: A detour for a direct outbound, which sing-box refuses too"
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bdirect%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "type": {
     "const": "direct"
    }
   },
   "additionalProperties": false
  },
  "outbounds[direct].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[fallback]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "outbounds": {
     "type": "array",
     "description": "Its members, in order; none may be when its providers give others."
    },
    "providers": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The outbound providers, by tag, whose outbounds join the group's own, in this order."
    },
    "filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions, as Mihomo's `filter`: of the providers' outbounds, only those whose names match one are members, those of the first first. The group's own outbounds are not filtered."
    },
    "exclude_filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions no member's name may match, the group's own outbounds' too."
    },
    "exclude_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The types no member may be of, the group's own outbounds too, in Mihomo's names for them, without case: `Shadowsocks`, `Vmess`, `Socks5`, `Direct`, ..."
    },
    "empty_fallback": {
     "type": "string",
     "description": "An outbound, not a group, that is the member while there is none else. Without it such a group has none, and its connections fail."
    },
    "url": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "What is requested through each member to test it: a URL, or a list of them, a sail extension, all tested at once in each round. The latency shown is the first URL's, and the API shows it as the group's `testUrl`."
    },
    "url_policy": {
     "type": "string",
     "enum": [
      "any",
      "all"
     ],
     "description": "With several URLs, which a member must answer to pass: `any` of them, which tells a dead member from a URL blocked, or `all`; a sail extension. Under `any`, the latency shown is that of the first URL that answered."
    },
    "expected_status": {
     "type": "string",
     "description": "The HTTP statuses a test must be answered with to pass, as Mihomo's `expected-status`: codes and ranges, `200/204/401-429`; any when unset. Each URL's answer must be one."
    },
    "unified_delay": {
     "type": "boolean",
     "description": "The latency of a second request on the connection the first opened, without the connect and handshakes, as Mihomo's `unified-delay`; a sail extension."
    },
    "interval": {
     "type": "string"
    },
    "timeout": {
     "type": "string",
     "description": "How long a test may take before its member counts as failed; 5s, as Mihomo's `timeout`. Also how close together `max_failed_times` failures must come, and `dial_timeout` when that is unset."
    },
    "dial_timeout": {
     "type": "string",
     "description": "How long a connection attempt through a member, with a member left to fall back to, may take before the group moves on to the next; a sail extension, 1s at least, `timeout` when unset. One still dialling the member's server then marks it down at once; one in the member's handshake is counted toward `max_failed_times`."
    },
    "max_failed_times": {
     "type": "number",
     "description": "How many failed connections, within `timeout` of the first, have the members tested again; 5, as Mihomo's `max-failed-times`. Only failures that may be the destination's count: one that says the member's server cannot be reached marks the member down at once."
    },
    "lazy": {
     "type": "boolean",
     "description": "Tests only while the group is in use: not when it was not used since the last ones."
    },
    "interrupt_exist_connections": {
     "type": "boolean",
     "description": "Ends the connections through the member left once the group switches."
    },
    "debounce": {
     "$ref": "#/$defs/outbounds%5Bfallback%5D.debounce",
     "description": "How many rounds of tests in a row have the group leave a member, or take an earlier one back, and how long it stays on a member at least; a sail extension. Unset, every round counts at once."
    },
    "disable_udp": {
     "description": "The group carries TCP alone, whatever member it picks (Mihomo's disable-udp)"
    },
    "type": {
     "const": "fallback"
    }
   },
   "additionalProperties": false
  },
  "outbounds[fallback].debounce": {
   "type": "object",
   "properties": {
    "fail_after": {
     "type": "number",
     "description": "Failed rounds in a row before the member the group is on is left, by default one. A connection that finds its server unreachable leaves it at once all the same."
    },
    "recover_after": {
     "type": "number",
     "description": "Passed rounds in a row before a member that was down, failed or found unreachable, is up again, and taken back if it comes first, by default one."
    },
    "min_dwell": {
     "type": "string",
     "description": "The least time on a member before the group leaves it, while it is up, for an earlier member up again; 0s. The first round past it switches. A member down is left at once."
    }
   },
   "additionalProperties": false
  },
  "outbounds[http]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bhttp%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string",
     "description": "May be left out, with `server_port`, by an outbound with a `detour`: one over ShadowTLS, which dials its own server."
    },
    "server_port": {
     "type": "number"
    },
    "username": {
     "type": "string"
    },
    "password": {
     "type": "string"
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Bhttp%5D.tls"
    },
    "path": {
     "type": "string",
     "description": "The request target instead of the destination, which then goes only in `Host`, as sing-box sends it."
    },
    "headers": {
     "type": "object",
     "description": "Sent with every `CONNECT`."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "version": {
     "type": "number",
     "description": "The HTTP version, sing-box 1.15's: 1, 2 or 3; unset (or 0), 1, as sing-box 1.14 speaks, until sail follows 1.15 stable. HTTP/2 needs TLS, and not REALITY's: without, HTTP/1.1. 3 is HTTP/2, which sail speaks in its place."
    },
    "disable_version_fallback": {
     "type": "boolean",
     "description": "HTTP/2 alone, never HTTP/1.1 in its place: a server that picks no `h2` is an error."
    },
    "idle_timeout": {
     "type": "string",
     "description": "HTTP/2's, sing-box 1.15's: how long a ping may go unanswered."
    },
    "keep_alive_period": {
     "type": "string",
     "description": "HTTP/2's: a ping after this long with nothing received."
    },
    "stream_receive_window": {
     "type": "number",
     "description": "HTTP/2's: a tunnel's receive window."
    },
    "connection_receive_window": {
     "type": "number",
     "description": "HTTP/2's: a connection's receive window."
    },
    "max_concurrent_streams": {
     "type": "number",
     "description": "HTTP/2's: the most tunnels one connection carries."
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "outbounds[http].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[http].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Bhttp%5D.tls.ech"
    },
    "utls": {
     "$ref": "#/$defs/outbounds%5Bhttp%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Bhttp%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[http].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[http].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[http].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bhysteria2%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number",
     "description": "The one port; with `server_ports`, not needed."
    },
    "server_ports": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Ports or ranges (\"20000:30000\") to hop between."
    },
    "hop_interval": {
     "type": "string",
     "description": "How often to hop, 30s unless set."
    },
    "hop_interval_max": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Hysteria's congestion tuning and debugging, the longest hop interval, and its QUIC fingerprint: the same traffic"
    },
    "up_mbps": {
     "type": "number",
     "description": "What we may send at; set, it selects Brutal."
    },
    "down_mbps": {
     "type": "number",
     "description": "What we can receive at, told to the server."
    },
    "obfs": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "gecko",
        "salamander"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "gecko"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bhysteria2%5D.obfs%5Bgecko%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "salamander"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bhysteria2%5D.obfs%5Bsalamander%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "password": {
     "type": "string"
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ],
     "description": "\"tcp\" or \"udp\", or both, as unset."
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Bhysteria2%5D.tls"
    },
    "idle_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "keep_alive_period": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "stream_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "connection_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "max_concurrent_streams": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "initial_packet_size": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "disable_path_mtu_discovery": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "bbr_profile": {
     "type": "string",
     "examples": [
      "standard",
      "conservative",
      "aggressive"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Hysteria's congestion tuning and debugging, the longest hop interval, and its QUIC fingerprint: the same traffic"
    },
    "brutal_debug": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Hysteria's congestion tuning and debugging, the longest hop interval, and its QUIC fingerprint: the same traffic"
    },
    "disable_chrome_parrot": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Hysteria's congestion tuning and debugging, the longest hop interval, and its QUIC fingerprint: the same traffic"
    },
    "realm": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "type": {
     "const": "hysteria2"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[hysteria2].obfs[gecko]": {
   "type": "object",
   "properties": {
    "password": {
     "type": "string"
    },
    "min_packet_size": {
     "not": {},
     "description": "sail refuses this field: The packet sizes of the gecko obfuscation: the packets would look otherwise"
    },
    "max_packet_size": {
     "not": {},
     "description": "sail refuses this field: The packet sizes of the gecko obfuscation: the packets would look otherwise"
    },
    "type": {
     "const": "gecko"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].obfs[salamander]": {
   "type": "object",
   "properties": {
    "password": {
     "type": "string"
    },
    "type": {
     "const": "salamander"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm": {
   "type": "object",
   "properties": {
    "server_url": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "token": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "realm_id": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "stun_servers": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "ip_version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "port_mapping": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "http_client": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm.http_client": {
   "type": "object",
   "properties": {
    "engine": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_version_fallback": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tls": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "detour": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "bind_interface": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "inet4_bind_address": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "inet6_bind_address": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "bind_address_no_port": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "protect_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "routing_mark": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "reuse_addr": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "connect_timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_fast_open": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_multi_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_tcp_keep_alive": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_keep_alive": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "tcp_keep_alive_interval": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "udp_fragment": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "domain_resolver": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "network_strategy": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "network_type": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fallback_network_type": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "keep_alive_period": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "stream_receive_window": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "connection_receive_window": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "max_concurrent_streams": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "initial_packet_size": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_path_mtu_discovery": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "domain_strategy": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm.http_client.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "strategy": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_cache": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_optimistic_cache": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "rewrite_ttl": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_subnet": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm.http_client.tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "engine": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "disable_sni": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "server_name": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "insecure": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "min_version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "max_version": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "certificate": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "certificate_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "certificate_public_key_sha256": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_certificate": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_certificate_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_key": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "client_key_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "kernel_tx": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "kernel_rx": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "handshake_timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "reality": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm.http_client.tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm.http_client.tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "short_id": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm.http_client.tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].realm.port_mapping": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "timeout": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    },
    "lifetime": {
     "not": {},
     "description": "sail refuses this field: Meeting peers through a Hysteria realm: connections would be made otherwise"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Bhysteria2%5D.tls.ech"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: Not supported over QUIC"
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Bhysteria2%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[hysteria2].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: Not supported over QUIC"
    }
   },
   "additionalProperties": false
  },
  "outbounds[load-balance]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "outbounds": {
     "type": "array",
     "description": "Its members; none may be when its providers give others."
    },
    "providers": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The outbound providers, by tag, whose outbounds join the group's own, in this order."
    },
    "filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions, as Mihomo's `filter`: of the providers' outbounds, only those whose names match one are members, those of the first first. The group's own outbounds are not filtered."
    },
    "exclude_filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions no member's name may match, the group's own outbounds' too."
    },
    "exclude_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The types no member may be of, the group's own outbounds too, in Mihomo's names for them, without case: `Shadowsocks`, `Vmess`, `Socks5`, `Direct`, ..."
    },
    "empty_fallback": {
     "type": "string",
     "description": "An outbound, not a group, that is the member while there is none else. Without it such a group has none, and its connections fail."
    },
    "strategy": {
     "type": "string",
     "enum": [
      "consistent-hashing",
      "round-robin",
      "sticky-sessions"
     ]
    },
    "hash_key": {
     "type": "string",
     "enum": [
      "user"
     ],
     "description": "`user`: a connection's user is its key, not its destination (and source); a sail extension. Unset, or a connection of no user, as without it. round-robin keys on nothing, and refuses it."
    },
    "url": {
     "type": "string",
     "description": "What is requested through each member to test it."
    },
    "interval": {
     "type": "string"
    },
    "expected_status": {
     "type": "string",
     "description": "The HTTP statuses a test must be answered with to pass, as urltest's; any when unset."
    },
    "unified_delay": {
     "type": "boolean",
     "description": "The latency of a second request on the connection the first opened, without the connect and handshakes, as Mihomo's `unified-delay`; a sail extension."
    },
    "timeout": {
     "type": "string",
     "description": "How long a test may take before its member counts as failed; 5s. Also how close together `max_failed_times` failures must come, as urltest's."
    },
    "max_failed_times": {
     "type": "number",
     "description": "How many failed connections, within `timeout` of the first, have the members tested again; 5, as urltest's."
    },
    "lazy": {
     "type": "boolean",
     "description": "Tests only while the group is in use: not when it was not used since the last ones."
    },
    "disable_udp": {
     "description": "The group carries TCP alone, whatever member it picks (Mihomo's disable-udp)"
    },
    "type": {
     "const": "load-balance"
    }
   },
   "additionalProperties": false
  },
  "outbounds[mptp]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "outbounds": {
     "type": "array"
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "type": {
     "const": "mptp"
    }
   },
   "additionalProperties": false
  },
  "outbounds[network]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "branches": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/outbounds%5Bnetwork%5D.branches%5B%5D"
     },
     "description": "Tried in order: the first whose conditions the network matches takes the connection."
    },
    "default": {
     "type": "string",
     "description": "Where connections go when no branch matches."
    },
    "type": {
     "const": "network"
    }
   },
   "additionalProperties": false
  },
  "outbounds[network].branches[]": {
   "type": "object",
   "properties": {
    "outbound": {
     "type": "string"
    },
    "wifi_ssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "wifi_bssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`wifi`, `cellular`, `ethernet`, `other`."
    },
    "network_is_expensive": {
     "type": "boolean"
    },
    "network_is_constrained": {
     "type": "boolean"
    },
    "wifi_ssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "wifi_bssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Matched whatever the case."
    },
    "network_gateway": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "network_mcc_mnc": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Only off Wi-Fi."
    }
   },
   "additionalProperties": false
  },
  "outbounds[pass]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "type": {
     "const": "pass"
    }
   },
   "additionalProperties": false
  },
  "outbounds[plugin]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "path": {
     "type": "string",
     "description": "The shared library to load."
    },
    "args": {
     "type": "string"
    },
    "type": {
     "const": "plugin"
    }
   },
   "additionalProperties": false
  },
  "outbounds[redirect]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "type": "number",
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "description": "Not implemented yet."
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "description": "Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "$ref": "#/$defs/outbounds%5Bredirect%5D.domain_resolver",
     "description": "The DNS server that resolves the names dialled."
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "type": {
     "const": "redirect"
    }
   },
   "additionalProperties": false
  },
  "outbounds[redirect].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "timeout": {
     "type": "string"
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "$ref": "#/$defs/outbounds%5Bredirect%5D.domain_resolver.client_subnet"
    }
   },
   "additionalProperties": false
  },
  "outbounds[redirect].domain_resolver.client_subnet": {
   "type": "object",
   "properties": {
    "addr": {
     "type": "string"
    },
    "len": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "outbounds[selector]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "outbounds": {
     "type": "array",
     "description": "Its members; none may be when its providers give others."
    },
    "default": {
     "type": "string",
     "description": "Selected when nothing was selected before, or what was is no longer a member; defaults to the first. It may be a member a provider gives, the first so named."
    },
    "interrupt_exist_connections": {
     "type": "boolean",
     "description": "Ends the connections through the member selected before once another is selected, rather than leaving them on it."
    },
    "providers": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The outbound providers, by tag, whose outbounds join the group's own, in this order."
    },
    "filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions, as Mihomo's `filter`: of the providers' outbounds, only those whose names match one are members, those of the first first. The group's own outbounds are not filtered."
    },
    "exclude_filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions no member's name may match, the group's own outbounds' too."
    },
    "exclude_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The types no member may be of, the group's own outbounds too, in Mihomo's names for them, without case: `Shadowsocks`, `Vmess`, `Socks5`, `Direct`, ..."
    },
    "empty_fallback": {
     "type": "string",
     "description": "An outbound, not a group, that is the member while there is none else. Without it such a group has none, and its connections fail."
    },
    "disable_udp": {
     "description": "The group carries TCP alone, whatever member it picks (Mihomo's disable-udp)"
    },
    "type": {
     "const": "selector"
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowsocks]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bshadowsocks%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string",
     "description": "May be left out, with `server_port`, by an outbound with a `detour`: one over ShadowTLS, which dials its own server."
    },
    "server_port": {
     "type": "number"
    },
    "method": {
     "type": "string",
     "examples": [
      "none",
      "aes-128-gcm",
      "aes-192-gcm",
      "aes-256-gcm",
      "chacha20-ietf-poly1305",
      "xchacha20-ietf-poly1305",
      "2022-blake3-aes-128-gcm",
      "2022-blake3-aes-256-gcm",
      "2022-blake3-chacha20-poly1305",
      "aes-128-ctr",
      "aes-192-ctr",
      "aes-256-ctr",
      "aes-128-cfb",
      "aes-192-cfb",
      "aes-256-cfb",
      "rc4-md5",
      "chacha20-ietf",
      "xchacha20"
     ]
    },
    "password": {
     "type": "string",
     "description": "With a 2022 method, the base64 PSK, or `iPSK:uPSK` for a server with users."
    },
    "plugin": {
     "type": "string",
     "description": "Only `obfs-local` (simple-obfs) is supported."
    },
    "plugin_opts": {
     "type": "string",
     "description": "`obfs=http|tls;obfs-host=<host>;obfs-uri=<path>`, as simple-obfs takes them."
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ]
    },
    "udp_over_tcp": {
     "anyOf": [
      {
       "type": "boolean"
      },
      {
       "$ref": "#/$defs/outbounds%5Bshadowsocks%5D.udp_over_tcp"
      }
     ],
     "description": "UDP over its TCP, to `sp.v2.udp-over-tcp.arpa` (version 2, the default) or `sp.udp-over-tcp.arpa` (version 1), instead of its own UDP."
    },
    "multiplex": {
     "$ref": "#/$defs/outbounds%5Bshadowsocks%5D.multiplex"
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "prefix": {
     "type": "string",
     "description": "Bytes sent before the first payload, percent-encoded."
    },
    "type": {
     "const": "shadowsocks"
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowsocks].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[shadowsocks].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "protocol": {
     "type": "string",
     "examples": [
      "h2mux",
      "smux",
      "yamux"
     ],
     "description": "sing-box's multiplex, above the protocol: `h2mux`, the default as in sing-box, `smux` or `yamux`. Or `amux`, sail's own, below the protocol, which is to be removed."
    },
    "max_connections": {
     "type": "number"
    },
    "min_streams": {
     "type": "number"
    },
    "max_streams": {
     "type": "number"
    },
    "padding": {
     "type": "boolean"
    },
    "brutal": {
     "$ref": "#/$defs/outbounds%5Bshadowsocks%5D.multiplex.brutal",
     "description": "sing-mux only: TCP Brutal, negotiated on each new connection."
    },
    "max_accepts": {
     "type": "number",
     "description": "amux only."
    },
    "concurrency": {
     "type": "number",
     "description": "With `protocol: amux`: the streams a session carries at once"
    },
    "max_recv_bytes": {
     "type": "number",
     "description": "With `protocol: amux`: the bytes a session receives before it takes no more streams; 0, no limit"
    },
    "max_lifetime": {
     "type": "number",
     "description": "With `protocol: amux`: the seconds a session takes new streams for; 0, no limit"
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowsocks].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowsocks].udp_over_tcp": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "version": {
     "type": "number",
     "examples": [
      1,
      2
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowtls]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bshadowtls%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "version": {
     "type": "number",
     "examples": [
      1,
      2,
      3
     ],
     "description": "Must be 3: versions 1 and 2 are not supported. sing-box's default is 1."
    },
    "password": {
     "type": "string",
     "description": "Cannot be empty."
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Bshadowtls%5D.tls",
     "description": "Must be enabled: the handshake with the site the server imitates, `server_name` being the site's (the server's address when unset). A browser fingerprint, disable_sni and a client certificate apply as for TLS; REALITY and ECH do not."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "type": {
     "const": "shadowtls"
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowtls].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[shadowtls].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Bshadowtls%5D.tls.ech"
    },
    "utls": {
     "$ref": "#/$defs/outbounds%5Bshadowtls%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Bshadowtls%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowtls].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowtls].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[shadowtls].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[smart]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "outbounds": {
     "type": "array",
     "description": "Its members; none may be when its providers give others."
    },
    "providers": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The outbound providers, by tag, whose outbounds join the group's own, in this order."
    },
    "filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions, as Mihomo's `filter`: of the providers' outbounds, only those whose names match one are members, those of the first first. The group's own outbounds are not filtered."
    },
    "exclude_filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions no member's name may match, the group's own outbounds' too."
    },
    "exclude_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The types no member may be of, the group's own outbounds too, in Mihomo's names for them, without case: `Shadowsocks`, `Vmess`, `Socks5`, `Direct`, ..."
    },
    "empty_fallback": {
     "type": "string",
     "description": "An outbound, not a group, that is the member while there is none else. Without it such a group has none, and its connections fail."
    },
    "url": {
     "type": "string",
     "description": "What is requested through each member to probe it."
    },
    "interval": {
     "type": "string",
     "description": "How often members nothing told of lately are probed; 5 minutes."
    },
    "timeout": {
     "type": "string",
     "description": "How long a probe, or a connection attempt that has a member left to try, may take before its member counts as failed; 5 seconds."
    },
    "idle_timeout": {
     "type": "string",
     "description": "Probes pause once the group has not been used for this long; 30 minutes."
    },
    "unified_delay": {
     "type": "boolean",
     "description": "The latency of a second request on the connection the first opened, without the connect and handshakes, as Mihomo's `unified-delay`; a sail extension."
    },
    "tolerance": {
     "type": "number",
     "description": "Milliseconds: a member whose score is within this of the best may be picked."
    },
    "tolerance_ratio": {
     "type": "number",
     "description": "A member whose score is within this fraction of the best may be picked too, whichever of the two is the wider."
    },
    "policy_priority": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/outbounds%5Bsmart%5D.policy_priority%5B%5D"
     },
     "description": "Factors of the scores of the members whose names match a regular expression, the first that matches: below 1 prefers them, above 1 avoids them. 1 for the others."
    },
    "site_ttl": {
     "type": "string",
     "description": "How long a site is kept on its member after its last connection; an hour."
    },
    "site_capacity": {
     "type": "number",
     "description": "How many sites are kept at most; the least recently used goes first."
    },
    "prefer_asn": {
     "type": "boolean",
     "description": "Destinations known by address alone are sites by their autonomous system, but those of CDNs, rather than by their network. Needs an ASN database: `asn.mmdb` in the asset directory, or `asn_file`."
    },
    "asn_file": {
     "type": "string",
     "description": "The ASN database, for `prefer_asn`; relative to the asset directory."
    },
    "evaluate_before_use": {
     "type": "boolean",
     "description": "The first connection waits for the first probes, `timeout` at most, rather than going through a member not measured yet."
    },
    "interrupt_exist_connections": {
     "type": "boolean",
     "description": "Ends the connections through a member once it leaves the group."
    },
    "disable_udp": {
     "description": "The group carries TCP alone, whatever member it picks (Mihomo's disable-udp)"
    },
    "type": {
     "const": "smart"
    }
   },
   "additionalProperties": false
  },
  "outbounds[smart].policy_priority[]": {
   "type": "object",
   "properties": {
    "regex": {
     "type": "string",
     "description": "Matched against the member's name, as Mihomo's filters are: lookarounds included, backtracking bounded."
    },
    "factor": {
     "type": "number",
     "description": "Multiplies the member's score: above 0."
    }
   },
   "additionalProperties": false
  },
  "outbounds[socks]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bsocks%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string",
     "description": "May be left out, with `server_port`, by an outbound with a `detour`: one over ShadowTLS, which dials its own server."
    },
    "server_port": {
     "type": "number"
    },
    "version": {
     "type": "string",
     "examples": [
      "4",
      "4a",
      "5"
     ],
     "description": "`5`, the default, which is all sail speaks. sing-box also takes `4` and `4a` (option/simple.go:25), which are errors here."
    },
    "username": {
     "type": "string"
    },
    "password": {
     "type": "string"
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ]
    },
    "udp_over_tcp": {
     "anyOf": [
      {
       "type": "boolean"
      },
      {
       "$ref": "#/$defs/outbounds%5Bsocks%5D.udp_over_tcp"
      }
     ],
     "description": "UDP over its TCP, to `sp.v2.udp-over-tcp.arpa` (version 2, the default) or `sp.udp-over-tcp.arpa` (version 1), instead of UDP ASSOCIATE."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "type": {
     "const": "socks"
    }
   },
   "additionalProperties": false
  },
  "outbounds[socks].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[socks].udp_over_tcp": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "version": {
     "type": "number",
     "examples": [
      1,
      2
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Btrojan%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string",
     "description": "May be left out, with `server_port`, by an outbound with a `detour`: one over ShadowTLS, which dials its own server."
    },
    "server_port": {
     "type": "number"
    },
    "password": {
     "type": "string"
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ]
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Btrojan%5D.tls"
    },
    "multiplex": {
     "$ref": "#/$defs/outbounds%5Btrojan%5D.multiplex"
    },
    "transport": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "grpc",
        "http",
        "httpupgrade",
        "ws"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "grpc"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Btrojan%5D.transport%5Bgrpc%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "http"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Btrojan%5D.transport%5Bhttp%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "httpupgrade"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Btrojan%5D.transport%5Bhttpupgrade%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "ws"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Btrojan%5D.transport%5Bws%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "type": {
     "const": "trojan"
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[trojan].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "protocol": {
     "type": "string",
     "examples": [
      "h2mux",
      "smux",
      "yamux"
     ],
     "description": "sing-box's multiplex, above the protocol: `h2mux`, the default as in sing-box, `smux` or `yamux`. Or `amux`, sail's own, below the protocol, which is to be removed."
    },
    "max_connections": {
     "type": "number"
    },
    "min_streams": {
     "type": "number"
    },
    "max_streams": {
     "type": "number"
    },
    "padding": {
     "type": "boolean"
    },
    "brutal": {
     "$ref": "#/$defs/outbounds%5Btrojan%5D.multiplex.brutal",
     "description": "sing-mux only: TCP Brutal, negotiated on each new connection."
    },
    "max_accepts": {
     "type": "number",
     "description": "amux only."
    },
    "concurrency": {
     "type": "number",
     "description": "With `protocol: amux`: the streams a session carries at once"
    },
    "max_recv_bytes": {
     "type": "number",
     "description": "With `protocol: amux`: the bytes a session receives before it takes no more streams; 0, no limit"
    },
    "max_lifetime": {
     "type": "number",
     "description": "With `protocol: amux`: the seconds a session takes new streams for; 0, no limit"
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Btrojan%5D.tls.ech"
    },
    "utls": {
     "$ref": "#/$defs/outbounds%5Btrojan%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Btrojan%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].transport[grpc]": {
   "type": "object",
   "properties": {
    "service_name": {
     "type": "string"
    },
    "idle_timeout": {
     "type": "string",
     "description": "Unset, no keepalive pings. A client pings this often; a server after this long with nothing received, so give a server no shorter a time than its clients' interval."
    },
    "ping_timeout": {
     "type": "string"
    },
    "permit_without_stream": {
     "type": "boolean",
     "description": "Whether a connection carrying no calls is pinged too."
    },
    "type": {
     "const": "grpc"
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].transport[http]": {
   "type": "object",
   "properties": {
    "host": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "path": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "method": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "ping_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].transport[httpupgrade]": {
   "type": "object",
   "properties": {
    "host": {
     "type": "string",
     "description": "Unset, the server's address."
    },
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object"
    },
    "type": {
     "const": "httpupgrade"
    }
   },
   "additionalProperties": false
  },
  "outbounds[trojan].transport[ws]": {
   "type": "object",
   "properties": {
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object"
    },
    "max_early_data": {
     "type": "number",
     "description": "How many of the first bytes to carry in the upgrade request."
    },
    "early_data_header_name": {
     "type": "string",
     "description": "The header they go in; unset, they go in the path."
    },
    "type": {
     "const": "ws"
    }
   },
   "additionalProperties": false
  },
  "outbounds[tryall]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "outbounds": {
     "type": "array",
     "description": "A group trying its members at once"
    },
    "delay_base": {
     "type": "number",
     "description": "Milliseconds to wait before trying each next outbound."
    },
    "type": {
     "const": "tryall"
    }
   },
   "additionalProperties": false
  },
  "outbounds[tuic]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Btuic%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string"
    },
    "server_port": {
     "type": "number"
    },
    "uuid": {
     "type": "string"
    },
    "password": {
     "type": "string"
    },
    "congestion_control": {
     "type": "string",
     "enum": [
      "cubic",
      "new_reno",
      "bbr"
     ]
    },
    "udp_relay_mode": {
     "type": "string",
     "enum": [
      "native",
      "quic"
     ]
    },
    "udp_over_stream": {
     "type": "boolean",
     "description": "UDP over TCP (v2), as sing-box has it: each UDP session a `Connect` stream to `sp.v2.udp-over-tcp.arpa`, instead of TUIC's own relay."
    },
    "zero_rtt_handshake": {
     "type": "boolean"
    },
    "heartbeat": {
     "type": "string"
    },
    "network": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "tcp",
        "udp"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "tcp",
         "udp"
        ]
       }
      }
     ],
     "description": "`tcp` or `udp`; both when not set."
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Btuic%5D.tls"
    },
    "idle_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "keep_alive_period": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "stream_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "connection_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "max_concurrent_streams": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "initial_packet_size": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "disable_path_mtu_discovery": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: QUIC tuning: the same connection without it"
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "type": {
     "const": "tuic"
    }
   },
   "additionalProperties": false
  },
  "outbounds[tuic].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[tuic].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Btuic%5D.tls.ech"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: Not supported with TUIC"
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Btuic%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[tuic].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[tuic].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[tuic].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: Not supported with TUIC"
    }
   },
   "additionalProperties": false
  },
  "outbounds[urltest]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "outbounds": {
     "type": "array",
     "description": "Its members; none may be when its providers give others."
    },
    "url": {
     "type": "string",
     "description": "What is requested through each member; sing-box's default."
    },
    "interval": {
     "type": "string"
    },
    "tolerance": {
     "type": "number",
     "description": "Milliseconds."
    },
    "idle_timeout": {
     "type": "string",
     "description": "Tests pause once the group has not been used for this long; 30m, sing-box's. A Clash `url-test` group, lazy, has it equal to its `interval`, as Mihomo's."
    },
    "interrupt_exist_connections": {
     "type": "boolean",
     "description": "Ends the connections through the member left once the group switches."
    },
    "providers": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The outbound providers, by tag, whose outbounds join the group's own, in this order."
    },
    "filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions, as Mihomo's `filter`: of the providers' outbounds, only those whose names match one are members, those of the first first. The group's own outbounds are not filtered."
    },
    "exclude_filter": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Regular expressions no member's name may match, the group's own outbounds' too."
    },
    "exclude_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The types no member may be of, the group's own outbounds too, in Mihomo's names for them, without case: `Shadowsocks`, `Vmess`, `Socks5`, `Direct`, ..."
    },
    "empty_fallback": {
     "type": "string",
     "description": "An outbound, not a group, that is the member while there is none else. Without it such a group has none, and its connections fail."
    },
    "timeout": {
     "type": "string",
     "description": "How long a test may take before its member counts as failed; 5s. Also how close together `max_failed_times` failures must come; Mihomo's `timeout`."
    },
    "max_failed_times": {
     "type": "number",
     "description": "How many failed connections, within `timeout` of the first, have the members tested again; 5, as Mihomo's `max-failed-times`. One whose member's server cannot be reached has them tested at once."
    },
    "expected_status": {
     "type": "string",
     "description": "The HTTP statuses a test must be answered with to pass, as Mihomo's `expected-status`: codes and ranges, `200/204/401-429`; any when unset."
    },
    "lazy": {
     "type": "boolean",
     "description": "`false`: tests never pause, used or not, as Mihomo's `lazy: false`; `idle_timeout` is then a mistake."
    },
    "unified_delay": {
     "type": "boolean",
     "description": "The latency of a second request on the connection the first opened, without the connect and handshakes, as Mihomo's `unified-delay`; a sail extension."
    },
    "disable_udp": {
     "description": "The group carries TCP alone, whatever member it picks (Mihomo's disable-udp)"
    },
    "type": {
     "const": "urltest"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bvless%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string",
     "description": "May be left out, with `server_port`, by an outbound with a `detour`: one over ShadowTLS, which dials its own server."
    },
    "server_port": {
     "type": "number"
    },
    "uuid": {
     "type": "string"
    },
    "flow": {
     "type": "string",
     "description": "`\"\"` or `xtls-rprx-vision`."
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ]
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Bvless%5D.tls"
    },
    "multiplex": {
     "$ref": "#/$defs/outbounds%5Bvless%5D.multiplex"
    },
    "transport": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "grpc",
        "http",
        "httpupgrade",
        "ws"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "grpc"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvless%5D.transport%5Bgrpc%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "http"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvless%5D.transport%5Bhttp%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "httpupgrade"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvless%5D.transport%5Bhttpupgrade%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "ws"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvless%5D.transport%5Bws%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "packet_encoding": {
     "type": "string",
     "description": "How UDP travels: unset means `xudp`, as in sing-box; `\"\"` is VLESS's own UDP, one destination per connection."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "type": {
     "const": "vless"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[vless].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "protocol": {
     "type": "string",
     "examples": [
      "h2mux",
      "smux",
      "yamux"
     ],
     "description": "sing-box's multiplex, above the protocol: `h2mux`, the default as in sing-box, `smux` or `yamux`. Or `amux`, sail's own, below the protocol, which is to be removed."
    },
    "max_connections": {
     "type": "number"
    },
    "min_streams": {
     "type": "number"
    },
    "max_streams": {
     "type": "number"
    },
    "padding": {
     "type": "boolean"
    },
    "brutal": {
     "$ref": "#/$defs/outbounds%5Bvless%5D.multiplex.brutal",
     "description": "sing-mux only: TCP Brutal, negotiated on each new connection."
    },
    "max_accepts": {
     "type": "number",
     "description": "amux only."
    },
    "concurrency": {
     "type": "number",
     "description": "With `protocol: amux`: the streams a session carries at once"
    },
    "max_recv_bytes": {
     "type": "number",
     "description": "With `protocol: amux`: the bytes a session receives before it takes no more streams; 0, no limit"
    },
    "max_lifetime": {
     "type": "number",
     "description": "With `protocol: amux`: the seconds a session takes new streams for; 0, no limit"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Bvless%5D.tls.ech"
    },
    "utls": {
     "$ref": "#/$defs/outbounds%5Bvless%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Bvless%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].transport[grpc]": {
   "type": "object",
   "properties": {
    "service_name": {
     "type": "string"
    },
    "idle_timeout": {
     "type": "string",
     "description": "Unset, no keepalive pings. A client pings this often; a server after this long with nothing received, so give a server no shorter a time than its clients' interval."
    },
    "ping_timeout": {
     "type": "string"
    },
    "permit_without_stream": {
     "type": "boolean",
     "description": "Whether a connection carrying no calls is pinged too."
    },
    "type": {
     "const": "grpc"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].transport[http]": {
   "type": "object",
   "properties": {
    "host": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "path": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "method": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "ping_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].transport[httpupgrade]": {
   "type": "object",
   "properties": {
    "host": {
     "type": "string",
     "description": "Unset, the server's address."
    },
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object"
    },
    "type": {
     "const": "httpupgrade"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vless].transport[ws]": {
   "type": "object",
   "properties": {
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object"
    },
    "max_early_data": {
     "type": "number",
     "description": "How many of the first bytes to carry in the upgrade request."
    },
    "early_data_header_name": {
     "type": "string",
     "description": "The header they go in; unset, they go in the path."
    },
    "type": {
     "const": "ws"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess]": {
   "type": "object",
   "properties": {
    "tag": {
     "type": "string",
     "description": "Defaults to the type."
    },
    "detour": {
     "type": "string",
     "description": "The outbound to dial through, in place of a socket of its own."
    },
    "bind_interface": {
     "type": "string",
     "description": "The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well."
    },
    "inet4_bind_address": {
     "type": "string",
     "description": "The local address for IPv4 destinations, loopback ones aside: as `bind_interface`."
    },
    "inet6_bind_address": {
     "type": "string",
     "description": "The local address for IPv6 destinations, loopback ones aside: as `bind_interface`."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "description": "`IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address, so that the port is picked at connect: Linux only."
    },
    "protect_path": {
     "type": "string",
     "description": "A Unix socket each socket's descriptor is handed to, with `SCM_RIGHTS`, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "`SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "description": "`SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "description": "How long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "description": "TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it. Not implemented yet."
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "description": "No TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "description": "How long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "description": "Between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "description": "Whether UDP datagrams may be fragmented on the way; unset, as the place says, see `udp_fragment_default`."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/outbounds%5Bvmess%5D.domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names dialled."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "Which of the host's interfaces a connection goes out of, and how they race; `default` where only types are given. Only where the host lists its interfaces (`NetworkState::interfaces`)."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types of interface the strategy goes out of first."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "description": "The types it falls back to, with `fallback`."
    },
    "fallback_delay": {
     "type": "string",
     "description": "How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset."
    },
    "server": {
     "type": "string",
     "description": "May be left out, with `server_port`, by an outbound with a `detour`: one over ShadowTLS, which dials its own server."
    },
    "server_port": {
     "type": "number"
    },
    "uuid": {
     "type": "string"
    },
    "security": {
     "type": "string",
     "examples": [
      "auto",
      "none",
      "zero",
      "aes-128-cfb",
      "aes-128-gcm",
      "chacha20-poly1305"
     ],
     "description": "`auto`, `aes-128-gcm`, `chacha20-poly1305`, `none` or `zero`."
    },
    "alter_id": {
     "type": "number",
     "description": "Only 0: legacy VMess is not spoken."
    },
    "global_padding": {
     "type": "boolean",
     "description": "Random padding after each chunk, as v2ray pads."
    },
    "authenticated_length": {
     "not": {},
     "description": "sail refuses this field: VMess's authenticated length: sail would speak VMess otherwise"
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp"
     ]
    },
    "tls": {
     "$ref": "#/$defs/outbounds%5Bvmess%5D.tls"
    },
    "packet_encoding": {
     "type": "string",
     "examples": [
      "packetaddr",
      "xudp"
     ],
     "description": "`\"\"` (VMess's own UDP) or `xudp`."
    },
    "multiplex": {
     "$ref": "#/$defs/outbounds%5Bvmess%5D.multiplex"
    },
    "transport": {
     "type": "object",
     "properties": {
      "type": {
       "enum": [
        "grpc",
        "http",
        "httpupgrade",
        "ws"
       ]
      }
     },
     "allOf": [
      {
       "if": {
        "properties": {
         "type": {
          "const": "grpc"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvmess%5D.transport%5Bgrpc%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "http"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvmess%5D.transport%5Bhttp%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "httpupgrade"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvmess%5D.transport%5Bhttpupgrade%5D"
       }
      },
      {
       "if": {
        "properties": {
         "type": {
          "const": "ws"
         }
        },
        "required": [
         "type"
        ]
       },
       "then": {
        "$ref": "#/$defs/outbounds%5Bvmess%5D.transport%5Bws%5D"
       }
      }
     ],
     "required": [
      "type"
     ]
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "sing-box's deprecated field for the families names resolve to, which a resolver's own `strategy` goes before.",
     "deprecated": true
    },
    "skip_default_domain_resolver": {
     "type": "boolean",
     "description": "A sail extension: without a `domain_resolver` of its own, the names dialled resolve as the DNS rules say, not as `route.default_domain_resolver` does; as Mihomo's DIRECT resolves apart from the proxies' servers."
    },
    "tcp_concurrent": {
     "type": "boolean",
     "description": "A sail extension, Mihomo's `tcp-concurrent`: a name's addresses are all connected to at once and the first to connect is taken, rather than one family's one by one, the other's raced against them after `fallback_delay` (Happy Eyeballs). With `network_strategy`, each address is still raced over the interfaces, so as many sockets open at once as there are addresses times interfaces."
    },
    "type": {
     "const": "vmess"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "outbounds[vmess].multiplex": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "protocol": {
     "type": "string",
     "examples": [
      "h2mux",
      "smux",
      "yamux"
     ],
     "description": "sing-box's multiplex, above the protocol: `h2mux`, the default as in sing-box, `smux` or `yamux`. Or `amux`, sail's own, below the protocol, which is to be removed."
    },
    "max_connections": {
     "type": "number"
    },
    "min_streams": {
     "type": "number"
    },
    "max_streams": {
     "type": "number"
    },
    "padding": {
     "type": "boolean"
    },
    "brutal": {
     "$ref": "#/$defs/outbounds%5Bvmess%5D.multiplex.brutal",
     "description": "sing-mux only: TCP Brutal, negotiated on each new connection."
    },
    "max_accepts": {
     "type": "number",
     "description": "amux only."
    },
    "concurrency": {
     "type": "number",
     "description": "With `protocol: amux`: the streams a session carries at once"
    },
    "max_recv_bytes": {
     "type": "number",
     "description": "With `protocol: amux`: the bytes a session receives before it takes no more streams; 0, no limit"
    },
    "max_lifetime": {
     "type": "number",
     "description": "With `protocol: amux`: the seconds a session takes new streams for; 0, no limit"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].multiplex.brutal": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "up_mbps": {
     "type": "number"
    },
    "down_mbps": {
     "type": "number"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple",
      "windows"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack: sail has one"
    },
    "disable_sni": {
     "type": "boolean",
     "description": "Sends no SNI. The certificate is still verified against `server_name`, unless `insecure`."
    },
    "server_name": {
     "type": "string",
     "description": "Defaults to the server's address."
    },
    "insecure": {
     "type": "boolean"
    },
    "alpn": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "min_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The lowest TLS version to negotiate, `1.0` to `1.3`; unset, 1.2."
    },
    "max_version": {
     "type": "string",
     "examples": [
      "1.0",
      "1.1",
      "1.2",
      "1.3"
     ],
     "description": "The highest; unset, 1.3."
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS cipher suites and key exchanges: sail's TLS would negotiate others than asked"
    },
    "certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate to trust."
    },
    "certificate_path": {
     "type": "string",
     "description": "A PEM certificate to trust, by path."
    },
    "certificate_public_key_sha256": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       ]
      },
      {
       "type": "array"
      }
     ],
     "description": "The SHA-256 hashes, base64, of the public keys to take a server's certificate by, in place of the certificates trusted, the name and `insecure`."
    },
    "client_certificate": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An inline PEM certificate, its chain after it, presented when the server asks for one; with `client_key`."
    },
    "client_certificate_path": {
     "type": "string",
     "description": "`client_certificate`, by path."
    },
    "client_key": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The inline PEM key of the client certificate."
    },
    "client_key_path": {
     "type": "string",
     "description": "`client_key`, by path."
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "kernel_tx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "kernel_rx": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "handshake_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: The TLS stack, kernel TLS and the handshake's timeout: the same TLS without them"
    },
    "ech": {
     "$ref": "#/$defs/outbounds%5Bvmess%5D.tls.ech"
    },
    "utls": {
     "$ref": "#/$defs/outbounds%5Bvmess%5D.tls.utls",
     "description": "The browser the ClientHello imitates. Unset, it is Chrome's."
    },
    "reality": {
     "$ref": "#/$defs/outbounds%5Bvmess%5D.tls.reality"
    },
    "certificate_sha256": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array"
      }
     ],
     "description": "sing-box 1.15's, with Mihomo's `fingerprint` semantics beyond it: the SHA-256 hashes, hex or base64, of whole certificates (DER) to take a server by, in place of the certificates trusted and `insecure`. A hash of the server's own certificate takes it outright: no CA and no name are checked, so that exact certificate is trusted for any server name. A hash of a certificate sent after it, an intermediate or a root, is the only CA the server's certificate is verified by, with the server name. With `certificate_public_key_sha256`, either passing is enough."
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "config": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "An ECHConfigList, base64 or PEM. Looked up in DNS when not set."
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: An ECH configuration from a file, or looked up under another name: the server name would go in the clear"
    },
    "disable_dns_lookup": {
     "type": "boolean",
     "description": "Never look the ECHConfigList up in DNS: `config` is then required."
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "public_key": {
     "type": "string"
    },
    "short_id": {
     "type": "string"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "type": "boolean"
    },
    "fingerprint": {
     "type": "string",
     "examples": [
      "chrome_psk",
      "chrome_psk_shuffle",
      "chrome_padding_psk_shuffle",
      "chrome_pq",
      "chrome_pq_psk",
      "chrome",
      "firefox",
      "edge",
      "safari",
      "360",
      "qq",
      "ios",
      "android",
      "random",
      "randomized"
     ]
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].transport[grpc]": {
   "type": "object",
   "properties": {
    "service_name": {
     "type": "string"
    },
    "idle_timeout": {
     "type": "string",
     "description": "Unset, no keepalive pings. A client pings this often; a server after this long with nothing received, so give a server no shorter a time than its clients' interval."
    },
    "ping_timeout": {
     "type": "string"
    },
    "permit_without_stream": {
     "type": "boolean",
     "description": "Whether a connection carrying no calls is pinged too."
    },
    "type": {
     "const": "grpc"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].transport[http]": {
   "type": "object",
   "properties": {
    "host": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "path": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "method": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "headers": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "idle_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "ping_timeout": {
     "not": {},
     "description": "sail refuses this field: Type http (HTTP/2) is not supported, by design; grpc, ws and httpupgrade are"
    },
    "type": {
     "const": "http"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].transport[httpupgrade]": {
   "type": "object",
   "properties": {
    "host": {
     "type": "string",
     "description": "Unset, the server's address."
    },
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object"
    },
    "type": {
     "const": "httpupgrade"
    }
   },
   "additionalProperties": false
  },
  "outbounds[vmess].transport[ws]": {
   "type": "object",
   "properties": {
    "path": {
     "type": "string"
    },
    "headers": {
     "type": "object"
    },
    "max_early_data": {
     "type": "number",
     "description": "How many of the first bytes to carry in the upgrade request."
    },
    "early_data_header_name": {
     "type": "string",
     "description": "The header they go in; unset, they go in the path."
    },
    "type": {
     "const": "ws"
    }
   },
   "additionalProperties": false
  },
  "route": {
   "type": "object",
   "properties": {
    "rules": {
     "type": "array",
     "items": {
      "type": "object",
      "properties": {
       "type": {
        "enum": [
         "logical",
         "default"
        ],
        "description": "`default`, or `logical`."
       }
      },
      "allOf": [
       {
        "if": {
         "properties": {
          "type": {
           "const": "logical"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/route.rules%5Blogical%5D%2Bactions"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "enum": [
            "logical"
           ]
          }
         },
         "required": [
          "type"
         ]
        },
        "else": {
         "$ref": "#/$defs/route.rules%5B%5D%2Bactions"
        }
       }
      ]
     }
    },
    "rule_set": {
     "type": "array",
     "items": {
      "type": "object",
      "properties": {
       "type": {
        "enum": [
         "inline",
         "local",
         "remote"
        ]
       }
      },
      "allOf": [
       {
        "if": {
         "properties": {
          "type": {
           "const": "inline"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/route.rule_set%5Binline%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "local"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/route.rule_set%5Blocal%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "const": "remote"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/route.rule_set%5Bremote%5D"
        }
       }
      ],
      "required": [
       "type"
      ]
     },
     "description": "The rule-sets rules name, by tag."
    },
    "final": {
     "type": "string",
     "description": "The outbound for connections no rule matches; defaults to the first outbound."
    },
    "find_process": {
     "type": "boolean",
     "description": "Looks up who opened every connection (the program, the package, the user), for the connections list, though no rule asks; without it, only when a rule has conditions on it, as in sing-box."
    },
    "find_neighbor": {
     "type": "boolean",
     "description": "Looks up the LAN device of each connection's source even without a rule on it, for the logs (sing-box's, since 1.14)."
    },
    "dhcp_lease_files": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The DHCP lease files the LAN devices' names are read from; the usual ones of dnsmasq, odhcpd, ISC dhcpd and Kea when none."
    },
    "auto_detect_interface": {
     "type": "boolean",
     "description": "Sends outbounds that name no interface of their own through the system's default interface, found at start. Needed when a TUN inbound routes everything, or outbound traffic would loop back into it."
    },
    "override_android_vpn": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Android's VPN is the host's to handle"
    },
    "default_interface": {
     "type": "string",
     "description": "The interface outbounds that name none of their own send through."
    },
    "default_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "description": "The routing mark (`SO_MARK`, Linux) of outbounds that set none."
    },
    "default_domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/route.default_domain_resolver"
      }
     ],
     "description": "The DNS server that resolves the names outbounds dial, for those that name no `domain_resolver` of their own. Unset, the DNS rules decide."
    },
    "default_network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "The `network_strategy`, `network_type`, `fallback_network_type` and `fallback_delay` of what sets none of the first three, or no delay; the strategy needs `auto_detect_interface`."
    },
    "default_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ]
    },
    "default_fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ]
    },
    "default_fallback_delay": {
     "type": "string"
    },
    "default_http_client": {
     "type": "string",
     "description": "The HTTP client of what names none, by tag; the first of `http_clients` when unset, or with none, the default outbound."
    },
    "geoip": {
     "type": "object",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: sing-box removed it in 1.12, and ignores it"
    },
    "geosite": {
     "type": "object",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: sing-box removed it in 1.12, and ignores it"
    },
    "block_quic": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, Surge's `block-quic`: the outbounds QUIC is refused to, by tag. A UDP connection sniffing recognized as QUIC that the rules send to one is rejected as a reject rule would, so that the app goes on over TCP. Sniffing is the rules' to ask for."
    }
   },
   "additionalProperties": false
  },
  "route.default_domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "route.rule_set[inline]": {
   "type": "object",
   "properties": {
    "tag": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "One tag, or several, each put in place of `{tag}` in the path or URL."
    },
    "rules": {
     "type": "array",
     "items": {
      "type": "object",
      "properties": {
       "type": {
        "enum": [
         "logical",
         "default"
        ],
        "description": "`default`, or `logical`."
       }
      },
      "allOf": [
       {
        "if": {
         "properties": {
          "type": {
           "const": "logical"
          }
         },
         "required": [
          "type"
         ]
        },
        "then": {
         "$ref": "#/$defs/route.rule_set%5Binline%5D.rules%5Blogical%5D"
        }
       },
       {
        "if": {
         "properties": {
          "type": {
           "enum": [
            "logical"
           ]
          }
         },
         "required": [
          "type"
         ]
        },
        "else": {
         "$ref": "#/$defs/route.rule_set%5Binline%5D.rules%5B%5D"
        }
       }
      ]
     },
     "description": "`inline`: the rules."
    },
    "type": {
     "const": "inline"
    }
   },
   "additionalProperties": false,
   "required": [
    "tag"
   ]
  },
  "route.rule_set[inline].rules[]": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string",
     "examples": [
      "default",
      "logical"
     ],
     "description": "`default`, or `logical`."
    },
    "query_type": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      {
       "type": "array",
       "items": {
        "anyOf": [
         {
          "type": "number"
         },
         {
          "type": "string"
         }
        ]
       }
      }
     ]
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp",
      "icmp"
     ]
    },
    "domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_suffix": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_keyword": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "source_port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "As a routing rule's: the app the host says opened the connection, an error without a host that tells."
    },
    "package_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ],
     "description": "Conditions on the network the host is on, as a routing rule's: `wifi|cellular|ethernet|other`."
    },
    "network_is_expensive": {
     "type": "boolean"
    },
    "network_is_constrained": {
     "type": "boolean"
    },
    "wifi_ssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "wifi_bssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "network_interface_address": {
     "not": {},
     "description": "sail refuses this field: sail does not match it yet"
    },
    "default_interface_address": {
     "not": {},
     "description": "sail refuses this field: sail does not match it yet"
    },
    "invert": {
     "type": "boolean"
    },
    "ip_asn": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ],
     "description": "A sail extension, as a routing rule's: autonomous systems, of `asn.mmdb` in the asset directory."
    },
    "http_user_agent": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Sail extensions, as a routing rule's: of a plain HTTP request."
    },
    "process_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as Mihomo's `PROCESS-NAME-REGEX`: regular expressions the program's name, its path's last part, matches."
    },
    "wifi_ssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Sail extensions, as a routing rule's: the Wi-Fi name and access point by pattern, the gateway, the cellular carrier."
    },
    "no_resolve": {
     "type": "boolean",
     "description": "A sail extension, as a routing rule's, and Surge's and Clash's `no-resolve` on a line of a set: the rule's `ip_cidr` and `ip_asn`, and those of the rules within, match only addresses already known, and never have an `on_demand` resolve resolve the domain for them. Only for a rule with such conditions."
    }
   },
   "additionalProperties": false
  },
  "route.rule_set[inline].rules[][conditions]": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string",
     "examples": [
      "default",
      "logical"
     ],
     "description": "`default`, or `logical`."
    },
    "query_type": {
     "anyOf": [
      {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      {
       "type": "array",
       "items": {
        "anyOf": [
         {
          "type": "number"
         },
         {
          "type": "string"
         }
        ]
       }
      }
     ]
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp",
      "icmp"
     ]
    },
    "domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_suffix": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_keyword": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "source_port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "As a routing rule's: the app the host says opened the connection, an error without a host that tells."
    },
    "package_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ],
     "description": "Conditions on the network the host is on, as a routing rule's: `wifi|cellular|ethernet|other`."
    },
    "network_is_expensive": {
     "type": "boolean"
    },
    "network_is_constrained": {
     "type": "boolean"
    },
    "wifi_ssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "wifi_bssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "network_interface_address": {
     "not": {},
     "description": "sail refuses this field: sail does not match it yet"
    },
    "default_interface_address": {
     "not": {},
     "description": "sail refuses this field: sail does not match it yet"
    },
    "invert": {
     "type": "boolean"
    },
    "ip_asn": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ],
     "description": "A sail extension, as a routing rule's: autonomous systems, of `asn.mmdb` in the asset directory."
    },
    "http_user_agent": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Sail extensions, as a routing rule's: of a plain HTTP request."
    },
    "process_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as Mihomo's `PROCESS-NAME-REGEX`: regular expressions the program's name, its path's last part, matches."
    },
    "wifi_ssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Sail extensions, as a routing rule's: the Wi-Fi name and access point by pattern, the gateway, the cellular carrier."
    },
    "no_resolve": {
     "type": "boolean",
     "description": "A sail extension, as a routing rule's, and Surge's and Clash's `no-resolve` on a line of a set: the rule's `ip_cidr` and `ip_asn`, and those of the rules within, match only addresses already known, and never have an `on_demand` resolve resolve the domain for them. Only for a rule with such conditions."
    }
   },
   "additionalProperties": false
  },
  "route.rule_set[inline].rules[logical]": {
   "type": "object",
   "properties": {
    "mode": {
     "type": "string",
     "examples": [
      "and",
      "or"
     ],
     "description": "`logical`: `and` or `or`."
    },
    "rules": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/route.rule_set%5Binline%5D.rules%5Bnested%5D"
     },
     "description": "`logical`: the rules combined."
    },
    "invert": {
     "type": "boolean"
    },
    "type": {
     "const": "logical"
    }
   },
   "additionalProperties": false,
   "required": [
    "mode",
    "rules"
   ]
  },
  "route.rule_set[inline].rules[logical][nested]": {
   "type": "object",
   "properties": {
    "mode": {
     "type": "string",
     "examples": [
      "and",
      "or"
     ],
     "description": "`logical`: `and` or `or`."
    },
    "rules": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/route.rule_set%5Binline%5D.rules%5Bnested%5D"
     },
     "description": "`logical`: the rules combined."
    },
    "invert": {
     "type": "boolean"
    },
    "type": {
     "const": "logical"
    }
   },
   "additionalProperties": false,
   "required": [
    "mode",
    "rules"
   ]
  },
  "route.rule_set[inline].rules[nested]": {
   "type": "object",
   "properties": {
    "type": {
     "enum": [
      "default",
      "logical"
     ]
    }
   },
   "allOf": [
    {
     "if": {
      "properties": {
       "type": {
        "const": "logical"
       }
      },
      "required": [
       "type"
      ]
     },
     "then": {
      "$ref": "#/$defs/route.rule_set%5Binline%5D.rules%5Blogical%5D%5Bnested%5D"
     },
     "else": {
      "$ref": "#/$defs/route.rule_set%5Binline%5D.rules%5B%5D%5Bconditions%5D"
     }
    }
   ]
  },
  "route.rule_set[local]": {
   "type": "object",
   "properties": {
    "tag": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "One tag, or several, each put in place of `{tag}` in the path or URL."
    },
    "format": {
     "type": "string",
     "enum": [
      "source",
      "binary",
      "mrs",
      "clash-yaml",
      "clash-text",
      "surge-text"
     ],
     "description": "`source` (JSON) or `binary` (`.srs`); from the extension of the path or URL when unset. A sail extension, for Clash's rule-providers: `mrs` (Mihomo's binary), `clash-yaml` or `clash-text`, which take a `behavior`."
    },
    "path": {
     "type": "string",
     "description": "`local`: the file."
    },
    "type": {
     "const": "local"
    }
   },
   "additionalProperties": false,
   "required": [
    "tag"
   ]
  },
  "route.rule_set[remote]": {
   "type": "object",
   "properties": {
    "tag": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "One tag, or several, each put in place of `{tag}` in the path or URL."
    },
    "format": {
     "type": "string",
     "enum": [
      "source",
      "binary",
      "mrs",
      "clash-yaml",
      "clash-text",
      "surge-text"
     ],
     "description": "`source` (JSON) or `binary` (`.srs`); from the extension of the path or URL when unset. A sail extension, for Clash's rule-providers: `mrs` (Mihomo's binary), `clash-yaml` or `clash-text`, which take a `behavior`."
    },
    "url": {
     "type": "string",
     "description": "`remote`: where it is downloaded from."
    },
    "initial_path": {
     "type": "string",
     "description": "`remote`: a file to start from before the first download."
    },
    "http_client": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/route.rule_set%5Bremote%5D.http_client"
      }
     ],
     "description": "`remote`: the HTTP client it is downloaded with, by tag or in place. With neither this nor `download_detour`, the default one of `http_clients` (`route.default_http_client`, or else the first), or else the default outbound."
    },
    "update_interval": {
     "type": "string",
     "description": "`remote`: how often it is downloaded again; 1d when unset."
    },
    "download_detour": {
     "type": "string",
     "description": "`remote`: the outbound it is downloaded through; deprecated in sing-box for `http_client`.",
     "deprecated": true
    },
    "behavior": {
     "type": "string",
     "enum": [
      "domain",
      "ipcidr",
      "classical"
     ],
     "description": "A sail extension, for the Clash formats: what each line is, `domain`, `ipcidr` or `classical` (a Clash rule without its target)."
    },
    "size_limit": {
     "type": "number",
     "description": "`remote`, a sail extension (Mihomo's `size-limit`): the most a download of it may be, in bytes; past it the download fails and the copy in use is kept. Unset, the download client's own cap."
    },
    "type": {
     "const": "remote"
    }
   },
   "additionalProperties": false,
   "required": [
    "tag"
   ]
  },
  "route.rule_set[remote].http_client": {
   "type": "object",
   "properties": {
    "engine": {
     "type": "string",
     "examples": [
      "go",
      "apple"
     ]
    },
    "version": {
     "type": "number",
     "examples": [
      0,
      1,
      2,
      3
     ]
    },
    "disable_version_fallback": {
     "type": "boolean"
    },
    "headers": {
     "type": "object"
    },
    "tls": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "detour": {
     "type": "string"
    },
    "bind_interface": {
     "type": "string"
    },
    "inet4_bind_address": {
     "type": "string"
    },
    "inet6_bind_address": {
     "type": "string"
    },
    "bind_address_no_port": {
     "type": "boolean"
    },
    "protect_path": {
     "type": "string"
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ]
    },
    "reuse_addr": {
     "type": "boolean"
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string"
    },
    "tcp_fast_open": {
     "type": "boolean"
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean"
    },
    "tcp_keep_alive": {
     "type": "string"
    },
    "tcp_keep_alive_interval": {
     "type": "string"
    },
    "udp_fragment": {
     "type": "boolean"
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/route.rule_set%5Bremote%5D.http_client.domain_resolver"
      }
     ]
    },
    "network_strategy": {
     "type": "string",
     "examples": [
      "default",
      "fallback",
      "hybrid"
     ]
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ]
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ]
    },
    "fallback_delay": {
     "type": "string"
    },
    "idle_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "keep_alive_period": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "stream_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "connection_receive_window": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "max_concurrent_streams": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "initial_packet_size": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "disable_path_mtu_discovery": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download"
    },
    "domain_strategy": {
     "type": "string",
     "deprecated": true
    }
   },
   "additionalProperties": false
  },
  "route.rule_set[remote].http_client.domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string"
    },
    "timeout": {
     "type": "string"
    },
    "strategy": {
     "type": "string",
     "examples": [
      "as_is",
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ]
    },
    "disable_cache": {
     "type": "boolean"
    },
    "disable_optimistic_cache": {
     "type": "boolean"
    },
    "rewrite_ttl": {
     "type": "number"
    },
    "client_subnet": {
     "type": "string"
    }
   },
   "additionalProperties": false,
   "required": [
    "server"
   ]
  },
  "route.rule_set[remote].http_client.tls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "engine": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "disable_sni": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "server_name": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "insecure": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "alpn": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "min_version": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "max_version": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "cipher_suites": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "curve_preferences": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "certificate": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "certificate_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "certificate_public_key_sha256": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_certificate": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_certificate_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_key": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "client_key_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "fragment": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "fragment_fallback_delay": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "record_fragment": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "spoof": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "spoof_method": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "kernel_tx": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "kernel_rx": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "handshake_timeout": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "ech": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "utls": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "reality": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "route.rule_set[remote].http_client.tls.ech": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "config": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "config_path": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "query_server_name": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "route.rule_set[remote].http_client.tls.reality": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "public_key": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "short_id": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "route.rule_set[remote].http_client.tls.utls": {
   "type": "object",
   "properties": {
    "enabled": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    },
    "fingerprint": {
     "not": {},
     "description": "sail refuses this field: TLS options of an HTTP client's own: its downloads would be checked otherwise"
    }
   },
   "additionalProperties": false
  },
  "route.rules[][conditions]": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string",
     "enum": [
      "default",
      "logical"
     ],
     "description": "`default`, or `logical`."
    },
    "inbound": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of the inbounds a connection came in through."
    },
    "ip_version": {
     "type": "number",
     "examples": [
      4,
      6
     ],
     "description": "4 or 6: the family of the destination address."
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp",
      "icmp"
     ],
     "description": "`tcp`, `udp`."
    },
    "auth_user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Names of the users an inbound authenticated."
    },
    "protocol": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tls",
      "http",
      "quic",
      "dns",
      "stun",
      "bittorrent",
      "dtls",
      "ssh",
      "rdp",
      "ntp"
     ],
     "description": "The protocols a `sniff` rule found, by sing-box's names: `tls`, `http`, `quic`, `dns`, `stun`, `bittorrent`, `dtls`."
    },
    "client": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_suffix": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_keyword": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_is_private": {
     "type": "boolean",
     "description": "The source address is not a public one."
    },
    "ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "ip_is_private": {
     "type": "boolean",
     "description": "The destination address, or one the domain resolved to, is not a public one."
    },
    "source_port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "source_port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Inclusive port ranges, as `port_range` writes them."
    },
    "port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Inclusive port ranges, as sing-box writes them: `1000:2000`, `:1024`, `8000:`."
    },
    "process_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The name of the program a connection comes from, its path's last part."
    },
    "process_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Android packages: the app the host says opened the connection (`find_connection_owner`); an error without a host that tells."
    },
    "package_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The user a connection's app runs as, by name and by id, as the host tells it; an error without a host that tells."
    },
    "user_id": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "clash_mode": {
     "type": "string",
     "description": "The mode of Clash's API: matches while it is that, whatever the case; never without an API."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ],
     "description": "The kind of network: `wifi`, `cellular`, `ethernet`, `other`."
    },
    "network_is_expensive": {
     "type": "boolean",
     "description": "The network is metered, as the system says."
    },
    "network_is_constrained": {
     "type": "boolean",
     "description": "The network is in a low data mode, as the system says."
    },
    "wifi_ssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The name of the Wi-Fi network the host is on, whole and with case. This and the other conditions on the network match the network as the host tells it or sail detects it at the time; one on something not known of it does not match."
    },
    "wifi_bssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The address of the Wi-Fi access point, `aa:bb:cc:dd:ee:ff`, in any case, with `:` or `-`, or as 12 hex digits."
    },
    "interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "network_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "default_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "source_mac_address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "MAC addresses of the LAN device the connection comes from, as the neighbor table and DHCP leases know it (sing-box's, since 1.14)."
    },
    "source_hostname": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Host names of the LAN device the connection comes from, as its DHCP lease has it."
    },
    "preferred_by": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "rule_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of rule-sets, any of whose rules matching matches."
    },
    "rule_set_ip_cidr_match_source": {
     "type": "boolean",
     "description": "The rule-sets' `ip_cidr` match the source address, not the destination."
    },
    "invert": {
     "type": "boolean"
    },
    "geoip": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Country codes, looked up in `geo.mmdb` in the asset directory; a sail extension, as `geosite` is."
    },
    "geosite": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Site groups, looked up in `site.dat` in the asset directory. A sail extension: sing-box has dropped its GeoIP and GeoSite databases."
    },
    "external": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension: `mmdb:<file>:<code>` or `site:<file>:<code>`, for data files other than the default ones."
    },
    "http_user_agent": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `USER-AGENT`: patterns the User-Agent of a plain HTTP request a `sniff` rule read matches, whole and with case, `*` any run of characters and `?` any one."
    },
    "url_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `URL-REGEX`: regular expressions found in the URL of a plain HTTP request a `sniff` rule read, `http://host/path?query`."
    },
    "ip_asn": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ],
     "description": "A sail extension, for Surge's `IP-ASN`: the autonomous systems the destination address, or one the domain resolved to, belongs to, as `asn.mmdb` in the asset directory (GeoLite2-ASN's format, or ipinfo's) has them."
    },
    "process_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as Mihomo's `PROCESS-NAME-REGEX`: regular expressions the program's name, its path's last part, matches."
    },
    "wifi_ssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `SSID:`: regular expressions found in the Wi-Fi network's name, with case."
    },
    "wifi_bssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `BSSID:`: regular expressions found in the access point's address as `aa:bb:cc:dd:ee:ff`, whatever the case."
    },
    "network_gateway": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `ROUTER:`: the address of the default gateway."
    },
    "network_mcc_mnc": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `MCCMNC:` and `CELLULAR-CARRIER`: the cellular carrier, its MCC and MNC as 5 or 6 digits; only off Wi-Fi."
    },
    "no_resolve": {
     "type": "boolean",
     "description": "A sail extension, Surge's and Clash's `no-resolve`: the rule's conditions on the destination's addresses (`ip_cidr`, `ip_is_private`, `ip_asn`, `geoip`, those of its rule-sets and of the rules within) match only addresses already known, and never have an `on_demand` resolve resolve the domain for them. Only for a rule with such conditions."
    }
   },
   "additionalProperties": false
  },
  "route.rules[]+actions": {
   "type": "object",
   "properties": {
    "type": {
     "type": "string",
     "enum": [
      "default",
      "logical"
     ],
     "description": "`default`, or `logical`."
    },
    "inbound": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of the inbounds a connection came in through."
    },
    "ip_version": {
     "type": "number",
     "examples": [
      4,
      6
     ],
     "description": "4 or 6: the family of the destination address."
    },
    "network": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tcp",
      "udp",
      "icmp"
     ],
     "description": "`tcp`, `udp`."
    },
    "auth_user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Names of the users an inbound authenticated."
    },
    "protocol": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "tls",
      "http",
      "quic",
      "dns",
      "stun",
      "bittorrent",
      "dtls",
      "ssh",
      "rdp",
      "ntp"
     ],
     "description": "The protocols a `sniff` rule found, by sing-box's names: `tls`, `http`, `quic`, `dns`, `stun`, `bittorrent`, `dtls`."
    },
    "client": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "domain": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_suffix": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_keyword": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "domain_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "source_ip_is_private": {
     "type": "boolean",
     "description": "The source address is not a public one."
    },
    "ip_cidr": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "ip_is_private": {
     "type": "boolean",
     "description": "The destination address, or one the domain resolved to, is not a public one."
    },
    "source_port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "source_port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Inclusive port ranges, as `port_range` writes them."
    },
    "port": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "port_range": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Inclusive port ranges, as sing-box writes them: `1000:2000`, `:1024`, `8000:`."
    },
    "process_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The name of the program a connection comes from, its path's last part."
    },
    "process_path": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "process_path_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "package_name": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Android packages: the app the host says opened the connection (`find_connection_owner`); an error without a host that tells."
    },
    "package_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ]
    },
    "user": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The user a connection's app runs as, by name and by id, as the host tells it; an error without a host that tells."
    },
    "user_id": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ]
    },
    "clash_mode": {
     "type": "string",
     "description": "The mode of Clash's API: matches while it is that, whatever the case; never without an API."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ],
     "description": "The kind of network: `wifi`, `cellular`, `ethernet`, `other`."
    },
    "network_is_expensive": {
     "type": "boolean",
     "description": "The network is metered, as the system says."
    },
    "network_is_constrained": {
     "type": "boolean",
     "description": "The network is in a low data mode, as the system says."
    },
    "wifi_ssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The name of the Wi-Fi network the host is on, whole and with case. This and the other conditions on the network match the network as the host tells it or sail detects it at the time; one on something not known of it does not match."
    },
    "wifi_bssid": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "The address of the Wi-Fi access point, `aa:bb:cc:dd:ee:ff`, in any case, with `:` or `-`, or as 12 hex digits."
    },
    "interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "network_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "default_interface_address": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "source_mac_address": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "MAC addresses of the LAN device the connection comes from, as the neighbor table and DHCP leases know it (sing-box's, since 1.14)."
    },
    "source_hostname": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Host names of the LAN device the connection comes from, as its DHCP lease has it."
    },
    "preferred_by": {
     "not": {},
     "description": "sail refuses this field: A condition sail does not match: the rule would match otherwise"
    },
    "rule_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Tags of rule-sets, any of whose rules matching matches."
    },
    "rule_set_ip_cidr_match_source": {
     "type": "boolean",
     "description": "The rule-sets' `ip_cidr` match the source address, not the destination."
    },
    "invert": {
     "type": "boolean"
    },
    "action": {
     "type": "string",
     "enum": [
      "route",
      "route-options",
      "reject",
      "hijack-dns",
      "sniff",
      "resolve",
      "bypass",
      "direct"
     ],
     "description": "`route` when unset."
    },
    "geoip": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Country codes, looked up in `geo.mmdb` in the asset directory; a sail extension, as `geosite` is."
    },
    "geosite": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "Site groups, looked up in `site.dat` in the asset directory. A sail extension: sing-box has dropped its GeoIP and GeoSite databases."
    },
    "external": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension: `mmdb:<file>:<code>` or `site:<file>:<code>`, for data files other than the default ones."
    },
    "http_user_agent": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `USER-AGENT`: patterns the User-Agent of a plain HTTP request a `sniff` rule read matches, whole and with case, `*` any run of characters and `?` any one."
    },
    "url_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `URL-REGEX`: regular expressions found in the URL of a plain HTTP request a `sniff` rule read, `http://host/path?query`."
    },
    "ip_asn": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "array",
       "items": {
        "type": "number"
       }
      }
     ],
     "description": "A sail extension, for Surge's `IP-ASN`: the autonomous systems the destination address, or one the domain resolved to, belongs to, as `asn.mmdb` in the asset directory (GeoLite2-ASN's format, or ipinfo's) has them."
    },
    "process_name_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, as Mihomo's `PROCESS-NAME-REGEX`: regular expressions the program's name, its path's last part, matches."
    },
    "wifi_ssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `SSID:`: regular expressions found in the Wi-Fi network's name, with case."
    },
    "wifi_bssid_regex": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `BSSID:`: regular expressions found in the access point's address as `aa:bb:cc:dd:ee:ff`, whatever the case."
    },
    "network_gateway": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `ROUTER:`: the address of the default gateway."
    },
    "network_mcc_mnc": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "A sail extension, for Surge's `MCCMNC:` and `CELLULAR-CARRIER`: the cellular carrier, its MCC and MNC as 5 or 6 digits; only off Wi-Fi."
    },
    "no_resolve": {
     "type": "boolean",
     "description": "A sail extension, Surge's and Clash's `no-resolve`: the rule's conditions on the destination's addresses (`ip_cidr`, `ip_is_private`, `ip_asn`, `geoip`, those of its rule-sets and of the rules within) match only addresses already known, and never have an `on_demand` resolve resolve the domain for them. Only for a rule with such conditions."
    },
    "outbound": {
     "type": "string",
     "description": "`route`: where a matching connection goes."
    },
    "override_address": {
     "type": "string",
     "description": "`route`, `route-options`: connects to this address, an IP or a domain, instead of the one asked for, on the same port."
    },
    "override_port": {
     "type": "number",
     "description": "`route`, `route-options`: connects to this port instead."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "`route`, `route-options`: how a direct outbound the connection goes out of chooses among the host's interfaces, instead of as its own says; not where it binds its sockets itself. A later rule's goes before. As in sing-box, only where the destination is an address (for UDP, a connected one) or a `resolve` rule resolved it; other outbounds, a group whose pick is a direct one among them, take no notice of it. `direct`: checked only."
    },
    "fallback_delay": {
     "type": "number",
     "description": "`route`, `route-options`: how long a direct outbound the connection goes out of tries one family's addresses, and its first interfaces, before the others race them, instead of its own `fallback_delay`, where `network_strategy` would apply. A later rule's goes before. A duration string, as sing-box's documentation writes it, or a number of nanoseconds, as sing-box 1.14.1 reads it here. `direct`: checked only."
    },
    "udp_disable_domain_unmapping": {
     "type": "boolean",
     "description": "`route`, `route-options`: answers to UDP sent to a domain come back from the address it resolved to, not from the domain."
    },
    "udp_connect": {
     "type": "boolean",
     "description": "`route`, `route-options`: a direct outbound sends UDP from a connected socket."
    },
    "udp_timeout": {
     "type": "string",
     "description": "`route`, `route-options`: how long a UDP session lasts idle, instead of its inbound's `udp_timeout`."
    },
    "tls_fragment": {
     "type": "boolean",
     "description": "`route`, `route-options`: sends the TLS ClientHello in pieces, cut in the server name, each in a TCP segment of its own."
    },
    "tls_fragment_fallback_delay": {
     "type": "string",
     "description": "`route`, `route-options`: how long to wait between the pieces; 500ms when unset."
    },
    "tls_record_fragment": {
     "type": "boolean",
     "description": "`route`, `route-options`: sends the TLS ClientHello as several TLS records, cut in the server name."
    },
    "tls_spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "tls_spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "bind_interface": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the interface to send through, by name."
    },
    "inet4_bind_address": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the local address for IPv4 destinations."
    },
    "inet6_bind_address": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the local address for IPv6 destinations."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: `IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address: Linux only."
    },
    "protect_path": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the Unix socket each socket's descriptor is handed to, to be protected: Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: `SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: `SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: how long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: TCP Fast Open."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: no TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: how long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: whether UDP datagrams may be fragmented on the way; not when unset, as sing-box's direct action has it."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/route.rules%5Baction%3Ddirect%5D.domain_resolver"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the DNS server that resolves the names it dials."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the types of interface its `fallback` strategy falls back to. Its `network_type` is not one: a rule's `network_type` is its condition, as in sing-box."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: sing-box's deprecated field for the families names resolve to."
    },
    "method": {
     "type": "string",
     "enum": [
      "default",
      "drop",
      "reply"
     ],
     "description": "`reject`: how."
    },
    "no_drop": {
     "type": "boolean",
     "description": "`reject`: never drops, however many connections the rule rejects."
    },
    "server": {
     "type": "string",
     "description": "`resolve`: the DNS server to ask, rather than the one the DNS rules pick."
    },
    "timeout": {
     "type": "string",
     "description": "`sniff`: how long to wait for the first bytes; 300ms when unset. `resolve`: how long to wait for the answer; `dns.timeout` when unset."
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "`resolve`: the address families, instead of `dns.strategy`."
    },
    "disable_cache": {
     "type": "boolean",
     "description": "`resolve`: the answers neither come from the DNS cache nor go into it."
    },
    "disable_optimistic_cache": {
     "type": "boolean",
     "description": "`resolve`: an expired answer is not given while it is asked for again, though `dns.optimistic` is enabled."
    },
    "rewrite_ttl": {
     "type": "number",
     "description": "`resolve`: the TTL the answers' records carry, in seconds."
    },
    "client_subnet": {
     "type": "string",
     "description": "`resolve`: the EDNS Client Subnet the queries carry, instead of `dns.client_subnet`."
    },
    "ignore_failure": {
     "type": "boolean",
     "description": "`resolve`, a sail extension: a domain that does not resolve, or not in time, has no addresses, and matching goes on, as Mihomo's IP rules have it; rather than the connection failing, as in sing-box."
    },
    "on_demand": {
     "type": "boolean",
     "description": "`resolve`, `sniff`, a sail extension: the rule does not act where it stands but arms its action, with its options, and matching goes on. The action is taken the first time a later rule needs what it learns, just before that rule is matched: a resolve for a rule with conditions on the destination's addresses, while the destination is a domain; a sniff for one on the protocol, the plain HTTP request, or a domain while the destination is an address. A connection no later rule needs it for is never resolved or sniffed, as Surge and Mihomo have it. A later rule arming the same action replaces its options."
    },
    "override_destination": {
     "anyOf": [
      {
       "type": "boolean"
      },
      {
       "type": "string"
      }
     ],
     "description": "`route`, `route-options`, `sniff`, a sail extension: a connection to an address is dialled by the name known for it, the sniffed domain or else the one `dns.reverse_mapping` keeps, where its last hop dials a proxy's server (`true` or `\"proxy\"`), or a direct dial too (`\"proxy_and_direct\"`). The rules still match the address. On a sniff rule, `\"at_sniff\"` instead makes the sniffed domain the destination there, for the rules after, as Mihomo's sniffer does."
    },
    "sniffer": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "tls",
        "http",
        "quic",
        "dns",
        "stun",
        "bittorrent",
        "dtls"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "tls",
         "http",
         "quic",
         "dns",
         "stun",
         "bittorrent",
         "dtls"
        ]
       }
      }
     ],
     "description": "`sniff`: the protocols to look for; all of them when empty."
    },
    "skip_rule_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`sniff`, a sail extension: a domain found that one of these rule-sets matches is not taken, neither matched nor connected to, as Mihomo's sniffer `skip-domain` has it."
    }
   },
   "additionalProperties": false
  },
  "route.rules[action=direct].domain_resolver": {
   "type": "object",
   "properties": {
    "server": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box)"
    },
    "timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box)"
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box)"
    },
    "disable_cache": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box)"
    },
    "disable_optimistic_cache": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box)"
    },
    "rewrite_ttl": {
     "type": "number",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box)"
    },
    "client_subnet": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box)"
    }
   },
   "additionalProperties": false
  },
  "route.rules[logical][nested]": {
   "type": "object",
   "properties": {
    "mode": {
     "type": "string",
     "enum": [
      "and",
      "or"
     ],
     "description": "`logical`: `and` or `or`."
    },
    "rules": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/route.rules%5Bnested%5D"
     },
     "description": "`logical`: the rules combined. They take no action of their own."
    },
    "invert": {
     "type": "boolean"
    },
    "type": {
     "const": "logical"
    }
   },
   "additionalProperties": false,
   "required": [
    "mode",
    "rules"
   ]
  },
  "route.rules[logical]+actions": {
   "type": "object",
   "properties": {
    "mode": {
     "type": "string",
     "enum": [
      "and",
      "or"
     ],
     "description": "`logical`: `and` or `or`."
    },
    "rules": {
     "type": "array",
     "items": {
      "$ref": "#/$defs/route.rules%5Bnested%5D"
     },
     "description": "`logical`: the rules combined. They take no action of their own."
    },
    "invert": {
     "type": "boolean"
    },
    "action": {
     "type": "string",
     "enum": [
      "route",
      "route-options",
      "reject",
      "hijack-dns",
      "sniff",
      "resolve",
      "bypass",
      "direct"
     ],
     "description": "`route` when unset."
    },
    "outbound": {
     "type": "string",
     "description": "`route`: where a matching connection goes."
    },
    "override_address": {
     "type": "string",
     "description": "`route`, `route-options`: connects to this address, an IP or a domain, instead of the one asked for, on the same port."
    },
    "override_port": {
     "type": "number",
     "description": "`route`, `route-options`: connects to this port instead."
    },
    "network_strategy": {
     "type": "string",
     "enum": [
      "default",
      "hybrid",
      "fallback"
     ],
     "description": "`route`, `route-options`: how a direct outbound the connection goes out of chooses among the host's interfaces, instead of as its own says; not where it binds its sockets itself. A later rule's goes before. As in sing-box, only where the destination is an address (for UDP, a connected one) or a `resolve` rule resolved it; other outbounds, a group whose pick is a direct one among them, take no notice of it. `direct`: checked only."
    },
    "fallback_delay": {
     "type": "number",
     "description": "`route`, `route-options`: how long a direct outbound the connection goes out of tries one family's addresses, and its first interfaces, before the others race them, instead of its own `fallback_delay`, where `network_strategy` would apply. A later rule's goes before. A duration string, as sing-box's documentation writes it, or a number of nanoseconds, as sing-box 1.14.1 reads it here. `direct`: checked only."
    },
    "udp_disable_domain_unmapping": {
     "type": "boolean",
     "description": "`route`, `route-options`: answers to UDP sent to a domain come back from the address it resolved to, not from the domain."
    },
    "udp_connect": {
     "type": "boolean",
     "description": "`route`, `route-options`: a direct outbound sends UDP from a connected socket."
    },
    "udp_timeout": {
     "type": "string",
     "description": "`route`, `route-options`: how long a UDP session lasts idle, instead of its inbound's `udp_timeout`."
    },
    "tls_fragment": {
     "type": "boolean",
     "description": "`route`, `route-options`: sends the TLS ClientHello in pieces, cut in the server name, each in a TCP segment of its own."
    },
    "tls_fragment_fallback_delay": {
     "type": "string",
     "description": "`route`, `route-options`: how long to wait between the pieces; 500ms when unset."
    },
    "tls_record_fragment": {
     "type": "boolean",
     "description": "`route`, `route-options`: sends the TLS ClientHello as several TLS records, cut in the server name."
    },
    "tls_spoof": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "tls_spoof_method": {
     "not": {},
     "description": "sail refuses this field: Fragmenting or spoofing the TLS handshake against censorship"
    },
    "bind_interface": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the interface to send through, by name."
    },
    "inet4_bind_address": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the local address for IPv4 destinations."
    },
    "inet6_bind_address": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the local address for IPv6 destinations."
    },
    "bind_address_no_port": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: `IP_BIND_ADDRESS_NO_PORT` on TCP sockets bound to an address: Linux only."
    },
    "protect_path": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the Unix socket each socket's descriptor is handed to, to be protected: Unix only."
    },
    "routing_mark": {
     "anyOf": [
      {
       "type": "number"
      },
      {
       "type": "string"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: `SO_MARK`, Linux only."
    },
    "reuse_addr": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: `SO_REUSEADDR`, and `SO_REUSEPORT` on Unix, on UDP sockets."
    },
    "netns": {
     "not": {},
     "description": "sail refuses this field: Linux network namespaces: sockets would leave another way"
    },
    "connect_timeout": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: how long a TCP connect to one address may take; 5s when unset."
    },
    "tcp_fast_open": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: TCP Fast Open."
    },
    "tcp_multi_path": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Socket tuning: connections go the same way without it"
    },
    "disable_tcp_keep_alive": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: no TCP keepalive at all."
    },
    "tcp_keep_alive": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: how long a TCP connection is idle before keepalive probes it; 5m when unset."
    },
    "tcp_keep_alive_interval": {
     "type": "string",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: between keepalive probes; 75s when unset."
    },
    "udp_fragment": {
     "type": "boolean",
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: whether UDP datagrams may be fragmented on the way; not when unset, as sing-box's direct action has it."
    },
    "domain_resolver": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "$ref": "#/$defs/route.rules%5Baction%3Ddirect%5D.domain_resolver"
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the DNS server that resolves the names it dials."
    },
    "network_type": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "examples": [
      "cellular",
      "ethernet",
      "other",
      "wifi"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). The kind of network: `wifi`, `cellular`, `ethernet`, `other`."
    },
    "fallback_network_type": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "wifi",
        "cellular",
        "ethernet",
        "other"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "wifi",
         "cellular",
         "ethernet",
         "other"
        ]
       }
      }
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: the types of interface its `fallback` strategy falls back to. Its `network_type` is not one: a rule's `network_type` is its condition, as in sing-box."
    },
    "domain_strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "deprecated": true,
     "description": "sail ignores this field, with a warning: Accepted, no effect (as sing-box). `direct`: sing-box's deprecated field for the families names resolve to."
    },
    "method": {
     "type": "string",
     "enum": [
      "default",
      "drop",
      "reply"
     ],
     "description": "`reject`: how."
    },
    "no_drop": {
     "type": "boolean",
     "description": "`reject`: never drops, however many connections the rule rejects."
    },
    "server": {
     "type": "string",
     "description": "`resolve`: the DNS server to ask, rather than the one the DNS rules pick."
    },
    "timeout": {
     "type": "string",
     "description": "`sniff`: how long to wait for the first bytes; 300ms when unset. `resolve`: how long to wait for the answer; `dns.timeout` when unset."
    },
    "strategy": {
     "type": "string",
     "enum": [
      "prefer_ipv4",
      "prefer_ipv6",
      "ipv4_only",
      "ipv6_only"
     ],
     "description": "`resolve`: the address families, instead of `dns.strategy`."
    },
    "disable_cache": {
     "type": "boolean",
     "description": "`resolve`: the answers neither come from the DNS cache nor go into it."
    },
    "disable_optimistic_cache": {
     "type": "boolean",
     "description": "`resolve`: an expired answer is not given while it is asked for again, though `dns.optimistic` is enabled."
    },
    "rewrite_ttl": {
     "type": "number",
     "description": "`resolve`: the TTL the answers' records carry, in seconds."
    },
    "client_subnet": {
     "type": "string",
     "description": "`resolve`: the EDNS Client Subnet the queries carry, instead of `dns.client_subnet`."
    },
    "ignore_failure": {
     "type": "boolean",
     "description": "`resolve`, a sail extension: a domain that does not resolve, or not in time, has no addresses, and matching goes on, as Mihomo's IP rules have it; rather than the connection failing, as in sing-box."
    },
    "on_demand": {
     "type": "boolean",
     "description": "`resolve`, `sniff`, a sail extension: the rule does not act where it stands but arms its action, with its options, and matching goes on. The action is taken the first time a later rule needs what it learns, just before that rule is matched: a resolve for a rule with conditions on the destination's addresses, while the destination is a domain; a sniff for one on the protocol, the plain HTTP request, or a domain while the destination is an address. A connection no later rule needs it for is never resolved or sniffed, as Surge and Mihomo have it. A later rule arming the same action replaces its options."
    },
    "override_destination": {
     "anyOf": [
      {
       "type": "boolean"
      },
      {
       "type": "string"
      }
     ],
     "description": "`route`, `route-options`, `sniff`, a sail extension: a connection to an address is dialled by the name known for it, the sniffed domain or else the one `dns.reverse_mapping` keeps, where its last hop dials a proxy's server (`true` or `\"proxy\"`), or a direct dial too (`\"proxy_and_direct\"`). The rules still match the address. On a sniff rule, `\"at_sniff\"` instead makes the sniffed domain the destination there, for the rules after, as Mihomo's sniffer does."
    },
    "sniffer": {
     "anyOf": [
      {
       "type": "string",
       "enum": [
        "tls",
        "http",
        "quic",
        "dns",
        "stun",
        "bittorrent",
        "dtls"
       ]
      },
      {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "tls",
         "http",
         "quic",
         "dns",
         "stun",
         "bittorrent",
         "dtls"
        ]
       }
      }
     ],
     "description": "`sniff`: the protocols to look for; all of them when empty."
    },
    "skip_rule_set": {
     "anyOf": [
      {
       "type": "string"
      },
      {
       "type": "array",
       "items": {
        "type": "string"
       }
      }
     ],
     "description": "`sniff`, a sail extension: a domain found that one of these rule-sets matches is not taken, neither matched nor connected to, as Mihomo's sniffer `skip-domain` has it."
    },
    "type": {
     "const": "logical"
    }
   },
   "additionalProperties": false,
   "required": [
    "mode",
    "rules"
   ]
  },
  "route.rules[nested]": {
   "type": "object",
   "properties": {
    "type": {
     "enum": [
      "default",
      "logical"
     ]
    }
   },
   "allOf": [
    {
     "if": {
      "properties": {
       "type": {
        "const": "logical"
       }
      },
      "required": [
       "type"
      ]
     },
     "then": {
      "$ref": "#/$defs/route.rules%5Blogical%5D%5Bnested%5D"
     },
     "else": {
      "$ref": "#/$defs/route.rules%5B%5D%5Bconditions%5D"
     }
    }
   ]
  },
  "user_limits": {
   "type": "object",
   "properties": {
    "max_connections": {
     "type": "number",
     "description": "How many connections it may have live at once."
    },
    "quota_bytes": {
     "type": "number",
     "description": "How many bytes, up and down together, it may send and receive; kept across restarts in the cache file, which it needs."
    },
    "expire_at": {
     "type": "string",
     "description": "When it may no longer connect, in RFC 3339."
    },
    "up_mbps": {
     "type": "number",
     "description": "Its rate up, what its clients send, in Mbps: the unit of sing-box's Hysteria2 `up_mbps`, not its direction."
    },
    "down_mbps": {
     "type": "number",
     "description": "Its rate down, what its clients receive, in Mbps."
    }
   },
   "additionalProperties": false
  }
 }
}
