diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index dd71ff578d..93e57441b1 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -14,6 +14,10 @@ updates:
directory: "/"
cooldown:
default-days: 42
+ exclude:
+ - "pyopenssl"
+ - "cryptography"
+ - "mitmproxy*"
schedule:
interval: "monthly"
open-pull-requests-limit: 10
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
index 8c30c96914..c46bcf6a2b 100644
--- a/.github/workflows/autofix.yml
+++ b/.github/workflows/autofix.yml
@@ -25,7 +25,7 @@ jobs:
- run: web/gen/all
- - uses: actions/setup-node@v6
+ - uses: actions/setup-node@v6.3.0
with:
node-version-file: .github/node-version.txt
- run: npm ci
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 81963bd475..53ac689270 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -96,7 +96,7 @@ jobs:
- if: runner.os == 'macOS' && github.repository == 'mitmproxy/mitmproxy'
&& (startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/tags/'))
id: keychain
- uses: apple-actions/import-codesign-certs@b610f78488812c1e56b20e6df63ec42d833f2d14
+ uses: apple-actions/import-codesign-certs@fe74d46e82474f87e1ba79832ad28a4013d0e33a
with:
keychain: ${{ runner.temp }}/temp
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
@@ -153,11 +153,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: mhils/workflows/checkout@8fe88b311a66c441e01edfebe4cd90d8a47fa335
- - uses: actions/setup-node@v6
+ - uses: actions/setup-node@v6.3.0
with:
node-version-file: .github/node-version.txt
- name: Cache Node.js modules
- uses: actions/cache@v5
+ uses: actions/cache@v5.0.4
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
@@ -250,16 +250,16 @@ jobs:
with:
name: binaries.wheel
path: release/docker
- - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v1.6.0
+ - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
+ - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v1.6.0
- name: Login to Docker Hub
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
+ uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
with:
username: mitmbot
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
+ uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -267,7 +267,7 @@ jobs:
- name: Docker meta
id: meta
- uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051
+ uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf
env:
DOCKER_METADATA_ANNOTATIONS_LEVELS: index
with:
@@ -283,7 +283,7 @@ jobs:
- name: Build and push
id: push
- uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
+ uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
with:
context: release/docker
platforms: linux/amd64,linux/arm64
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 475b67a36c..2f7802447f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v6
with:
token: ${{ secrets.GH_PUSH_TOKEN }} # this token works to push to the protected main branch.
- - uses: actions/setup-node@v6
+ - uses: actions/setup-node@v6.3.0
with:
node-version-file: .github/node-version.txt
- uses: mhils/workflows/setup-python@8fe88b311a66c441e01edfebe4cd90d8a47fa335
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 109f8e799c..ba8bb13d7f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,29 @@
## Unreleased: mitmproxy next
+- Fix contentview detection for XML files that start with CRLF.
+ ([#8243](https://github.com/mitmproxy/mitmproxy/pull/8243), @ADiTyaRaj8969)
+- mitmweb: Fix the filter input losing half-typed text on unrelated parent re-renders.
+ ([#8234](https://github.com/mitmproxy/mitmproxy/pull/8234), @ariel42)
+- mitmweb: Fix an infinite update cycle in `FlowTable` by only recomputing the virtual-scroll window in `componentDidUpdate` when `flowView` or `rowHeight` actually change.
+ ([#8233](https://github.com/mitmproxy/mitmproxy/pull/8233), @ariel42)
+- mitmweb: Fix AVIF images and `image/vnd.microsoft.icon` favicons not rendering in the response tab.
+ ([#8232](https://github.com/mitmproxy/mitmproxy/pull/8232), @ariel42)
+
+## 12 May 2026: mitmproxy 12.2.3
+
+- Reduce generated leaf certificate validity from 199 to 197 days so the 2-day
+ `notBefore` backdate remains below Chromium's 200-day limit.
+ ([#8203](https://github.com/mitmproxy/mitmproxy/pull/8203), @emanuele-em)
+- Fixed a bug where mitmweb would not pick up its XSRF cookie.
+ ([#8224](https://github.com/mitmproxy/mitmproxy/pull/8224), @mhils)
+- Fix `authority and subject key identifier mismatch` errors when mitmproxy
+ is configured with a custom CA whose SubjectKeyIdentifier was not derived
+ as SHA-1 of the public key.
+ ([#8214](https://github.com/mitmproxy/mitmproxy/pull/8214), @unique-jakub)
+- Fix `IndexError` in `is_mostly_bin` when exporting flows to HAR with payloads
+ that have a UTF-8 continuation byte at the 100-byte cutoff.
+ ([#8196](https://github.com/mitmproxy/mitmproxy/pull/8196), @juliosuas)
## 12 April 2026: mitmproxy 12.2.2
diff --git a/docs/build.py b/docs/build.py
index d8c3e944c2..2f0677f818 100755
--- a/docs/build.py
+++ b/docs/build.py
@@ -1,13 +1,16 @@
#!/usr/bin/env python3
import shutil
import subprocess
+import sys
from pathlib import Path
here = Path(__file__).parent
for script in sorted((here / "scripts").glob("*.py")):
print(f"Generating output for {script.name}...")
- out = subprocess.check_output(["python3", script.absolute()], cwd=here, text=True)
+ out = subprocess.check_output(
+ [sys.executable, script.absolute()], cwd=here, text=True
+ )
if out:
(here / "src" / "generated" / f"{script.stem}.html").write_text(
out, encoding="utf8"
diff --git a/docs/src/content/addons/overview.md b/docs/src/content/addons/overview.md
index cecb2c6646..409ad69677 100644
--- a/docs/src/content/addons/overview.md
+++ b/docs/src/content/addons/overview.md
@@ -54,3 +54,28 @@ This lets us place event handler functions in the module scope.
For instance, here is a complete script that adds a header to every request:
{{< example src="examples/addons/anatomy2.py" lang="py" >}}
+
+# Developing Addons
+
+## Live Reloading
+
+Scripts loaded with `-s path/to/script.py` are watched for changes.
+Whenever the file's modification time changes, mitmproxy unregisters the
+old module, re-imports the file, and re-registers the new addon — without
+restarting the proxy or losing the state of any other addons or in-flight
+flows. This means you can edit your addon in your editor and the changes
+take effect on the next save (within roughly one second).
+
+Errors raised at import time, in `configure`, or in `running` are logged
+to the event log and the previous version of the addon is left
+unregistered. Fix the error and save the file again to retry. Errors
+raised inside event handlers (`request`, `response`, …) are logged but do
+not unload the addon.
+
+## Testing Addons
+
+Because addons are regular Python files, the easiest way to unit-test
+them is to import the module from your test, instantiate the addon, and
+call the event handler directly. For more complex testing needs,
+see [`test/mitmproxy/addons`](https://github.com/mitmproxy/mitmproxy/tree/main/test/mitmproxy/addons)
+(but please note that internal testing helpers have no guaranteed stable API).
diff --git a/examples/contrib/block_dns_over_https.py b/examples/contrib/block_dns_over_https.py
index 63f0c723db..7178aa41e3 100644
--- a/examples/contrib/block_dns_over_https.py
+++ b/examples/contrib/block_dns_over_https.py
@@ -257,8 +257,8 @@
doh_hostnames, doh_ips = default_blocklist["hostnames"], default_blocklist["ips"]
# convert to sets for faster lookups
-doh_hostnames = set(doh_hostnames)
-doh_ips = set(doh_ips)
+doh_hostnames = set(doh_hostnames) | set(additional_doh_names)
+doh_ips = set(doh_ips) | set(additional_doh_ips)
def _has_dns_message_content_type(flow):
@@ -335,7 +335,7 @@ def _requested_hostname_is_in_doh_blocklist(flow):
:return: True if server's hostname is in DoH blocklist, otherwise False
"""
hostname = flow.request.host
- ip = flow.server_conn.address
+ ip = flow.server_conn.address[0]
return hostname in doh_hostnames or hostname in doh_ips or ip in doh_ips
diff --git a/mitmproxy/certs.py b/mitmproxy/certs.py
index 2f421e25e1..b67e064cee 100644
--- a/mitmproxy/certs.py
+++ b/mitmproxy/certs.py
@@ -35,10 +35,14 @@
logger = logging.getLogger(__name__)
# Default expiry must not be too long: https://github.com/mitmproxy/mitmproxy/issues/815
+# Note that expiry will be offset by `CERT_VALIDITY_OFFSET`, i.e. the cert will be
+# backdated a bit to account for clients with incorrect clocks.
CA_EXPIRY = datetime.timedelta(days=10 * 365)
CERT_EXPIRY = datetime.timedelta(days=199)
CRL_EXPIRY = datetime.timedelta(days=7)
+CERT_VALIDITY_OFFSET = datetime.timedelta(days=-2)
+
# Generated with "openssl dhparam". It's too slow to generate this on startup.
DEFAULT_DHPARAM = b"""
-----BEGIN DH PARAMETERS-----
@@ -245,8 +249,8 @@ def create_ca(
builder = x509.CertificateBuilder()
builder = builder.serial_number(x509.random_serial_number())
builder = builder.subject_name(name)
- builder = builder.not_valid_before(now - datetime.timedelta(days=2))
- builder = builder.not_valid_after(now + CA_EXPIRY)
+ builder = builder.not_valid_before(now + CERT_VALIDITY_OFFSET)
+ builder = builder.not_valid_after(now + CERT_VALIDITY_OFFSET + CA_EXPIRY)
builder = builder.issuer_name(name)
builder = builder.public_key(private_key.public_key())
builder = builder.add_extension(
@@ -335,8 +339,8 @@ def dummy_cert(
builder = builder.public_key(cacert.public_key())
now = datetime.datetime.now()
- builder = builder.not_valid_before(now - datetime.timedelta(days=2))
- builder = builder.not_valid_after(now + CERT_EXPIRY)
+ builder = builder.not_valid_before(now + CERT_VALIDITY_OFFSET)
+ builder = builder.not_valid_after(now + CERT_VALIDITY_OFFSET + CERT_EXPIRY)
subject = []
is_valid_commonname = commonname is not None and len(commonname) < 64
@@ -356,10 +360,26 @@ def dummy_cert(
)
# https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.1
- builder = builder.add_extension(
- x509.AuthorityKeyIdentifier.from_issuer_public_key(cacert.public_key()), # type: ignore
- critical=False,
- )
+ # Per RFC 5280 §4.2.1.2, the AKI's keyIdentifier in a child certificate
+ # MUST be byte-equal to the issuer's stored SubjectKeyIdentifier. If we
+ # recompute it from the public key with `from_issuer_public_key()`, we
+ # always derive a SHA-1 digest, which mismatches whenever the issuer's
+ # SKI was generated by a different method (RFC 7093 truncated
+ # SHA-256/384/512, hardware-rooted CAs, or any custom value). This
+ # mismatch is rejected by strict TLS chain builders (`X509_V_FLAG_X509_STRICT`,
+ # Python `ssl`, Go `crypto/x509`) with "authority and subject key
+ # identifier mismatch". Most notably, cert-manager >=1.18 / Go >=1.25
+ # default to truncated SHA-256 SKIs for FIPS 140-3 compliance.
+ try:
+ issuer_ski = cacert.extensions.get_extension_for_class(
+ x509.SubjectKeyIdentifier
+ ).value
+ aki = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(issuer_ski)
+ except x509.ExtensionNotFound:
+ # Fall back when the issuer cert has no SKI extension at all (legacy
+ # CAs predating RFC 5280 conformance).
+ aki = x509.AuthorityKeyIdentifier.from_issuer_public_key(cacert.public_key()) # type: ignore
+ builder = builder.add_extension(aki, critical=False)
# If CA and leaf cert have the same Subject Key Identifier, SChannel breaks in funny ways,
# see https://github.com/mitmproxy/mitmproxy/issues/6494.
# https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.2 states
@@ -400,8 +420,8 @@ def dummy_crl(
builder = builder.issuer_name(cacert.issuer)
now = datetime.datetime.now()
- builder = builder.last_update(now - datetime.timedelta(days=2))
- builder = builder.next_update(now + CRL_EXPIRY)
+ builder = builder.last_update(now + CERT_VALIDITY_OFFSET)
+ builder = builder.next_update(now + CERT_VALIDITY_OFFSET + CRL_EXPIRY)
builder = builder.add_extension(x509.CRLNumber(1000), False) # meaningless number
crl = builder.sign(private_key=privkey, algorithm=hashes.SHA256())
diff --git a/mitmproxy/tools/web/app.py b/mitmproxy/tools/web/app.py
index c207701ed3..1989bd2e9d 100644
--- a/mitmproxy/tools/web/app.py
+++ b/mitmproxy/tools/web/app.py
@@ -925,6 +925,9 @@ def __init__(
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
xsrf_cookies=True,
+ # https://github.com/mitmproxy/mitmproxy/issues/8194
+ # 2026-05: We can move back to the default cookie name in a few years.
+ xsrf_cookie_name="_mitmproxy_xsrf",
xsrf_cookie_kwargs=dict(samesite="Strict"),
cookie_secret=secrets.token_bytes(32),
debug=debug,
diff --git a/mitmproxy/tools/web/index.html b/mitmproxy/tools/web/index.html
index 0ec4aa2fa6..74288b6128 100644
--- a/mitmproxy/tools/web/index.html
+++ b/mitmproxy/tools/web/index.html
@@ -5,7 +5,7 @@
mitmproxy
-
+
diff --git a/mitmproxy/tools/web/static/index-D7g-N5jK.js b/mitmproxy/tools/web/static/index-Be7e-cwP.js
similarity index 80%
rename from mitmproxy/tools/web/static/index-D7g-N5jK.js
rename to mitmproxy/tools/web/static/index-Be7e-cwP.js
index 7dc205c955..54b08644e2 100644
--- a/mitmproxy/tools/web/static/index-D7g-N5jK.js
+++ b/mitmproxy/tools/web/static/index-Be7e-cwP.js
@@ -1,4 +1,4 @@
-import{c as fe,R as Cl,a as _e,r as I,b as Te,d as je,j as o,e as k,f as ui,u as Nl,g as kl,h as fi,s as Kt,i as El,l as Ht,k as Tl,m as Rl,n as Al,y as Dl,o as Fl,p as Il,q as zt,Q as Ll,t as Pl,P as Ol}from"./vendor-BS4xPthR.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))i(r);new MutationObserver(r=>{for(const n of r)if(n.type==="childList")for(const l of n.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&i(l)}).observe(document,{childList:!0,subtree:!0});function s(r){const n={};return r.integrity&&(n.integrity=r.integrity),r.referrerPolicy&&(n.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?n.credentials="include":r.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function i(r){if(r.ep)return;r.ep=!0;const n=s(r);fetch(r.href,n)}})();const Ml={tab:"request",contentViewFor:{}},ql=fe({name:"ui/flow",initialState:Ml,reducers:{selectTab(t,e){t.tab=e.payload},setContentViewFor(t,e){t.contentViewFor[e.payload.messageId]=e.payload.contentView}}}),{actions:Hl,reducer:Vl}=ql,{selectTab:Ut,setContentViewFor:pi}=Hl;window.React=Cl;const hi=function(t){if(t===0)return"0";const e=["b","kb","mb","gb","tb"];let s=0;for(;st);s++);let i;return t%Math.pow(1024,s)===0?i=0:i=1,(t/Math.pow(1024,s)).toFixed(i)+e[s]},mi=function(t){let e=t;const s=["ms","s","min","h"],i=[1e3,60,60];let r=0;for(;Math.abs(e)>=i[r]&&r{const t=Ul("_xsrf");return fs=()=>t,fs()};function ne(t,e={}){return e.method&&e.method!=="GET"&&(e.headers=e.headers||{},e.headers["X-XSRFToken"]=fs()),t.startsWith("/")&&(t="."+t),fetch(t,{credentials:"same-origin",...e})}ne.put=(t,e,s={})=>ne(t,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});ne.post=(t,e,s={})=>ne(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});async function Bt(t,...e){return await(await ne(`/commands/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({arguments:e})})).json()}async function gi(t){try{await navigator.clipboard.write([new ClipboardItem({"text/plain":t})]);return}catch(i){console.warn(i)}const e=await t;try{await navigator.clipboard.writeText(e);return}catch(i){console.warn(i)}const s=document.createElement("textarea");s.value=e,s.style.position="absolute",s.style.opacity="0",document.body.appendChild(s);try{if(s.focus(),s.select(),!document.execCommand("copy"))throw"failed to copy"}catch{alert(e)}finally{s.remove()}}async function Bl(t){await gi(Promise.resolve(t?.text||""))}function ps(t,e){const s=t.lastIndexOf(e);if(s===-1)return["",t];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function vi(t,e){const s=t.indexOf(e);if(s===-1)return[t,""];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function Ct(t){throw new Error(`Unreachable: ${JSON.stringify(t)}`)}const xi={http:80,https:443},Vn=new WeakMap;class we{static getContentType(e){const s=we.get_first_header(e,/^Content-Type$/i);if(s)return s.split(";")[0].trim()}static get_first_header(e,s){let i=Vn.get(e);i||(i=new Map,Vn.set(e,i));let r=i.get(s);if(r===void 0){const n=e.headers.find(([l,a])=>s.test(l));r=n?n[1]:!1,i.set(s,r)}return r!==!1?r:void 0}static match_header(e,s){const i=e.headers;if(!i)return!1;let r=i.length;for(;r--;)if(s.test(i[r].join(" ")))return i[r];return!1}static getContentURL(e,s,i,r){e.type==="http"&&s===e.request?s="request":e.type==="http"&&s===e.response&&(s="response");const n=r?`?lines=${r}`:"";return`./flows/${e.id}/${s}/`+(i?`content/${encodeURIComponent(i)}.json${n}`:"content.data")}}class ct extends we{static pretty_url(e){let s="";return xi[e.scheme]!==e.port&&(s=":"+e.port),e.scheme+"://"+e.pretty_host+s+e.path}}class mt extends we{}const Wl=/^(?:(https?):\/\/)?([^/:]+)?(?::(\d+))?(\/.*)?$/i,_i=function(t){const e=Wl.exec(t);if(!e)return;const s=e[1],i=e[2],r=parseInt(e[3]),n=e[4],l=s?r||xi[s]:r,a={};return s&&(a.scheme=s),i&&(a.host=i),l&&(a.port=l),n&&(a.path=n),a},Kl=/^HTTP\/\d+(\.\d+)*$/i,ji=function(t){return Kl.test(t)};function Wt(t){switch(t.type){case"http":return t.request.timestamp_start;case"tcp":case"udp":return t.client_conn.timestamp_start;case"dns":return t.request.timestamp}}function yi(t){switch(t.type){case"http":if(t.websocket){if(t.websocket.timestamp_end)return t.websocket.timestamp_end;if(t.websocket.messages_meta.timestamp_last)return t.websocket.messages_meta.timestamp_last}return t.response?t.response.timestamp_end:void 0;case"tcp":return t.server_conn?.timestamp_end;case"udp":return t.messages_meta.timestamp_last;case"dns":return t.response?.timestamp}}const wi=t=>{switch(t.type){case"http":{let e=t.request.contentLength||0;return t.response&&(e+=t.response.contentLength||0),t.websocket&&(e+=t.websocket.messages_meta.contentLength||0),e}case"tcp":case"udp":return t.messages_meta.contentLength||0;case"dns":return t.response?.size??0}},xs=t=>t.type==="http"&&!t.websocket,bi=t=>t.modified,_s=t=>t.intercepted,Si=t=>{if(t.type!=="http")return t.client_conn.tls_version==="QUICv1"?"resource-icon-quic":`resource-icon-${t.type}`;if(t.websocket)return"resource-icon-websocket";if(!t.response)return"resource-icon-plain";const e=mt.getContentType(t.response)||"";return t.response.status_code===304?"resource-icon-not-modified":300<=t.response.status_code&&t.response.status_code<400?"resource-icon-redirect":e.indexOf("image")>=0?"resource-icon-image":e.indexOf("javascript")>=0?"resource-icon-js":e.indexOf("css")>=0?"resource-icon-css":e.indexOf("html")>=0?"resource-icon-document":"resource-icon-plain"},$i=t=>{switch(t.type){case"http":return ct.pretty_url(t.request);case"tcp":case"udp":return`${t.client_conn.peername.join(":")} ↔ ${t.server_conn?.address?.join(":")}`;case"dns":return`${t.request.questions.map(e=>`${e.name} ${e.type}`).join(", ")} = ${(t.response?.answers.map(e=>e.data).join(", ")??"...")||"?"}`}},Ci=t=>{switch(t.type){case"http":return t.response?.status_code;case"dns":return t.response?.response_code;default:return}},Ni=t=>{switch(t.type){case"http":return t.websocket?t.client_conn.tls_established?"WSS":"WS":t.request.method;case"dns":return t.request.op_code;default:return t.type.toUpperCase()}},ki=t=>{switch(t.type){case"http":return t.request.http_version;default:return""}},Ei={tls:t=>t.type==="http"&&t.request.scheme,icon:Si,index:()=>0,path:$i,method:Ni,version:ki,status:Ci,size:wi,time:t=>{const e=Wt(t),s=yi(t);return e&&s&&s-e},timestamp:Wt,quickactions:()=>0,comment:t=>t.comment};function zl(t){return t in Ei}var ve=(t=>(t.Search="search",t.Highlight="highlight",t))(ve||{});const Ti={search:"",highlight:""},Gl=fe({name:"ui/filters",initialState:Ti,reducers:{setFilter(t,e){t.search=e.payload},setHighlight(t,e){t.highlight=e.payload}}}),{actions:Yl,reducer:Jl}=Gl,{setFilter:Ri,setHighlight:Ai}=Yl;function rs(t,e){return t.toSorted?t.toSorted(e):[...t].sort(e)}function js(t,...e){if(t.toSpliced)return t.toSpliced(...e);{const s=[...t];return s.splice(...e),s}}function jt(t){return new Map(t.map((e,s)=>[e.id,s]))}function os(t){return new Set(t.map(e=>e.id))}function Un(t,e){return t.has(e)&&(t=new Set(t),t.delete(e)),t}function Bn(t,e,s){const i=js(t,s,1),r=new Map(e);r.delete(t[s].id);for(let n=i.length-1;n>=s;n--)r.set(i[n].id,n);return{view:i,_viewIndex:r}}function Ql(t,e,s,i){const r=[...t],n=r.length;let l=e,a=l.get(s.id);if(a+10){l=new Map(l);do{const d=r[a+1];r[a]=d,l.set(d.id,a),a++}while(a+10);l.set(s.id,a)}else if(a>0&&i(s,r[a-1])<0){l=new Map(l);do{const d=r[a-1];r[a]=d,l.set(d.id,a),a--}while(a>0&&i(s,r[a-1])<0);l.set(s.id,a)}return r[a]=s,{view:r,_viewIndex:l}}function Wn(t,e,s,i){const r=Xl(t,s,i),n=js(t,r,0,s),l=new Map(e);for(let a=n.length-1;a>=r;a--)l.set(n[a].id,a);return{view:n,_viewIndex:l}}function Xl(t,e,s){let i=0,r=t.length;if(r===0||s(t[r-1],e)<=0)return r;for(;i>>1;s(e,t[n])>=0?i=n+1:r=n}return i}function ys(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/resume`,{method:"POST"})))}function Di(){return()=>ne("/flows/resume",{method:"POST"})}function Fi(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/kill`,{method:"POST"})))}function Zl(){return()=>ne("/flows/kill",{method:"POST"})}function Ii(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}`,{method:"DELETE"})))}function Li(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/duplicate`,{method:"POST"})))}function ws(t){return t=t.filter(xs),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/replay`,{method:"POST"})))}function Pi(t){return t=t.filter(bi),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/revert`,{method:"POST"})))}function Kn(t,e){return()=>Promise.all(t.map(s=>Le(s,{marked:e})()))}function Le(t,e){return()=>ne.put(`/flows/${t.id}`,e)}function ec(t,e,s){const i=new FormData;return e=new window.Blob([e],{type:"plain/text"}),i.append("file",e),()=>ne(`/flows/${t.id}/${s}/content.data`,{method:"POST",body:i})}function Oi(){return()=>ne("/clear",{method:"POST"})}function tc(t){const e=new FormData;return e.append("file",t),()=>ne("/flows/dump",{method:"POST",body:e})}const Mi=_e("flows/add"),qi=_e("flows/update"),Hi=_e("flows/remove"),bs=_e("flows/receive"),Vi=_e("flows/filterUpdate"),Ui=_e("flows/sort"),Ve=_e("flows/select"),sc={list:[],_listIndex:new Map,byId:new Map,view:[],_viewIndex:new Map,sort:{column:void 0,desc:!1},selected:[],selectedIds:new Set,highlightedIds:new Set};function nc(t=sc,e){if(bs.match(e)){const{sort:s}=t,i=e.payload,r=jt(i),n=new Map(i.map(h=>[h.id,h])),l=rs(i,pt(s)),a=jt(l),d=t.selected.map(h=>n.get(h.id)).filter(h=>h!==void 0),f=os(d);return{list:i,_listIndex:r,byId:n,view:l,_viewIndex:a,sort:s,selected:d,selectedIds:f,highlightedIds:new Set}}else if(Mi.match(e)){const{flow:s,matching_filters:i}=e.payload;if(t._listIndex.has(s.id))return t;const{sort:r,selected:n,selectedIds:l}=t;let{view:a,_viewIndex:d,highlightedIds:f}=t;const p=new Map(t._listIndex);p.set(s.id,t.list.length);const h=[...t.list,s],g=new Map(t.byId);return g.set(s.id,s),(i[ve.Search]===!0||i[ve.Search]===void 0)&&({view:a,_viewIndex:d}=Wn(a,d,s,pt(r))),i[ve.Highlight]===!0&&(f=new Set(f),f.add(s.id)),{list:h,_listIndex:p,byId:g,view:a,_viewIndex:d,sort:r,selected:n,selectedIds:l,highlightedIds:f}}else if(qi.match(e)){const{flow:s,matching_filters:i}=e.payload,{_listIndex:r,sort:n,selectedIds:l}=t;let{view:a,_viewIndex:d,selected:f,highlightedIds:p}=t;const h=t._listIndex.get(s.id),g=[...t.list];h!==void 0?g[h]=s:g.push(s);const _=new Map(t.byId);_.set(s.id,s);const j=d.get(s.id),y=j!==void 0,w=i[ve.Search]===!0||i[ve.Search]===void 0;return w&&!y?{view:a,_viewIndex:d}=Wn(a,d,s,pt(n)):!w&&y?{view:a,_viewIndex:d}=Bn(a,d,j):w&&y&&({view:a,_viewIndex:d}=Ql(a,d,s,pt(n))),l.has(s.id)&&(f=f.map($=>$.id===s.id?s:$)),i[ve.Highlight]===!0?p.has(s.id)||(p=new Set(p),p.add(s.id)):p=Un(p,s.id),{list:g,_listIndex:r,byId:_,view:a,_viewIndex:d,sort:n,selected:f,selectedIds:l,highlightedIds:p}}else if(Hi.match(e)){const s=e.payload,{sort:i}=t;let{view:r,_viewIndex:n,selected:l,selectedIds:a}=t;const d=t._listIndex.get(s);if(d===void 0)return t;const f=js(t.list,d,1),p=jt(f),h=new Map(t.byId);h.delete(s);const g=n.get(s);if(g!==void 0&&({view:r,_viewIndex:n}=Bn(r,n,g)),a.has(s)){if(l.length===1&&g!==void 0){const j=r[g]??r[g-1];l=j?[j]:[]}else l=l.filter(j=>j.id!==s);a=os(l)}const _=Un(t.highlightedIds,s);return{list:f,_listIndex:p,byId:h,view:r,_viewIndex:n,sort:i,selected:l,selectedIds:a,highlightedIds:_}}else if(Vi.match(e)){const{name:s,matching_flow_ids:i}=e.payload;switch(s){case ve.Search:{const r=rs(i===null?t.list:i.map(l=>t.byId.get(l)).filter(l=>l!==void 0),pt(t.sort)),n=jt(r);return{...t,view:r,_viewIndex:n}}case ve.Highlight:return{...t,highlightedIds:new Set(i)};default:Ct(s)}}else if(Ui.match(e)){const s=e.payload;let i;s.column?i=rs(t.view,pt(s)):i=t.list.filter(n=>t._viewIndex.has(n.id));const r=jt(i);return{...t,sort:s,view:i,_viewIndex:r}}else return Ve.match(e)?{...t,selected:e.payload,selectedIds:os(e.payload)}:t}function pt({column:t,desc:e}){if(!t)return(i,r)=>0;const s=Ei[t];return(i,r)=>{const n=s(i),l=s(r);return n>l?e?-1:1:n{const{flows:i}=s();i.selectedIds.has(t.id)?e(Ve(i.selected.filter(r=>r!==t))):e(Ve([...i.selected,t]))}}function rc(t){return(e,s)=>{const{flows:i}=s(),r=i.selected[i.selected.length-1],n=i._viewIndex.get(t.id),l=i._viewIndex.get(r?.id);if(n===void 0||l===void 0)return e(Ve([t]));let a;return n<=l?a=i.view.slice(n,l+1):(a=i.view.slice(l+1,n+1),a.push(r)),e(Ve(a))}}const oc={activeModal:void 0},Bi=fe({name:"ui/modal",initialState:oc,reducers:{setActiveModal(t,e){t.activeModal=e.payload},hideModal(t){t.activeModal=void 0}}}),{actions:lc,reducer:cc}=Bi,ac=Bi.actions.hideModal.type,{setActiveModal:dc,hideModal:Wi}=lc,zn=(()=>{const t=document.createElement("div");return t.setAttribute("contenteditable","PLAINTEXT-ONLY"),t.contentEditable==="plaintext-only"?"plaintext-only":"true"})();class ce extends I.Component{input=Te.createRef();render(){const e=je("inline-input",this.props.className);return o.jsx("span",{ref:this.input,tabIndex:0,className:e,placeholder:this.props.placeholder,onFocus:this.onFocus,onBlur:this.onBlur,onKeyDown:this.onKeyDown,onInput:this.onInput,onPaste:this.onPaste,onMouseDown:this.onMouseDown,onClick:this.onClick,children:this.props.content})}componentDidUpdate(e){e.content!==this.props.content&&this.props.onInput?.(this.props.content)}isEditing=()=>this.input.current?.contentEditable===zn;startEditing=()=>{if(!this.input.current)return console.error("unreachable");this.isEditing()||(this.suppress_events=!0,this.input.current.blur(),this.input.current.contentEditable=zn,window.requestAnimationFrame(()=>{if(this.input.current){if(this.input.current.focus(),this.suppress_events=!1,this.props.selectAllOnClick){const e=document.createRange();e.selectNodeContents(this.input.current);const s=window.getSelection();s?.removeAllRanges(),s?.addRange(e)}this.props.onEditStart?.()}}))};resetValue=()=>{if(!this.input.current)return console.error("unreachable");this.input.current.textContent=this.props.content,this.props.onInput?.(this.props.content)};finishEditing=()=>{if(!this.input.current)return console.error("unreachable");this.props.onEditDone(this.input.current.textContent||""),this.input.current.blur(),this.input.current.contentEditable="inherit"};onPaste=e=>{e.preventDefault();const s=e.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,s)};suppress_events=!1;onMouseDown=e=>{this.suppress_events=!0,window.addEventListener("mouseup",this.onMouseUp,{once:!0})};onMouseUp=e=>{const s=e.target===this.input.current,i=!window.getSelection()?.toString();this.props.selectAllOnClick?s&&i&&this.startEditing():s&&this.startEditing(),this.suppress_events=!1};onClick=e=>{};onFocus=e=>{if(!this.input.current)throw"unreachable";this.suppress_events||this.startEditing()};onInput=e=>{this.props.onInput?.(this.input.current?.textContent||"")};onBlur=e=>{this.suppress_events||this.finishEditing()};onKeyDown=e=>{switch(e.stopPropagation(),e.key){case"Escape":e.preventDefault(),this.resetValue(),this.finishEditing();break;case"Enter":e.shiftKey||(e.preventDefault(),this.finishEditing());break}this.props.onKeyDown?.(e)}}function bt(t){const e=k.c(15);let s;e[0]!==t.content||e[1]!==t.isValid?(s=t.isValid(t.content),e[0]=t.content,e[1]=t.isValid,e[2]=s):s=e[2];const[i,r]=I.useState(s),n=I.useRef(null);let l;e[3]!==t?(l=_=>{t.isValid(_)?t.onEditDone(_):n.current?.resetValue()},e[3]=t,e[4]=l):l=e[4];const a=l,d=i?"has-success":"has-warning";let f;e[5]!==t.className||e[6]!==d?(f=je(t.className,d),e[5]=t.className,e[6]=d,e[7]=f):f=e[7];const p=f;let h;e[8]!==t?(h=_=>r(t.isValid(_)),e[8]=t,e[9]=h):h=e[9];let g;return e[10]!==p||e[11]!==a||e[12]!==t||e[13]!==h?(g=o.jsx(ce,{...t,className:p,onInput:h,onEditDone:a,ref:n}),e[10]=p,e[11]=a,e[12]=t,e[13]=h,e[14]=g):g=e[14],g}const G=()=>Nl(),D=kl,uc=ui.withTypes(),Ss=_e("EVENTS_ADD"),Ki=_e("EVENTS_RECEIVE"),Gt=_e("events/toggleVisibility"),zi=_e("events/toggleFilter");var Gi=(t=>(t.debug="debug",t.info="info",t.web="web",t.warn="warn",t.error="error",t))(Gi||{});const fc={visible:!1,filters:{debug:!1,info:!0,web:!0,warn:!0,error:!0},list:[],view:[]};function pc(t=fc,e){if(Ss.match(e)){const s=e.payload;return{...t,list:[...t.list,s],view:t.filters[s.level]?[...t.view,s]:t.view}}else{if(Ki.match(e))return{...t,list:e.payload,view:e.payload.filter(s=>t.filters[s.level])};if(Gt.match(e))return{...t,visible:!t.visible};if(zi.match(e)){const s={...t.filters,[e.payload]:!t.filters[e.payload]};return{...t,filters:s,view:t.list.filter(i=>s[i.level])}}else return t}}function hc(t,e="web"){return Ss({id:Math.random().toString(),message:t,level:e})}const Gn={},mc=fe({name:"ui/optionsEditor",initialState:Gn,reducers:{startUpdate(t,e){t[e.payload.option]={isUpdating:!0,value:e.payload.value,error:!1}},updateSuccess(t,e){t[e.payload.option]=void 0},updateError(t,e){let s=t[e.payload.option].value;typeof s=="boolean"&&(s=!s),t[e.payload.option]={value:s,isUpdating:!1,error:e.payload.error}}},extraReducers:t=>{t.addCase(ac,()=>Gn)}}),{actions:gc,reducer:vc}=mc,{startUpdate:xc,updateSuccess:_c,updateError:jc}=gc;var xe=(t=>(t[t.Capture=0]="Capture",t[t.FlowList=1]="FlowList",t[t.Options=2]="Options",t[t.Flow=3]="Flow",t))(xe||{});const yc=fe({name:"ui/tabs",initialState:{current:1},reducers:{setCurrent(t,e){t.current=e.payload}}}),{actions:wc,reducer:bc}=yc,{setCurrent:Vt}=wc,Sc=fi({flow:Vl,modal:cc,optionsEditor:vc,tabs:bc,filter:Jl});var wt=(t=>(t.INIT="CONNECTION_INIT",t.FETCHING="CONNECTION_FETCHING",t.ESTABLISHED="CONNECTION_ESTABLISHED",t.ERROR="CONNECTION_ERROR",t))(wt||{});const $c={state:"CONNECTION_INIT",message:void 0},Yi=fe({name:"connection",initialState:$c,reducers:{startFetching:t=>{t.state==="CONNECTION_INIT"&&(t.state="CONNECTION_FETCHING")},finishFetching:t=>{t.state==="CONNECTION_FETCHING"&&(t.state="CONNECTION_ESTABLISHED")},connectionError:(t,e)=>{t.state="CONNECTION_ERROR",t.message=e.payload}}}),{startFetching:Cc,finishFetching:Nc,connectionError:kc}=Yi.actions,Ec=Yi.reducer,Tc={add_upstream_certs_to_client_chain:!1,allow_hosts:[],anticache:!1,anticomp:!1,block_global:!0,block_list:[],block_private:!1,body_size_limit:void 0,cert_passphrase:void 0,certs:[],ciphers_client:void 0,ciphers_server:void 0,client_certs:void 0,client_replay:[],client_replay_concurrency:1,command_history:!0,confdir:"~/.mitmproxy",connect_addr:void 0,connection_strategy:"eager",console_focus_follow:!1,content_view_lines_cutoff:512,dns_name_servers:[],dns_use_hosts_file:!0,export_preserve_original_ip:!1,hardump:"",http2:!0,http2_ping_keepalive:58,http3:!0,http_connect_send_host_header:!0,ignore_hosts:[],intercept:void 0,intercept_active:!1,keep_alt_svc_header:!1,keep_host_header:!1,key_size:2048,listen_host:"",listen_port:void 0,map_local:[],map_remote:[],mode:["regular"],modify_body:[],modify_headers:[],normalize_outbound_headers:!0,onboarding:!0,onboarding_host:"mitm.it",protobuf_definitions:void 0,proxy_debug:!1,proxyauth:void 0,rawtcp:!0,readfile_filter:void 0,request_client_cert:!1,rfile:void 0,save_stream_file:void 0,save_stream_filter:void 0,scripts:[],server:!0,server_replay:[],server_replay_extra:"forward",server_replay_ignore_content:!1,server_replay_ignore_host:!1,server_replay_ignore_params:[],server_replay_ignore_payload_params:[],server_replay_ignore_port:!1,server_replay_kill_extra:!1,server_replay_nopop:!1,server_replay_refresh:!0,server_replay_reuse:!1,server_replay_use_headers:[],show_ignored_hosts:!1,showhost:!1,ssl_insecure:!1,ssl_verify_upstream_trusted_ca:void 0,ssl_verify_upstream_trusted_confdir:void 0,stickyauth:void 0,stickycookie:void 0,store_streamed_bodies:!1,stream_large_bodies:void 0,strip_ech:!0,tcp_hosts:[],tcp_timeout:600,termlog_verbosity:"info",tls_ecdh_curve_client:void 0,tls_ecdh_curve_server:void 0,tls_version_client_max:"UNBOUNDED",tls_version_client_min:"TLS1_2",tls_version_server_max:"UNBOUNDED",tls_version_server_min:"TLS1_2",udp_hosts:[],upstream_auth:void 0,upstream_cert:!0,validate_inbound_headers:!0,view_filter:void 0,view_order:"time",view_order_reversed:!1,web_columns:["tls","icon","path","method","status","size","time"],web_debug:!1,web_host:"127.0.0.1",web_open_browser:!0,web_password:"",web_port:8081,web_static_viewer:"",websocket:!0},Yt=_e("OPTIONS_RECEIVE"),$s=_e("OPTIONS_UPDATE"),Rc=fe({name:"options",initialState:Tc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>{const i={};for(const[r,{value:n}]of Object.entries(s.payload))i[r]=n;return i}).addCase($s,(e,s)=>{for(const[i,{value:r}]of Object.entries(s.payload))e[i]=r})}}),Ac=Rc.reducer;async function Dc(t,e,s){try{const i=await ne.put("/options",{[t]:e});if(i.status===200)s(_c({option:t}));else throw await i.text()}catch(i){s(jc({option:t,error:i.toString()}))}}const Fc=Dc;function Cs(t,e){return s=>{s(xc({option:t,value:e})),Fc(t,e,s)}}const Ic={visible:!1},Lc=fe({name:"commandBar",initialState:Ic,reducers:{toggleVisibility(t){t.visible=!t.visible}}}),{actions:Pc,reducer:Oc}=Lc,{toggleVisibility:Ji}=Pc,Ue=_e("STATE_RECEIVE"),Be=_e("STATE_UPDATE"),Mc={available:!1,version:"",contentViews:[],servers:{},platform:"",localModeUnavailable:null},qc=fe({name:"backendState",initialState:Mc,reducers:{},extraReducers:t=>{t.addCase(Ue,(e,s)=>({...e,available:!0,...s.payload})).addCase(Be,(e,s)=>({...e,...s.payload}))}}),Hc=qc.reducer,Vc={},Uc=fe({name:"optionsMeta",initialState:Vc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>s.payload).addCase($s,(e,s)=>({...e,...s.payload}))}}),Bc=Uc.reducer,dt=(t,e)=>e.listen_host&&e.listen_port?`${t}@${e.listen_host}:${e.listen_port}`:e.listen_port?`${t}@${e.listen_port}`:t,Qi=t=>{let[e,s]=ps(t,"@");e||(e=s,s="");const[i,r]=vi(e,":");let n,l;if(s){let a;if(s.includes(":")?[n,a]=ps(s,":"):(n="",a=s),a&&(l=parseInt(a,10),isNaN(l)||l<0||l>65535))throw new Error(`invalid port: ${a}`)}return{full_spec:t,name:i,data:r,listen_host:n,listen_port:l}},Xi=t=>dt("regular",t),Yn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Zi=t=>t.selectedProcesses?`local:${t.selectedProcesses}`:"local",Jn=({data:t})=>({ui_id:Math.random(),active:!0,selectedProcesses:t}),er=t=>{const e=t.file_path?`wireguard:${t.file_path}`:"wireguard";return dt(e,t)},Qn=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,listen_host:e,listen_port:s,file_path:t});var Jt=(t=>(t.HTTP="http",t.HTTPS="https",t.HTTP3="http3",t.TLS="tls",t.DTLS="dtls",t.TCP="tcp",t.UDP="udp",t.DNS="dns",t.QUIC="quic",t))(Jt||{}),ot=(t=>(t.CSS="css",t.JAVASCRIPT="javascript",t.XML="xml",t.YAML="yaml",t.NONE="none",t.ERROR="error",t))(ot||{});const hs=()=>({active:!1,protocol:Jt.HTTPS,destination:"",ui_id:Math.random()}),Ns=t=>dt(`reverse:${t.protocol}://${t.destination}`,t),Wc=({data:t,listen_host:e,listen_port:s})=>{let[i,r]=vi(t,"://");return r||(r=i,i=Jt.HTTPS),{ui_id:Math.random(),active:!0,protocol:i,destination:r,listen_host:e,listen_port:s}},tr=t=>dt("transparent",t),Xn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),sr=t=>dt("socks5",t),Zn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),nr=t=>dt(`upstream:${t.destination}`,t),ei=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,destination:t||"",listen_host:e,listen_port:s}),ir=t=>dt("dns",t),ti=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Xe=t=>t.active&&!t.error;async function Kc(t,e){const s=e.getState().modes,i=[...s.regular.filter(Xe).map(Xi),...s.local.filter(Xe).map(Zi),...s.wireguard.filter(Xe).map(er),...s.reverse.filter(Xe).map(Ns),...s.transparent.filter(Xe).map(tr),...s.socks.filter(Xe).map(sr),...s.upstream.filter(Xe).map(nr),...s.dns.filter(Xe).map(ir)],r=await ne.put("/options",{mode:i});if(r.status!==200)throw new Error(await r.text())}function ie(t){return uc(t,Kc)}function se(t,e,s){t.addCase(s.pending,(i,r)=>{const{server:n,value:l}=r.meta.arg,a=i.findIndex(d=>d.ui_id===n.ui_id);a>=0&&(i[a][e]=l,i[a].error=void 0)}),t.addCase(s.rejected,(i,r)=>{const{server:n}=r.meta.arg,l=i.findIndex(a=>a.ui_id===n.ui_id);l>=0&&(i[l].error=r.error.message)})}function be(t,e){return function(i,r){if(r.payload.servers){const n=Object.values(r.payload.servers).filter(l=>l.type===t).map(l=>Qi(l.full_spec));if(n.length>0)return n.map(e);for(const l of i)l.active=!1}}}const rr=ie("modes/regular/setActive"),or=ie("modes/regular/setListenHost"),lr=ie("modes/regular/setListenPort"),zc=[{active:!0,ui_id:Math.random()}],Gc=fe({name:"modes/regular",initialState:zc,reducers:{},extraReducers:t=>{se(t,"active",rr),se(t,"listen_host",or),se(t,"listen_port",lr),t.addCase(Ue,be("regular",Yn)),t.addCase(Be,be("regular",Yn))}}),Yc=Gc.reducer,cr=ie("modes/local/setActive"),St=ie("modes/local/setSelectedProcesses"),Jc=[{active:!1,selectedProcesses:"",ui_id:Math.random()}],Qc=fe({name:"modes/local",initialState:Jc,reducers:{},extraReducers:t=>{se(t,"active",cr),se(t,"selectedProcesses",St),t.addCase(Ue,be("local",Jn)),t.addCase(Be,be("local",Jn))}}),Xc=Qc.reducer,ar=ie("modes/wireguard/setActive"),dr=ie("modes/wireguard/setListenHost"),ur=ie("modes/wireguard/setListenPort"),fr=ie("modes/wireguard/setFilePath"),Zc=[{active:!1,ui_id:Math.random()}],ea=fe({name:"modes/wireguard",initialState:Zc,reducers:{},extraReducers:t=>{se(t,"active",ar),se(t,"listen_host",dr),se(t,"listen_port",ur),se(t,"file_path",fr),t.addCase(Ue,be("wireguard",Qn)),t.addCase(Be,be("wireguard",Qn))}}),ta=ea.reducer,ms=ie("modes/reverse/setActive"),pr=ie("modes/reverse/setListenHost"),hr=ie("modes/reverse/setListenPort"),mr=ie("modes/reverse/setProtocol"),gr=ie("modes/reverse/setDestination"),sa=[hs()],vr=fe({name:"modes/reverse",initialState:sa,reducers:{addServer:t=>{t.push(hs())},removeServer:(t,e)=>{const s=t.findIndex(i=>i.ui_id===e.payload.ui_id);s!==-1&&(t[s].active&&console.error("servers should be deactivated before removal"),t.splice(s,1))}},extraReducers:t=>{se(t,"active",ms),se(t,"listen_host",pr),se(t,"listen_port",hr),se(t,"protocol",mr),se(t,"destination",gr),t.addCase(Ue,e),t.addCase(Be,e);function e(s,i){if(i.payload.servers){const r=Object.fromEntries(Object.entries(i.payload.servers).filter(([l,a])=>a.type==="reverse").map(([l,a])=>[l,Qi(l)])),n=[];for(const l of s){const a=Ns(l),d=a in r;delete r[a],n.push({...l,active:d})}for(const l of Object.values(r))n.push(Wc(l));return n.length>1&&Kt({...n[0],ui_id:void 0},{...hs(),ui_id:void 0})&&n.shift(),n}}}}),{addServer:na,removeServer:ia}=vr.actions,ra=vr.reducer,xr=ie("modes/transparent/setActive"),_r=ie("modes/transparent/setListenHost"),jr=ie("modes/transparent/setListenPort"),oa=[{active:!1,ui_id:Math.random()}],la=fe({name:"modes/transparent",initialState:oa,reducers:{},extraReducers:t=>{se(t,"active",xr),se(t,"listen_host",_r),se(t,"listen_port",jr),t.addCase(Ue,be("transparent",Xn)),t.addCase(Be,be("transparent",Xn))}}),ca=la.reducer,yr=ie("modes/socks5/setActive"),wr=ie("modes/socks5/setListenHost"),br=ie("modes/socks5/setListenPort"),aa=[{active:!1,ui_id:Math.random()}],da=fe({name:"modes/socks5",initialState:aa,reducers:{},extraReducers:t=>{se(t,"active",yr),se(t,"listen_host",wr),se(t,"listen_port",br),t.addCase(Ue,be("socks5",Zn)),t.addCase(Be,be("socks5",Zn))}}),ua=da.reducer,Sr=ie("modes/upstream/setActive"),$r=ie("modes/upstream/setListenHost"),Cr=ie("modes/upstream/setListenPort"),Nr=ie("modes/upstream/setDestination"),fa=[{active:!1,destination:"",ui_id:Math.random()}],pa=fe({name:"modes/upstream",initialState:fa,reducers:{},extraReducers:t=>{se(t,"active",Sr),se(t,"listen_host",$r),se(t,"listen_port",Cr),se(t,"destination",Nr),t.addCase(Ue,be("upstream",ei)),t.addCase(Be,be("upstream",ei))}}),ha=pa.reducer,kr=ie("modes/dns/setActive"),Er=ie("modes/dns/setListenHost"),Tr=ie("modes/dns/setListenPort"),ma=[{active:!0,ui_id:Math.random()}],ga=fe({name:"modes/dns",initialState:ma,reducers:{},extraReducers:t=>{se(t,"active",kr),se(t,"listen_host",Er),se(t,"listen_port",Tr),t.addCase(Ue,be("dns",ti)),t.addCase(Be,be("dns",ti))}}),va=ga.reducer,xa=fi({regular:Yc,local:Xc,wireguard:ta,reverse:ra,transparent:ca,socks:ua,upstream:ha,dns:va}),$t=ui("fetchProcesses",async(t,{rejectWithValue:e})=>{try{return(await ne("/processes")).json()}catch(s){return e(s.message)}}),_a={currentProcesses:[],isLoading:!1},ja=fe({name:"processes",initialState:_a,reducers:{},extraReducers:t=>{t.addCase($t.pending,e=>{e.isLoading=!0,e.error=void 0}),t.addCase($t.fulfilled,(e,s)=>{e.isLoading=!1,e.currentProcesses=s.payload}),t.addCase($t.rejected,(e,s)=>{e.isLoading=!1,e.error=s.payload})}}),ya=ja.reducer,wa={commandBar:Oc,eventLog:pc,flows:nc,connection:Ec,modes:xa,ui:Sc,options:Ac,options_meta:Bc,backendState:Hc,processes:ya},ba={immutableCheck:{warnAfter:5e5},serializableCheck:{warnAfter:5e5,ignoredPaths:["flows"]}},Nt=El({reducer:wa,middleware:t=>t(ba),devTools:!1});class Sa extends I.Component{container=Te.createRef();nameInput=Te.createRef();valueInput=Te.createRef();render=()=>{const[e,s]=this.props.item;return o.jsxs("div",{ref:this.container,className:"kv-row",onClick:this.onClick,onKeyDownCapture:this.onKeyDown,children:[o.jsx(ce,{ref:this.nameInput,className:"kv-key",content:e,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([i,s]),selectAllOnClick:!0}),": ",o.jsx(ce,{ref:this.valueInput,className:"kv-value",content:s,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([e,i]),placeholder:"empty",selectAllOnClick:!0})]})};onClick=e=>{e.target===this.container.current&&this.props.onClickEmptyArea()};onKeyDown=e=>{e.target===this.valueInput.current?.input.current&&e.key==="Tab"&&this.props.onTabNext()}}class Rr extends I.Component{rowRefs={};currentlyEditing;justFinishedEditing;state={currentList:this.props.data||[],initialList:this.props.data};static getDerivedStateFromProps(e,s){return e.data!==s.initialList?{currentList:e.data||[],initialList:e.data}:null}render=()=>{this.rowRefs={};const e=this.state.currentList.map((s,i)=>o.jsx(Sa,{item:s,onEditStart:()=>this.currentlyEditing=i,onEditDone:r=>this.onEditDone(i,r),onClickEmptyArea:()=>this.onClickEmptyArea(i),onTabNext:()=>this.onTabNext(i),ref:r=>{this.rowRefs[i]=r}},i));return o.jsxs("div",{className:je("kv-editor",this.props.className),onMouseDown:this.onMouseDown,children:[e,o.jsx("div",{onClick:s=>{s.preventDefault(),this.onClickEmptyArea(this.state.currentList.length-1)},className:"kv-add-row fa fa-plus-square-o",role:"button","aria-label":"Add"})]})};onEditDone=(e,s)=>{const i=[...this.state.currentList];s[0]?i[e]=s:i.splice(e,1),this.currentlyEditing=void 0,Ht.isEqual(this.state.currentList,i)||this.props.onChange(i),this.setState({currentList:i})};onClickEmptyArea=e=>{if(this.justFinishedEditing)return;const s=[...this.state.currentList];s.splice(e+1,0,["",""]),this.setState({currentList:s},()=>this.rowRefs[e+1]?.nameInput.current?.startEditing())};onTabNext=e=>{e==this.state.currentList.length-1&&this.onClickEmptyArea(e)};onMouseDown=e=>{this.justFinishedEditing=this.currentlyEditing}}function Ar(t,e){const s=k.c(6),[i,r]=I.useState(),[n,l]=I.useState();let a;s[0]!==n||s[1]!==t?(a=()=>{n&&n.abort();const f=new AbortController;return ne(t,{signal:f.signal}).then($a).then(p=>{r(p)}).catch(p=>{f.signal.aborted||r(`Error getting content: ${p}.`)}),l(f),()=>{f.signal.aborted||f.abort()}},s[0]=n,s[1]=t,s[2]=a):a=s[2];let d;return s[3]!==e||s[4]!==t?(d=[t,e],s[3]=e,s[4]=t,s[5]=d):d=s[5],I.useEffect(a,d),i}function $a(t){if(!t.ok)throw`${t.status} ${t.statusText}`.trim();return t.text()}function Dr(t,e,s,i,r){const n=k.c(11);let l;n[0]!==t||n[1]!==i||n[2]!==e||n[3]!==s?(l=we.getContentURL(t,e,s,i),n[0]=t,n[1]=i,n[2]=e,n[3]=s,n[4]=l):l=n[4];const d=Ar(l,r);let f;if(d)try{let p;n[5]!==d?(p=JSON.parse(d),n[5]=d,n[6]=p):p=n[6],f=p}catch{let p;n[7]!==d?(p={text:d,description:"Network Error",syntax_highlight:"error",view_name:"raw"},n[7]=d,n[8]=p):p=n[8];const h=p;if(e==="messages"){let g;n[9]!==h?(g=[h],n[9]=h,n[10]=g):g=n[10],f=g}else f=h}else f=void 0;return f}const Fr=Te.memo(function({icon:e,text:s,className:i,title:r,onOpenFile:n,onClick:l}){let a;return o.jsxs("a",{href:"#",onClick:d=>{a.click(),l&&l(d)},className:i,title:r,children:[o.jsx("i",{className:"fa fa-fw "+e}),s,o.jsx("input",{ref:d=>{a=d},className:"hidden",type:"file",onChange:d=>{d.preventDefault(),d.target.files&&d.target.files.length>0&&n(d.target.files[0]),a.value=""}})]})});function pe(t){const e=k.c(11),{onClick:s,children:i,icon:r,disabled:n,className:l,title:a}=t;let d;e[0]!==l?(d=je(l,"btn btn-default"),e[0]=l,e[1]=d):d=e[1];const f=n?void 0:s;let p;e[2]!==r?(p=r&&o.jsxs(o.Fragment,{children:[o.jsx("i",{className:"fa "+r})," "]}),e[2]=r,e[3]=p):p=e[3];let h;return e[4]!==i||e[5]!==n||e[6]!==d||e[7]!==f||e[8]!==p||e[9]!==a?(h=o.jsxs("button",{className:d,onClick:f,disabled:n,title:a,children:[p,i]}),e[4]=i,e[5]=n,e[6]=d,e[7]=f,e[8]=p,e[9]=a,e[10]=h):h=e[10],h}function Ca(t){const e=k.c(11),{initialContent:s,onChange:i,language:r,readonly:n}=t,l=n===void 0?!1:n,a=Na;let d;e:switch(r){case ot.YAML:{let h;e[0]===Symbol.for("react.memo_cache_sentinel")?(h=[Dl()],e[0]=h):h=e[0],d=h;break e}case ot.XML:{let h;e[1]===Symbol.for("react.memo_cache_sentinel")?(h=[Al()],e[1]=h):h=e[1],d=h;break e}case ot.JAVASCRIPT:{let h;e[2]===Symbol.for("react.memo_cache_sentinel")?(h=[Rl()],e[2]=h):h=e[2],d=h;break e}case ot.CSS:{let h;e[3]===Symbol.for("react.memo_cache_sentinel")?(h=[Tl()],e[3]=h):h=e[3],d=h;break e}case void 0:case null:case ot.NONE:case ot.ERROR:{let h;e[4]===Symbol.for("react.memo_cache_sentinel")?(h=[],e[4]=h):h=e[4],d=h;break e}default:{console.error("Unexpected syntax highlighting language: ",r);let g;e[5]===Symbol.for("react.memo_cache_sentinel")?(g=[],e[5]=g):g=e[5],d=g}}const f=d;let p;return e[6]!==f||e[7]!==s||e[8]!==i||e[9]!==l?(p=o.jsx("div",{className:"codeeditor",onKeyDown:a,children:o.jsx(Fl,{value:s,onChange:i,readOnly:l,extensions:f})}),e[6]=f,e[7]=s,e[8]=i,e[9]=l,e[10]=p):p=e[10],p}function Na(t){return t.stopPropagation()}const Ir=Te.memo(function(e){const s=k.c(9),{content:i,maxLines:r,showMore:n}=e;if(i.length===0)return null;let l;if(s[0]!==i||s[1]!==r||s[2]!==n){let d;s[4]!==r||s[5]!==n?(d=(f,p)=>p===r?o.jsxs("button",{onClick:n,className:"btn btn-xs btn-info",children:[o.jsx("i",{className:"fa fa-angle-double-down","aria-hidden":"true"})," ","Show more"]},"showmore"):o.jsx("div",{children:f},p),s[4]=r,s[5]=n,s[6]=d):d=s[6],l=i.split(`
+import{c as fe,R as Cl,a as _e,r as I,b as Te,d as je,j as o,e as k,f as ui,u as Nl,g as kl,h as fi,s as Kt,i as El,l as Ht,k as Tl,m as Rl,n as Al,y as Dl,o as Fl,p as Il,q as zt,Q as Ll,t as Pl,P as Ol}from"./vendor-BS4xPthR.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))i(r);new MutationObserver(r=>{for(const n of r)if(n.type==="childList")for(const l of n.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&i(l)}).observe(document,{childList:!0,subtree:!0});function s(r){const n={};return r.integrity&&(n.integrity=r.integrity),r.referrerPolicy&&(n.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?n.credentials="include":r.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function i(r){if(r.ep)return;r.ep=!0;const n=s(r);fetch(r.href,n)}})();const Ml={tab:"request",contentViewFor:{}},ql=fe({name:"ui/flow",initialState:Ml,reducers:{selectTab(t,e){t.tab=e.payload},setContentViewFor(t,e){t.contentViewFor[e.payload.messageId]=e.payload.contentView}}}),{actions:Hl,reducer:Vl}=ql,{selectTab:Ut,setContentViewFor:pi}=Hl;window.React=Cl;const hi=function(t){if(t===0)return"0";const e=["b","kb","mb","gb","tb"];let s=0;for(;st);s++);let i;return t%Math.pow(1024,s)===0?i=0:i=1,(t/Math.pow(1024,s)).toFixed(i)+e[s]},mi=function(t){let e=t;const s=["ms","s","min","h"],i=[1e3,60,60];let r=0;for(;Math.abs(e)>=i[r]&&r{const t=Ul("_mitmproxy_xsrf");return fs=()=>t,fs()};function ne(t,e={}){return e.method&&e.method!=="GET"&&(e.headers=e.headers||{},e.headers["X-XSRFToken"]=fs()),t.startsWith("/")&&(t="."+t),fetch(t,{credentials:"same-origin",...e})}ne.put=(t,e,s={})=>ne(t,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});ne.post=(t,e,s={})=>ne(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});async function Bt(t,...e){return await(await ne(`/commands/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({arguments:e})})).json()}async function gi(t){try{await navigator.clipboard.write([new ClipboardItem({"text/plain":t})]);return}catch(i){console.warn(i)}const e=await t;try{await navigator.clipboard.writeText(e);return}catch(i){console.warn(i)}const s=document.createElement("textarea");s.value=e,s.style.position="absolute",s.style.opacity="0",document.body.appendChild(s);try{if(s.focus(),s.select(),!document.execCommand("copy"))throw"failed to copy"}catch{alert(e)}finally{s.remove()}}async function Bl(t){await gi(Promise.resolve(t?.text||""))}function ps(t,e){const s=t.lastIndexOf(e);if(s===-1)return["",t];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function vi(t,e){const s=t.indexOf(e);if(s===-1)return[t,""];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function Ct(t){throw new Error(`Unreachable: ${JSON.stringify(t)}`)}const xi={http:80,https:443},Vn=new WeakMap;class we{static getContentType(e){const s=we.get_first_header(e,/^Content-Type$/i);if(s)return s.split(";")[0].trim()}static get_first_header(e,s){let i=Vn.get(e);i||(i=new Map,Vn.set(e,i));let r=i.get(s);if(r===void 0){const n=e.headers.find(([l,a])=>s.test(l));r=n?n[1]:!1,i.set(s,r)}return r!==!1?r:void 0}static match_header(e,s){const i=e.headers;if(!i)return!1;let r=i.length;for(;r--;)if(s.test(i[r].join(" ")))return i[r];return!1}static getContentURL(e,s,i,r){e.type==="http"&&s===e.request?s="request":e.type==="http"&&s===e.response&&(s="response");const n=r?`?lines=${r}`:"";return`./flows/${e.id}/${s}/`+(i?`content/${encodeURIComponent(i)}.json${n}`:"content.data")}}class ct extends we{static pretty_url(e){let s="";return xi[e.scheme]!==e.port&&(s=":"+e.port),e.scheme+"://"+e.pretty_host+s+e.path}}class mt extends we{}const Wl=/^(?:(https?):\/\/)?([^/:]+)?(?::(\d+))?(\/.*)?$/i,_i=function(t){const e=Wl.exec(t);if(!e)return;const s=e[1],i=e[2],r=parseInt(e[3]),n=e[4],l=s?r||xi[s]:r,a={};return s&&(a.scheme=s),i&&(a.host=i),l&&(a.port=l),n&&(a.path=n),a},Kl=/^HTTP\/\d+(\.\d+)*$/i,ji=function(t){return Kl.test(t)};function Wt(t){switch(t.type){case"http":return t.request.timestamp_start;case"tcp":case"udp":return t.client_conn.timestamp_start;case"dns":return t.request.timestamp}}function yi(t){switch(t.type){case"http":if(t.websocket){if(t.websocket.timestamp_end)return t.websocket.timestamp_end;if(t.websocket.messages_meta.timestamp_last)return t.websocket.messages_meta.timestamp_last}return t.response?t.response.timestamp_end:void 0;case"tcp":return t.server_conn?.timestamp_end;case"udp":return t.messages_meta.timestamp_last;case"dns":return t.response?.timestamp}}const wi=t=>{switch(t.type){case"http":{let e=t.request.contentLength||0;return t.response&&(e+=t.response.contentLength||0),t.websocket&&(e+=t.websocket.messages_meta.contentLength||0),e}case"tcp":case"udp":return t.messages_meta.contentLength||0;case"dns":return t.response?.size??0}},xs=t=>t.type==="http"&&!t.websocket,bi=t=>t.modified,_s=t=>t.intercepted,Si=t=>{if(t.type!=="http")return t.client_conn.tls_version==="QUICv1"?"resource-icon-quic":`resource-icon-${t.type}`;if(t.websocket)return"resource-icon-websocket";if(!t.response)return"resource-icon-plain";const e=mt.getContentType(t.response)||"";return t.response.status_code===304?"resource-icon-not-modified":300<=t.response.status_code&&t.response.status_code<400?"resource-icon-redirect":e.indexOf("image")>=0?"resource-icon-image":e.indexOf("javascript")>=0?"resource-icon-js":e.indexOf("css")>=0?"resource-icon-css":e.indexOf("html")>=0?"resource-icon-document":"resource-icon-plain"},$i=t=>{switch(t.type){case"http":return ct.pretty_url(t.request);case"tcp":case"udp":return`${t.client_conn.peername.join(":")} ↔ ${t.server_conn?.address?.join(":")}`;case"dns":return`${t.request.questions.map(e=>`${e.name} ${e.type}`).join(", ")} = ${(t.response?.answers.map(e=>e.data).join(", ")??"...")||"?"}`}},Ci=t=>{switch(t.type){case"http":return t.response?.status_code;case"dns":return t.response?.response_code;default:return}},Ni=t=>{switch(t.type){case"http":return t.websocket?t.client_conn.tls_established?"WSS":"WS":t.request.method;case"dns":return t.request.op_code;default:return t.type.toUpperCase()}},ki=t=>{switch(t.type){case"http":return t.request.http_version;default:return""}},Ei={tls:t=>t.type==="http"&&t.request.scheme,icon:Si,index:()=>0,path:$i,method:Ni,version:ki,status:Ci,size:wi,time:t=>{const e=Wt(t),s=yi(t);return e&&s&&s-e},timestamp:Wt,quickactions:()=>0,comment:t=>t.comment};function zl(t){return t in Ei}var ve=(t=>(t.Search="search",t.Highlight="highlight",t))(ve||{});const Ti={search:"",highlight:""},Gl=fe({name:"ui/filters",initialState:Ti,reducers:{setFilter(t,e){t.search=e.payload},setHighlight(t,e){t.highlight=e.payload}}}),{actions:Yl,reducer:Jl}=Gl,{setFilter:Ri,setHighlight:Ai}=Yl;function rs(t,e){return t.toSorted?t.toSorted(e):[...t].sort(e)}function js(t,...e){if(t.toSpliced)return t.toSpliced(...e);{const s=[...t];return s.splice(...e),s}}function jt(t){return new Map(t.map((e,s)=>[e.id,s]))}function os(t){return new Set(t.map(e=>e.id))}function Un(t,e){return t.has(e)&&(t=new Set(t),t.delete(e)),t}function Bn(t,e,s){const i=js(t,s,1),r=new Map(e);r.delete(t[s].id);for(let n=i.length-1;n>=s;n--)r.set(i[n].id,n);return{view:i,_viewIndex:r}}function Ql(t,e,s,i){const r=[...t],n=r.length;let l=e,a=l.get(s.id);if(a+10){l=new Map(l);do{const d=r[a+1];r[a]=d,l.set(d.id,a),a++}while(a+10);l.set(s.id,a)}else if(a>0&&i(s,r[a-1])<0){l=new Map(l);do{const d=r[a-1];r[a]=d,l.set(d.id,a),a--}while(a>0&&i(s,r[a-1])<0);l.set(s.id,a)}return r[a]=s,{view:r,_viewIndex:l}}function Wn(t,e,s,i){const r=Xl(t,s,i),n=js(t,r,0,s),l=new Map(e);for(let a=n.length-1;a>=r;a--)l.set(n[a].id,a);return{view:n,_viewIndex:l}}function Xl(t,e,s){let i=0,r=t.length;if(r===0||s(t[r-1],e)<=0)return r;for(;i>>1;s(e,t[n])>=0?i=n+1:r=n}return i}function ys(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/resume`,{method:"POST"})))}function Di(){return()=>ne("/flows/resume",{method:"POST"})}function Fi(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/kill`,{method:"POST"})))}function Zl(){return()=>ne("/flows/kill",{method:"POST"})}function Ii(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}`,{method:"DELETE"})))}function Li(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/duplicate`,{method:"POST"})))}function ws(t){return t=t.filter(xs),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/replay`,{method:"POST"})))}function Pi(t){return t=t.filter(bi),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/revert`,{method:"POST"})))}function Kn(t,e){return()=>Promise.all(t.map(s=>Le(s,{marked:e})()))}function Le(t,e){return()=>ne.put(`/flows/${t.id}`,e)}function ec(t,e,s){const i=new FormData;return e=new window.Blob([e],{type:"plain/text"}),i.append("file",e),()=>ne(`/flows/${t.id}/${s}/content.data`,{method:"POST",body:i})}function Oi(){return()=>ne("/clear",{method:"POST"})}function tc(t){const e=new FormData;return e.append("file",t),()=>ne("/flows/dump",{method:"POST",body:e})}const Mi=_e("flows/add"),qi=_e("flows/update"),Hi=_e("flows/remove"),bs=_e("flows/receive"),Vi=_e("flows/filterUpdate"),Ui=_e("flows/sort"),Ve=_e("flows/select"),sc={list:[],_listIndex:new Map,byId:new Map,view:[],_viewIndex:new Map,sort:{column:void 0,desc:!1},selected:[],selectedIds:new Set,highlightedIds:new Set};function nc(t=sc,e){if(bs.match(e)){const{sort:s}=t,i=e.payload,r=jt(i),n=new Map(i.map(h=>[h.id,h])),l=rs(i,pt(s)),a=jt(l),d=t.selected.map(h=>n.get(h.id)).filter(h=>h!==void 0),f=os(d);return{list:i,_listIndex:r,byId:n,view:l,_viewIndex:a,sort:s,selected:d,selectedIds:f,highlightedIds:new Set}}else if(Mi.match(e)){const{flow:s,matching_filters:i}=e.payload;if(t._listIndex.has(s.id))return t;const{sort:r,selected:n,selectedIds:l}=t;let{view:a,_viewIndex:d,highlightedIds:f}=t;const p=new Map(t._listIndex);p.set(s.id,t.list.length);const h=[...t.list,s],g=new Map(t.byId);return g.set(s.id,s),(i[ve.Search]===!0||i[ve.Search]===void 0)&&({view:a,_viewIndex:d}=Wn(a,d,s,pt(r))),i[ve.Highlight]===!0&&(f=new Set(f),f.add(s.id)),{list:h,_listIndex:p,byId:g,view:a,_viewIndex:d,sort:r,selected:n,selectedIds:l,highlightedIds:f}}else if(qi.match(e)){const{flow:s,matching_filters:i}=e.payload,{_listIndex:r,sort:n,selectedIds:l}=t;let{view:a,_viewIndex:d,selected:f,highlightedIds:p}=t;const h=t._listIndex.get(s.id),g=[...t.list];h!==void 0?g[h]=s:g.push(s);const _=new Map(t.byId);_.set(s.id,s);const j=d.get(s.id),y=j!==void 0,w=i[ve.Search]===!0||i[ve.Search]===void 0;return w&&!y?{view:a,_viewIndex:d}=Wn(a,d,s,pt(n)):!w&&y?{view:a,_viewIndex:d}=Bn(a,d,j):w&&y&&({view:a,_viewIndex:d}=Ql(a,d,s,pt(n))),l.has(s.id)&&(f=f.map($=>$.id===s.id?s:$)),i[ve.Highlight]===!0?p.has(s.id)||(p=new Set(p),p.add(s.id)):p=Un(p,s.id),{list:g,_listIndex:r,byId:_,view:a,_viewIndex:d,sort:n,selected:f,selectedIds:l,highlightedIds:p}}else if(Hi.match(e)){const s=e.payload,{sort:i}=t;let{view:r,_viewIndex:n,selected:l,selectedIds:a}=t;const d=t._listIndex.get(s);if(d===void 0)return t;const f=js(t.list,d,1),p=jt(f),h=new Map(t.byId);h.delete(s);const g=n.get(s);if(g!==void 0&&({view:r,_viewIndex:n}=Bn(r,n,g)),a.has(s)){if(l.length===1&&g!==void 0){const j=r[g]??r[g-1];l=j?[j]:[]}else l=l.filter(j=>j.id!==s);a=os(l)}const _=Un(t.highlightedIds,s);return{list:f,_listIndex:p,byId:h,view:r,_viewIndex:n,sort:i,selected:l,selectedIds:a,highlightedIds:_}}else if(Vi.match(e)){const{name:s,matching_flow_ids:i}=e.payload;switch(s){case ve.Search:{const r=rs(i===null?t.list:i.map(l=>t.byId.get(l)).filter(l=>l!==void 0),pt(t.sort)),n=jt(r);return{...t,view:r,_viewIndex:n}}case ve.Highlight:return{...t,highlightedIds:new Set(i)};default:Ct(s)}}else if(Ui.match(e)){const s=e.payload;let i;s.column?i=rs(t.view,pt(s)):i=t.list.filter(n=>t._viewIndex.has(n.id));const r=jt(i);return{...t,sort:s,view:i,_viewIndex:r}}else return Ve.match(e)?{...t,selected:e.payload,selectedIds:os(e.payload)}:t}function pt({column:t,desc:e}){if(!t)return(i,r)=>0;const s=Ei[t];return(i,r)=>{const n=s(i),l=s(r);return n>l?e?-1:1:n{const{flows:i}=s();i.selectedIds.has(t.id)?e(Ve(i.selected.filter(r=>r!==t))):e(Ve([...i.selected,t]))}}function rc(t){return(e,s)=>{const{flows:i}=s(),r=i.selected[i.selected.length-1],n=i._viewIndex.get(t.id),l=i._viewIndex.get(r?.id);if(n===void 0||l===void 0)return e(Ve([t]));let a;return n<=l?a=i.view.slice(n,l+1):(a=i.view.slice(l+1,n+1),a.push(r)),e(Ve(a))}}const oc={activeModal:void 0},Bi=fe({name:"ui/modal",initialState:oc,reducers:{setActiveModal(t,e){t.activeModal=e.payload},hideModal(t){t.activeModal=void 0}}}),{actions:lc,reducer:cc}=Bi,ac=Bi.actions.hideModal.type,{setActiveModal:dc,hideModal:Wi}=lc,zn=(()=>{const t=document.createElement("div");return t.setAttribute("contenteditable","PLAINTEXT-ONLY"),t.contentEditable==="plaintext-only"?"plaintext-only":"true"})();class ce extends I.Component{input=Te.createRef();render(){const e=je("inline-input",this.props.className);return o.jsx("span",{ref:this.input,tabIndex:0,className:e,placeholder:this.props.placeholder,onFocus:this.onFocus,onBlur:this.onBlur,onKeyDown:this.onKeyDown,onInput:this.onInput,onPaste:this.onPaste,onMouseDown:this.onMouseDown,onClick:this.onClick,children:this.props.content})}componentDidUpdate(e){e.content!==this.props.content&&this.props.onInput?.(this.props.content)}isEditing=()=>this.input.current?.contentEditable===zn;startEditing=()=>{if(!this.input.current)return console.error("unreachable");this.isEditing()||(this.suppress_events=!0,this.input.current.blur(),this.input.current.contentEditable=zn,window.requestAnimationFrame(()=>{if(this.input.current){if(this.input.current.focus(),this.suppress_events=!1,this.props.selectAllOnClick){const e=document.createRange();e.selectNodeContents(this.input.current);const s=window.getSelection();s?.removeAllRanges(),s?.addRange(e)}this.props.onEditStart?.()}}))};resetValue=()=>{if(!this.input.current)return console.error("unreachable");this.input.current.textContent=this.props.content,this.props.onInput?.(this.props.content)};finishEditing=()=>{if(!this.input.current)return console.error("unreachable");this.props.onEditDone(this.input.current.textContent||""),this.input.current.blur(),this.input.current.contentEditable="inherit"};onPaste=e=>{e.preventDefault();const s=e.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,s)};suppress_events=!1;onMouseDown=e=>{this.suppress_events=!0,window.addEventListener("mouseup",this.onMouseUp,{once:!0})};onMouseUp=e=>{const s=e.target===this.input.current,i=!window.getSelection()?.toString();this.props.selectAllOnClick?s&&i&&this.startEditing():s&&this.startEditing(),this.suppress_events=!1};onClick=e=>{};onFocus=e=>{if(!this.input.current)throw"unreachable";this.suppress_events||this.startEditing()};onInput=e=>{this.props.onInput?.(this.input.current?.textContent||"")};onBlur=e=>{this.suppress_events||this.finishEditing()};onKeyDown=e=>{switch(e.stopPropagation(),e.key){case"Escape":e.preventDefault(),this.resetValue(),this.finishEditing();break;case"Enter":e.shiftKey||(e.preventDefault(),this.finishEditing());break}this.props.onKeyDown?.(e)}}function bt(t){const e=k.c(15);let s;e[0]!==t.content||e[1]!==t.isValid?(s=t.isValid(t.content),e[0]=t.content,e[1]=t.isValid,e[2]=s):s=e[2];const[i,r]=I.useState(s),n=I.useRef(null);let l;e[3]!==t?(l=_=>{t.isValid(_)?t.onEditDone(_):n.current?.resetValue()},e[3]=t,e[4]=l):l=e[4];const a=l,d=i?"has-success":"has-warning";let f;e[5]!==t.className||e[6]!==d?(f=je(t.className,d),e[5]=t.className,e[6]=d,e[7]=f):f=e[7];const p=f;let h;e[8]!==t?(h=_=>r(t.isValid(_)),e[8]=t,e[9]=h):h=e[9];let g;return e[10]!==p||e[11]!==a||e[12]!==t||e[13]!==h?(g=o.jsx(ce,{...t,className:p,onInput:h,onEditDone:a,ref:n}),e[10]=p,e[11]=a,e[12]=t,e[13]=h,e[14]=g):g=e[14],g}const G=()=>Nl(),D=kl,uc=ui.withTypes(),Ss=_e("EVENTS_ADD"),Ki=_e("EVENTS_RECEIVE"),Gt=_e("events/toggleVisibility"),zi=_e("events/toggleFilter");var Gi=(t=>(t.debug="debug",t.info="info",t.web="web",t.warn="warn",t.error="error",t))(Gi||{});const fc={visible:!1,filters:{debug:!1,info:!0,web:!0,warn:!0,error:!0},list:[],view:[]};function pc(t=fc,e){if(Ss.match(e)){const s=e.payload;return{...t,list:[...t.list,s],view:t.filters[s.level]?[...t.view,s]:t.view}}else{if(Ki.match(e))return{...t,list:e.payload,view:e.payload.filter(s=>t.filters[s.level])};if(Gt.match(e))return{...t,visible:!t.visible};if(zi.match(e)){const s={...t.filters,[e.payload]:!t.filters[e.payload]};return{...t,filters:s,view:t.list.filter(i=>s[i.level])}}else return t}}function hc(t,e="web"){return Ss({id:Math.random().toString(),message:t,level:e})}const Gn={},mc=fe({name:"ui/optionsEditor",initialState:Gn,reducers:{startUpdate(t,e){t[e.payload.option]={isUpdating:!0,value:e.payload.value,error:!1}},updateSuccess(t,e){t[e.payload.option]=void 0},updateError(t,e){let s=t[e.payload.option].value;typeof s=="boolean"&&(s=!s),t[e.payload.option]={value:s,isUpdating:!1,error:e.payload.error}}},extraReducers:t=>{t.addCase(ac,()=>Gn)}}),{actions:gc,reducer:vc}=mc,{startUpdate:xc,updateSuccess:_c,updateError:jc}=gc;var xe=(t=>(t[t.Capture=0]="Capture",t[t.FlowList=1]="FlowList",t[t.Options=2]="Options",t[t.Flow=3]="Flow",t))(xe||{});const yc=fe({name:"ui/tabs",initialState:{current:1},reducers:{setCurrent(t,e){t.current=e.payload}}}),{actions:wc,reducer:bc}=yc,{setCurrent:Vt}=wc,Sc=fi({flow:Vl,modal:cc,optionsEditor:vc,tabs:bc,filter:Jl});var wt=(t=>(t.INIT="CONNECTION_INIT",t.FETCHING="CONNECTION_FETCHING",t.ESTABLISHED="CONNECTION_ESTABLISHED",t.ERROR="CONNECTION_ERROR",t))(wt||{});const $c={state:"CONNECTION_INIT",message:void 0},Yi=fe({name:"connection",initialState:$c,reducers:{startFetching:t=>{t.state==="CONNECTION_INIT"&&(t.state="CONNECTION_FETCHING")},finishFetching:t=>{t.state==="CONNECTION_FETCHING"&&(t.state="CONNECTION_ESTABLISHED")},connectionError:(t,e)=>{t.state="CONNECTION_ERROR",t.message=e.payload}}}),{startFetching:Cc,finishFetching:Nc,connectionError:kc}=Yi.actions,Ec=Yi.reducer,Tc={add_upstream_certs_to_client_chain:!1,allow_hosts:[],anticache:!1,anticomp:!1,block_global:!0,block_list:[],block_private:!1,body_size_limit:void 0,cert_passphrase:void 0,certs:[],ciphers_client:void 0,ciphers_server:void 0,client_certs:void 0,client_replay:[],client_replay_concurrency:1,command_history:!0,confdir:"~/.mitmproxy",connect_addr:void 0,connection_strategy:"eager",console_focus_follow:!1,content_view_lines_cutoff:512,dns_name_servers:[],dns_use_hosts_file:!0,export_preserve_original_ip:!1,hardump:"",http2:!0,http2_ping_keepalive:58,http3:!0,http_connect_send_host_header:!0,ignore_hosts:[],intercept:void 0,intercept_active:!1,keep_alt_svc_header:!1,keep_host_header:!1,key_size:2048,listen_host:"",listen_port:void 0,map_local:[],map_remote:[],mode:["regular"],modify_body:[],modify_headers:[],normalize_outbound_headers:!0,onboarding:!0,onboarding_host:"mitm.it",protobuf_definitions:void 0,proxy_debug:!1,proxyauth:void 0,rawtcp:!0,readfile_filter:void 0,request_client_cert:!1,rfile:void 0,save_stream_file:void 0,save_stream_filter:void 0,scripts:[],server:!0,server_replay:[],server_replay_extra:"forward",server_replay_ignore_content:!1,server_replay_ignore_host:!1,server_replay_ignore_params:[],server_replay_ignore_payload_params:[],server_replay_ignore_port:!1,server_replay_kill_extra:!1,server_replay_nopop:!1,server_replay_refresh:!0,server_replay_reuse:!1,server_replay_use_headers:[],show_ignored_hosts:!1,showhost:!1,ssl_insecure:!1,ssl_verify_upstream_trusted_ca:void 0,ssl_verify_upstream_trusted_confdir:void 0,stickyauth:void 0,stickycookie:void 0,store_streamed_bodies:!1,stream_large_bodies:void 0,strip_ech:!0,tcp_hosts:[],tcp_timeout:600,termlog_verbosity:"info",tls_ecdh_curve_client:void 0,tls_ecdh_curve_server:void 0,tls_version_client_max:"UNBOUNDED",tls_version_client_min:"TLS1_2",tls_version_server_max:"UNBOUNDED",tls_version_server_min:"TLS1_2",udp_hosts:[],upstream_auth:void 0,upstream_cert:!0,validate_inbound_headers:!0,view_filter:void 0,view_order:"time",view_order_reversed:!1,web_columns:["tls","icon","path","method","status","size","time"],web_debug:!1,web_host:"127.0.0.1",web_open_browser:!0,web_password:"",web_port:8081,web_static_viewer:"",websocket:!0},Yt=_e("OPTIONS_RECEIVE"),$s=_e("OPTIONS_UPDATE"),Rc=fe({name:"options",initialState:Tc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>{const i={};for(const[r,{value:n}]of Object.entries(s.payload))i[r]=n;return i}).addCase($s,(e,s)=>{for(const[i,{value:r}]of Object.entries(s.payload))e[i]=r})}}),Ac=Rc.reducer;async function Dc(t,e,s){try{const i=await ne.put("/options",{[t]:e});if(i.status===200)s(_c({option:t}));else throw await i.text()}catch(i){s(jc({option:t,error:i.toString()}))}}const Fc=Dc;function Cs(t,e){return s=>{s(xc({option:t,value:e})),Fc(t,e,s)}}const Ic={visible:!1},Lc=fe({name:"commandBar",initialState:Ic,reducers:{toggleVisibility(t){t.visible=!t.visible}}}),{actions:Pc,reducer:Oc}=Lc,{toggleVisibility:Ji}=Pc,Ue=_e("STATE_RECEIVE"),Be=_e("STATE_UPDATE"),Mc={available:!1,version:"",contentViews:[],servers:{},platform:"",localModeUnavailable:null},qc=fe({name:"backendState",initialState:Mc,reducers:{},extraReducers:t=>{t.addCase(Ue,(e,s)=>({...e,available:!0,...s.payload})).addCase(Be,(e,s)=>({...e,...s.payload}))}}),Hc=qc.reducer,Vc={},Uc=fe({name:"optionsMeta",initialState:Vc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>s.payload).addCase($s,(e,s)=>({...e,...s.payload}))}}),Bc=Uc.reducer,dt=(t,e)=>e.listen_host&&e.listen_port?`${t}@${e.listen_host}:${e.listen_port}`:e.listen_port?`${t}@${e.listen_port}`:t,Qi=t=>{let[e,s]=ps(t,"@");e||(e=s,s="");const[i,r]=vi(e,":");let n,l;if(s){let a;if(s.includes(":")?[n,a]=ps(s,":"):(n="",a=s),a&&(l=parseInt(a,10),isNaN(l)||l<0||l>65535))throw new Error(`invalid port: ${a}`)}return{full_spec:t,name:i,data:r,listen_host:n,listen_port:l}},Xi=t=>dt("regular",t),Yn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Zi=t=>t.selectedProcesses?`local:${t.selectedProcesses}`:"local",Jn=({data:t})=>({ui_id:Math.random(),active:!0,selectedProcesses:t}),er=t=>{const e=t.file_path?`wireguard:${t.file_path}`:"wireguard";return dt(e,t)},Qn=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,listen_host:e,listen_port:s,file_path:t});var Jt=(t=>(t.HTTP="http",t.HTTPS="https",t.HTTP3="http3",t.TLS="tls",t.DTLS="dtls",t.TCP="tcp",t.UDP="udp",t.DNS="dns",t.QUIC="quic",t))(Jt||{}),ot=(t=>(t.CSS="css",t.JAVASCRIPT="javascript",t.XML="xml",t.YAML="yaml",t.NONE="none",t.ERROR="error",t))(ot||{});const hs=()=>({active:!1,protocol:Jt.HTTPS,destination:"",ui_id:Math.random()}),Ns=t=>dt(`reverse:${t.protocol}://${t.destination}`,t),Wc=({data:t,listen_host:e,listen_port:s})=>{let[i,r]=vi(t,"://");return r||(r=i,i=Jt.HTTPS),{ui_id:Math.random(),active:!0,protocol:i,destination:r,listen_host:e,listen_port:s}},tr=t=>dt("transparent",t),Xn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),sr=t=>dt("socks5",t),Zn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),nr=t=>dt(`upstream:${t.destination}`,t),ei=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,destination:t||"",listen_host:e,listen_port:s}),ir=t=>dt("dns",t),ti=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Xe=t=>t.active&&!t.error;async function Kc(t,e){const s=e.getState().modes,i=[...s.regular.filter(Xe).map(Xi),...s.local.filter(Xe).map(Zi),...s.wireguard.filter(Xe).map(er),...s.reverse.filter(Xe).map(Ns),...s.transparent.filter(Xe).map(tr),...s.socks.filter(Xe).map(sr),...s.upstream.filter(Xe).map(nr),...s.dns.filter(Xe).map(ir)],r=await ne.put("/options",{mode:i});if(r.status!==200)throw new Error(await r.text())}function ie(t){return uc(t,Kc)}function se(t,e,s){t.addCase(s.pending,(i,r)=>{const{server:n,value:l}=r.meta.arg,a=i.findIndex(d=>d.ui_id===n.ui_id);a>=0&&(i[a][e]=l,i[a].error=void 0)}),t.addCase(s.rejected,(i,r)=>{const{server:n}=r.meta.arg,l=i.findIndex(a=>a.ui_id===n.ui_id);l>=0&&(i[l].error=r.error.message)})}function be(t,e){return function(i,r){if(r.payload.servers){const n=Object.values(r.payload.servers).filter(l=>l.type===t).map(l=>Qi(l.full_spec));if(n.length>0)return n.map(e);for(const l of i)l.active=!1}}}const rr=ie("modes/regular/setActive"),or=ie("modes/regular/setListenHost"),lr=ie("modes/regular/setListenPort"),zc=[{active:!0,ui_id:Math.random()}],Gc=fe({name:"modes/regular",initialState:zc,reducers:{},extraReducers:t=>{se(t,"active",rr),se(t,"listen_host",or),se(t,"listen_port",lr),t.addCase(Ue,be("regular",Yn)),t.addCase(Be,be("regular",Yn))}}),Yc=Gc.reducer,cr=ie("modes/local/setActive"),St=ie("modes/local/setSelectedProcesses"),Jc=[{active:!1,selectedProcesses:"",ui_id:Math.random()}],Qc=fe({name:"modes/local",initialState:Jc,reducers:{},extraReducers:t=>{se(t,"active",cr),se(t,"selectedProcesses",St),t.addCase(Ue,be("local",Jn)),t.addCase(Be,be("local",Jn))}}),Xc=Qc.reducer,ar=ie("modes/wireguard/setActive"),dr=ie("modes/wireguard/setListenHost"),ur=ie("modes/wireguard/setListenPort"),fr=ie("modes/wireguard/setFilePath"),Zc=[{active:!1,ui_id:Math.random()}],ea=fe({name:"modes/wireguard",initialState:Zc,reducers:{},extraReducers:t=>{se(t,"active",ar),se(t,"listen_host",dr),se(t,"listen_port",ur),se(t,"file_path",fr),t.addCase(Ue,be("wireguard",Qn)),t.addCase(Be,be("wireguard",Qn))}}),ta=ea.reducer,ms=ie("modes/reverse/setActive"),pr=ie("modes/reverse/setListenHost"),hr=ie("modes/reverse/setListenPort"),mr=ie("modes/reverse/setProtocol"),gr=ie("modes/reverse/setDestination"),sa=[hs()],vr=fe({name:"modes/reverse",initialState:sa,reducers:{addServer:t=>{t.push(hs())},removeServer:(t,e)=>{const s=t.findIndex(i=>i.ui_id===e.payload.ui_id);s!==-1&&(t[s].active&&console.error("servers should be deactivated before removal"),t.splice(s,1))}},extraReducers:t=>{se(t,"active",ms),se(t,"listen_host",pr),se(t,"listen_port",hr),se(t,"protocol",mr),se(t,"destination",gr),t.addCase(Ue,e),t.addCase(Be,e);function e(s,i){if(i.payload.servers){const r=Object.fromEntries(Object.entries(i.payload.servers).filter(([l,a])=>a.type==="reverse").map(([l,a])=>[l,Qi(l)])),n=[];for(const l of s){const a=Ns(l),d=a in r;delete r[a],n.push({...l,active:d})}for(const l of Object.values(r))n.push(Wc(l));return n.length>1&&Kt({...n[0],ui_id:void 0},{...hs(),ui_id:void 0})&&n.shift(),n}}}}),{addServer:na,removeServer:ia}=vr.actions,ra=vr.reducer,xr=ie("modes/transparent/setActive"),_r=ie("modes/transparent/setListenHost"),jr=ie("modes/transparent/setListenPort"),oa=[{active:!1,ui_id:Math.random()}],la=fe({name:"modes/transparent",initialState:oa,reducers:{},extraReducers:t=>{se(t,"active",xr),se(t,"listen_host",_r),se(t,"listen_port",jr),t.addCase(Ue,be("transparent",Xn)),t.addCase(Be,be("transparent",Xn))}}),ca=la.reducer,yr=ie("modes/socks5/setActive"),wr=ie("modes/socks5/setListenHost"),br=ie("modes/socks5/setListenPort"),aa=[{active:!1,ui_id:Math.random()}],da=fe({name:"modes/socks5",initialState:aa,reducers:{},extraReducers:t=>{se(t,"active",yr),se(t,"listen_host",wr),se(t,"listen_port",br),t.addCase(Ue,be("socks5",Zn)),t.addCase(Be,be("socks5",Zn))}}),ua=da.reducer,Sr=ie("modes/upstream/setActive"),$r=ie("modes/upstream/setListenHost"),Cr=ie("modes/upstream/setListenPort"),Nr=ie("modes/upstream/setDestination"),fa=[{active:!1,destination:"",ui_id:Math.random()}],pa=fe({name:"modes/upstream",initialState:fa,reducers:{},extraReducers:t=>{se(t,"active",Sr),se(t,"listen_host",$r),se(t,"listen_port",Cr),se(t,"destination",Nr),t.addCase(Ue,be("upstream",ei)),t.addCase(Be,be("upstream",ei))}}),ha=pa.reducer,kr=ie("modes/dns/setActive"),Er=ie("modes/dns/setListenHost"),Tr=ie("modes/dns/setListenPort"),ma=[{active:!0,ui_id:Math.random()}],ga=fe({name:"modes/dns",initialState:ma,reducers:{},extraReducers:t=>{se(t,"active",kr),se(t,"listen_host",Er),se(t,"listen_port",Tr),t.addCase(Ue,be("dns",ti)),t.addCase(Be,be("dns",ti))}}),va=ga.reducer,xa=fi({regular:Yc,local:Xc,wireguard:ta,reverse:ra,transparent:ca,socks:ua,upstream:ha,dns:va}),$t=ui("fetchProcesses",async(t,{rejectWithValue:e})=>{try{return(await ne("/processes")).json()}catch(s){return e(s.message)}}),_a={currentProcesses:[],isLoading:!1},ja=fe({name:"processes",initialState:_a,reducers:{},extraReducers:t=>{t.addCase($t.pending,e=>{e.isLoading=!0,e.error=void 0}),t.addCase($t.fulfilled,(e,s)=>{e.isLoading=!1,e.currentProcesses=s.payload}),t.addCase($t.rejected,(e,s)=>{e.isLoading=!1,e.error=s.payload})}}),ya=ja.reducer,wa={commandBar:Oc,eventLog:pc,flows:nc,connection:Ec,modes:xa,ui:Sc,options:Ac,options_meta:Bc,backendState:Hc,processes:ya},ba={immutableCheck:{warnAfter:5e5},serializableCheck:{warnAfter:5e5,ignoredPaths:["flows"]}},Nt=El({reducer:wa,middleware:t=>t(ba),devTools:!1});class Sa extends I.Component{container=Te.createRef();nameInput=Te.createRef();valueInput=Te.createRef();render=()=>{const[e,s]=this.props.item;return o.jsxs("div",{ref:this.container,className:"kv-row",onClick:this.onClick,onKeyDownCapture:this.onKeyDown,children:[o.jsx(ce,{ref:this.nameInput,className:"kv-key",content:e,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([i,s]),selectAllOnClick:!0}),": ",o.jsx(ce,{ref:this.valueInput,className:"kv-value",content:s,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([e,i]),placeholder:"empty",selectAllOnClick:!0})]})};onClick=e=>{e.target===this.container.current&&this.props.onClickEmptyArea()};onKeyDown=e=>{e.target===this.valueInput.current?.input.current&&e.key==="Tab"&&this.props.onTabNext()}}class Rr extends I.Component{rowRefs={};currentlyEditing;justFinishedEditing;state={currentList:this.props.data||[],initialList:this.props.data};static getDerivedStateFromProps(e,s){return e.data!==s.initialList?{currentList:e.data||[],initialList:e.data}:null}render=()=>{this.rowRefs={};const e=this.state.currentList.map((s,i)=>o.jsx(Sa,{item:s,onEditStart:()=>this.currentlyEditing=i,onEditDone:r=>this.onEditDone(i,r),onClickEmptyArea:()=>this.onClickEmptyArea(i),onTabNext:()=>this.onTabNext(i),ref:r=>{this.rowRefs[i]=r}},i));return o.jsxs("div",{className:je("kv-editor",this.props.className),onMouseDown:this.onMouseDown,children:[e,o.jsx("div",{onClick:s=>{s.preventDefault(),this.onClickEmptyArea(this.state.currentList.length-1)},className:"kv-add-row fa fa-plus-square-o",role:"button","aria-label":"Add"})]})};onEditDone=(e,s)=>{const i=[...this.state.currentList];s[0]?i[e]=s:i.splice(e,1),this.currentlyEditing=void 0,Ht.isEqual(this.state.currentList,i)||this.props.onChange(i),this.setState({currentList:i})};onClickEmptyArea=e=>{if(this.justFinishedEditing)return;const s=[...this.state.currentList];s.splice(e+1,0,["",""]),this.setState({currentList:s},()=>this.rowRefs[e+1]?.nameInput.current?.startEditing())};onTabNext=e=>{e==this.state.currentList.length-1&&this.onClickEmptyArea(e)};onMouseDown=e=>{this.justFinishedEditing=this.currentlyEditing}}function Ar(t,e){const s=k.c(6),[i,r]=I.useState(),[n,l]=I.useState();let a;s[0]!==n||s[1]!==t?(a=()=>{n&&n.abort();const f=new AbortController;return ne(t,{signal:f.signal}).then($a).then(p=>{r(p)}).catch(p=>{f.signal.aborted||r(`Error getting content: ${p}.`)}),l(f),()=>{f.signal.aborted||f.abort()}},s[0]=n,s[1]=t,s[2]=a):a=s[2];let d;return s[3]!==e||s[4]!==t?(d=[t,e],s[3]=e,s[4]=t,s[5]=d):d=s[5],I.useEffect(a,d),i}function $a(t){if(!t.ok)throw`${t.status} ${t.statusText}`.trim();return t.text()}function Dr(t,e,s,i,r){const n=k.c(11);let l;n[0]!==t||n[1]!==i||n[2]!==e||n[3]!==s?(l=we.getContentURL(t,e,s,i),n[0]=t,n[1]=i,n[2]=e,n[3]=s,n[4]=l):l=n[4];const d=Ar(l,r);let f;if(d)try{let p;n[5]!==d?(p=JSON.parse(d),n[5]=d,n[6]=p):p=n[6],f=p}catch{let p;n[7]!==d?(p={text:d,description:"Network Error",syntax_highlight:"error",view_name:"raw"},n[7]=d,n[8]=p):p=n[8];const h=p;if(e==="messages"){let g;n[9]!==h?(g=[h],n[9]=h,n[10]=g):g=n[10],f=g}else f=h}else f=void 0;return f}const Fr=Te.memo(function({icon:e,text:s,className:i,title:r,onOpenFile:n,onClick:l}){let a;return o.jsxs("a",{href:"#",onClick:d=>{a.click(),l&&l(d)},className:i,title:r,children:[o.jsx("i",{className:"fa fa-fw "+e}),s,o.jsx("input",{ref:d=>{a=d},className:"hidden",type:"file",onChange:d=>{d.preventDefault(),d.target.files&&d.target.files.length>0&&n(d.target.files[0]),a.value=""}})]})});function pe(t){const e=k.c(11),{onClick:s,children:i,icon:r,disabled:n,className:l,title:a}=t;let d;e[0]!==l?(d=je(l,"btn btn-default"),e[0]=l,e[1]=d):d=e[1];const f=n?void 0:s;let p;e[2]!==r?(p=r&&o.jsxs(o.Fragment,{children:[o.jsx("i",{className:"fa "+r})," "]}),e[2]=r,e[3]=p):p=e[3];let h;return e[4]!==i||e[5]!==n||e[6]!==d||e[7]!==f||e[8]!==p||e[9]!==a?(h=o.jsxs("button",{className:d,onClick:f,disabled:n,title:a,children:[p,i]}),e[4]=i,e[5]=n,e[6]=d,e[7]=f,e[8]=p,e[9]=a,e[10]=h):h=e[10],h}function Ca(t){const e=k.c(11),{initialContent:s,onChange:i,language:r,readonly:n}=t,l=n===void 0?!1:n,a=Na;let d;e:switch(r){case ot.YAML:{let h;e[0]===Symbol.for("react.memo_cache_sentinel")?(h=[Dl()],e[0]=h):h=e[0],d=h;break e}case ot.XML:{let h;e[1]===Symbol.for("react.memo_cache_sentinel")?(h=[Al()],e[1]=h):h=e[1],d=h;break e}case ot.JAVASCRIPT:{let h;e[2]===Symbol.for("react.memo_cache_sentinel")?(h=[Rl()],e[2]=h):h=e[2],d=h;break e}case ot.CSS:{let h;e[3]===Symbol.for("react.memo_cache_sentinel")?(h=[Tl()],e[3]=h):h=e[3],d=h;break e}case void 0:case null:case ot.NONE:case ot.ERROR:{let h;e[4]===Symbol.for("react.memo_cache_sentinel")?(h=[],e[4]=h):h=e[4],d=h;break e}default:{console.error("Unexpected syntax highlighting language: ",r);let g;e[5]===Symbol.for("react.memo_cache_sentinel")?(g=[],e[5]=g):g=e[5],d=g}}const f=d;let p;return e[6]!==f||e[7]!==s||e[8]!==i||e[9]!==l?(p=o.jsx("div",{className:"codeeditor",onKeyDown:a,children:o.jsx(Fl,{value:s,onChange:i,readOnly:l,extensions:f})}),e[6]=f,e[7]=s,e[8]=i,e[9]=l,e[10]=p):p=e[10],p}function Na(t){return t.stopPropagation()}const Ir=Te.memo(function(e){const s=k.c(9),{content:i,maxLines:r,showMore:n}=e;if(i.length===0)return null;let l;if(s[0]!==i||s[1]!==r||s[2]!==n){let d;s[4]!==r||s[5]!==n?(d=(f,p)=>p===r?o.jsxs("button",{onClick:n,className:"btn btn-xs btn-info",children:[o.jsx("i",{className:"fa fa-angle-double-down","aria-hidden":"true"})," ","Show more"]},"showmore"):o.jsx("div",{children:f},p),s[4]=r,s[5]=n,s[6]=d):d=s[6],l=i.split(`
`).map(d),s[0]=i,s[1]=r,s[2]=n,s[3]=l}else l=s[3];let a;return s[7]!==l?(a=o.jsx("pre",{children:l}),s[7]=l,s[8]=a):a=s[8],a}),ka=()=>{const t=k.c(1);let e;return t[0]===Symbol.for("react.memo_cache_sentinel")?(e=o.jsx("li",{role:"separator",className:"divider"}),t[0]=e):e=t[0],e};function ke(t){const e=k.c(8);let s,i,r;if(e[0]!==t){const{onClick:a,children:d,...f}=t;i=d,s=f,r=p=>{p.preventDefault(),a()},e[0]=t,e[1]=s,e[2]=i,e[3]=r}else s=e[1],i=e[2],r=e[3];const n=r;let l;return e[4]!==s||e[5]!==i||e[6]!==n?(l=o.jsx("li",{children:o.jsx("a",{href:"#",onClick:n,...s,children:i})}),e[4]=s,e[5]=i,e[6]=n,e[7]=l):l=e[7],l}const Et=Te.memo(function({text:e,children:s,options:i,className:r,onOpen:n,...l}){const[a,d]=I.useState(!1),{refs:f,floatingStyles:p}=Il(i),h=_=>{d(_),n&&n(_)};I.useEffect(()=>{f.floating.current&&document.addEventListener("click",_=>{f.floating.current?.contains(_.target)?document.addEventListener("click",()=>h(!1),{once:!0}):(_.preventDefault(),_.stopPropagation(),h(!1))},{once:!0,capture:!0})},[f.floating.current]);let g;return a?g=o.jsx("ul",{className:"dropdown-menu show",ref:f.setFloating,style:p,children:s}):g=null,o.jsxs(o.Fragment,{children:[o.jsx("a",{href:"#",ref:f.setReference,className:je(r,{open:a}),onClick:_=>{_.preventDefault(),h(!0)},...l,children:e}),g]})});function Lr(t){const e=k.c(16),{value:s,onChange:i}=t,r=D(Ea);let n;e[0]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("i",{className:"fa fa-fw fa-files-o"}),e[0]=n):n=e[0];let l;e[1]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsx("b",{children:"View:"}),e[1]=l):l=e[1];let a;e[2]!==s?(a=s.toLowerCase(),e[2]=s,e[3]=a):a=e[3];let d;e[4]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("span",{className:"caret"}),e[4]=d):d=e[4];let f;e[5]!==a?(f=o.jsxs("span",{children:[n," ",l," ",a," ",d]}),e[5]=a,e[6]=f):f=e[6];const p=f;let h;e[7]===Symbol.for("react.memo_cache_sentinel")?(h={placement:"top-end"},e[7]=h):h=e[7];let g;if(e[8]!==r||e[9]!==i){let j;e[11]!==i?(j=y=>o.jsx(ke,{onClick:()=>i(y),children:y.toLowerCase().replace("_"," ")},y),e[11]=i,e[12]=j):j=e[12],g=r.map(j),e[8]=r,e[9]=i,e[10]=g}else g=e[10];let _;return e[13]!==p||e[14]!==g?(_=o.jsx(Et,{text:p,className:"btn btn-default btn-xs",options:h,children:g}),e[13]=p,e[14]=g,e[15]=_):_=e[15],_}function Ea(t){return t.backendState.contentViews||[]}function Ta(t){const e=k.c(8),{flow:s,message:i}=t,[r,n]=I.useState(!1);if(r){let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l=()=>n(!1),e[0]=l):l=e[0];let a;return e[1]!==s||e[2]!==i?(a=o.jsx(Ra,{flow:s,message:i,stopEdit:l}),e[1]=s,e[2]=i,e[3]=a):a=e[3],a}else{let l;e[4]===Symbol.for("react.memo_cache_sentinel")?(l=()=>n(!0),e[4]=l):l=e[4];let a;return e[5]!==s||e[6]!==i?(a=o.jsx(Aa,{flow:s,message:i,startEdit:l}),e[5]=s,e[6]=i,e[7]=a):a=e[7],a}}function Ra(t){const e=k.c(23),{flow:s,message:i,stopEdit:r}=t,n=G(),l=s.request===i?"request":"response";let a;e[0]!==s||e[1]!==i?(a=we.getContentURL(s,i),e[0]=s,e[1]=i,e[2]=a):a=e[2];const f=Ar(a,i.contentHash),[p,h]=I.useState();let g;e[3]!==f||e[4]!==n||e[5]!==p||e[6]!==s||e[7]!==l||e[8]!==r?(g=async()=>{await n(Le(s,{[l]:{content:p??f??""}})),r()},e[3]=f,e[4]=n,e[5]=p,e[6]=s,e[7]=l,e[8]=r,e[9]=g):g=e[9];const _=g;let j;e[10]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsx("h5",{children:"[Editing]"}),e[10]=j):j=e[10];let y;e[11]!==_?(y=o.jsx(pe,{onClick:_,icon:"fa-check text-success",className:"btn-xs",children:"Done"}),e[11]=_,e[12]=y):y=e[12];let w;e[13]!==r?(w=o.jsx(pe,{onClick:()=>r(),icon:"fa-times text-danger",className:"btn-xs",children:"Cancel"}),e[13]=r,e[14]=w):w=e[14];let $;e[15]!==y||e[16]!==w?($=o.jsxs("div",{className:"controls",children:[j,y," ",w]}),e[15]=y,e[16]=w,e[17]=$):$=e[17];const N=f||"";let E;e[18]!==N?(E=o.jsx(Ca,{initialContent:N,onChange:h}),e[18]=N,e[19]=E):E=e[19];let T;return e[20]!==$||e[21]!==E?(T=o.jsxs("div",{className:"contentview",children:[$,E]},"edit"),e[20]=$,e[21]=E,e[22]=T):T=e[22],T}function Aa(t){const e=k.c(43),{flow:s,message:i,startEdit:r}=t,n=G(),l=s.request===i?"request":"response";let a;e[0]!==s.id||e[1]!==l?(a=V=>V.ui.flow.contentViewFor[s.id+l]||"Auto",e[0]=s.id,e[1]=l,e[2]=a):a=e[2];const d=D(a),[f,p]=I.useState(D(Da));let h;e[3]!==f?(h=()=>p(Math.max(1024,f*2)),e[3]=f,e[4]=h):h=e[4];const g=h,_=Dr(s,i,d,f+1,i.contentHash);let j;if(i.contentLength===0)j="No content";else if(_===void 0)j="Loading...";else{const V=`${_.view_name} ${_.description}`;let W;e[5]!==V?(W=V.trimEnd(),e[5]=V,e[6]=W):W=e[6],j=W}let y;e[7]!==j?(y=o.jsx("h5",{children:j}),e[7]=j,e[8]=y):y=e[8];let w;e[9]!==_||e[10]!==s||e[11]!==i?(w=_&&_?.text.length>0&&o.jsx(Fa,{flow:s,message:i}),e[9]=_,e[10]=s,e[11]=i,e[12]=w):w=e[12];let $;e[13]!==r?($=o.jsx(pe,{onClick:r,icon:"fa-edit",className:"btn-xs",children:"Edit"}),e[13]=r,e[14]=$):$=e[14];let N;e[15]!==n||e[16]!==s||e[17]!==l?(N=o.jsx(Fr,{icon:"fa-upload",text:"Replace",title:"Upload a file to replace the content.",onOpenFile:V=>n(ec(s,V,l)),className:"btn btn-default btn-xs"}),e[15]=n,e[16]=s,e[17]=l,e[18]=N):N=e[18];let E;e[19]!==n||e[20]!==s.id||e[21]!==l?(E=V=>n(pi({messageId:s.id+l,contentView:V})),e[19]=n,e[20]=s.id,e[21]=l,e[22]=E):E=e[22];let T;e[23]!==d||e[24]!==E?(T=o.jsx(Lr,{value:d,onChange:E}),e[23]=d,e[24]=E,e[25]=T):T=e[25];let P;e[26]!==y||e[27]!==w||e[28]!==$||e[29]!==N||e[30]!==T?(P=o.jsxs("div",{className:"controls",children:[y,w," ",$," ",N," ",T]}),e[26]=y,e[27]=w,e[28]=$,e[29]=N,e[30]=T,e[31]=P):P=e[31];let L;e[32]!==s||e[33]!==i?(L=gs.matches(i)&&o.jsx(gs,{flow:s,message:i}),e[32]=s,e[33]=i,e[34]=L):L=e[34];const O=_?.text??"";let M;e[35]!==f||e[36]!==g||e[37]!==O?(M=o.jsx(Ir,{content:O,maxLines:f,showMore:g}),e[35]=f,e[36]=g,e[37]=O,e[38]=M):M=e[38];let U;return e[39]!==L||e[40]!==M||e[41]!==P?(U=o.jsxs("div",{className:"contentview",children:[P,L,M]},"view"),e[39]=L,e[40]=M,e[41]=P,e[42]=U):U=e[42],U}function Da(t){return t.options.content_view_lines_cutoff}function Fa({flow:t,message:e}){const s=t.request===e?"request":"response",i=D(f=>f.ui.flow.contentViewFor[t.id+s]||"Auto"),[r,n]=I.useState(!1),[l,a]=I.useState(!1),d=async()=>{try{const f=we.getContentURL(t,e,i);a(!0);const p=await ne(f);if(!p.ok)throw new Error(`${p.status} ${p.statusText}`.trim());const h=await p.json();await Bl(h),n(!0),setTimeout(()=>n(!1),2e3)}catch(f){console.error(f)}finally{a(!1)}};return o.jsx(pe,{onClick:d,icon:"fa-clipboard",className:"btn-xs",disabled:l,children:r?"Copied!":"Copy"})}const Ia=/^image\/(png|jpe?g|gif|webp|vnc.microsoft.icon|x-icon|svg\+xml)$/i;gs.matches=t=>Ia.test(we.getContentType(t)||"");function gs(t){const e=k.c(5),{flow:s,message:i}=t;let r;e[0]!==s||e[1]!==i?(r=we.getContentURL(s,i),e[0]=s,e[1]=i,e[2]=r):r=e[2];let n;return e[3]!==r?(n=o.jsx("div",{className:"flowview-image",children:o.jsx("img",{src:r,alt:"preview",className:"img-thumbnail"})}),e[3]=r,e[4]=n):n=e[4],n}function La(t){const e=k.c(24),{flow:s}=t,i=G();let r;e[0]!==i||e[1]!==s?(r=g=>i(Le(s,{request:{method:g}})),e[0]=i,e[1]=s,e[2]=r):r=e[2];let n;e[3]!==s.request.method||e[4]!==r?(n=o.jsx(bt,{content:s.request.method,onEditDone:r,isValid:Oa,selectAllOnClick:!0}),e[3]=s.request.method,e[4]=r,e[5]=n):n=e[5];let l;e[6]!==s.request?(l=ct.pretty_url(s.request),e[6]=s.request,e[7]=l):l=e[7];let a;e[8]!==i||e[9]!==s?(a=g=>i(Le(s,{request:{path:"",..._i(g)}})),e[8]=i,e[9]=s,e[10]=a):a=e[10];let d;e[11]!==l||e[12]!==a?(d=o.jsx(bt,{content:l,onEditDone:a,isValid:Pa}),e[11]=l,e[12]=a,e[13]=d):d=e[13];let f;e[14]!==i||e[15]!==s?(f=g=>i(Le(s,{request:{http_version:g}})),e[14]=i,e[15]=s,e[16]=f):f=e[16];let p;e[17]!==s.request.http_version||e[18]!==f?(p=o.jsx(bt,{content:s.request.http_version,onEditDone:f,isValid:ji,selectAllOnClick:!0}),e[17]=s.request.http_version,e[18]=f,e[19]=p):p=e[19];let h;return e[20]!==n||e[21]!==d||e[22]!==p?(h=o.jsx("div",{className:"first-line request-line",children:o.jsxs("div",{children:[n," ",d," ",p]})}),e[20]=n,e[21]=d,e[22]=p,e[23]=h):h=e[23],h}function Pa(t){return!!_i(t)?.host}function Oa(t){return t.length>0}function Ma(t){const e=k.c(19),{flow:s}=t,i=G();let r;e[0]!==i||e[1]!==s?(r=h=>i(Le(s,{response:{http_version:h}})),e[0]=i,e[1]=s,e[2]=r):r=e[2];let n;e[3]!==s.response.http_version||e[4]!==r?(n=o.jsx(bt,{content:s.response.http_version,onEditDone:r,isValid:ji,selectAllOnClick:!0}),e[3]=s.response.http_version,e[4]=r,e[5]=n):n=e[5];const l=s.response.status_code+"";let a;e[6]!==i||e[7]!==s?(a=h=>i(Le(s,{response:{code:parseInt(h)}})),e[6]=i,e[7]=s,e[8]=a):a=e[8];let d;e[9]!==l||e[10]!==a?(d=o.jsx(bt,{content:l,onEditDone:a,isValid:qa,selectAllOnClick:!0}),e[9]=l,e[10]=a,e[11]=d):d=e[11];let f;e[12]!==i||e[13]!==s?(f=s.response.http_version!=="HTTP/2.0"&&o.jsxs(o.Fragment,{children:[" ",o.jsx(ce,{content:s.response.reason,onEditDone:h=>i(Le(s,{response:{msg:h}})),selectAllOnClick:!0})]}),e[12]=i,e[13]=s,e[14]=f):f=e[14];let p;return e[15]!==n||e[16]!==d||e[17]!==f?(p=o.jsxs("div",{className:"first-line response-line",children:[n," ",d,f]}),e[15]=n,e[16]=d,e[17]=f,e[18]=p):p=e[18],p}function qa(t){return/^\d+$/.test(t)}function Ha(t){const e=k.c(7),{flow:s,message:i}=t,r=G(),n=s.request===i?"request":"response";let l;e[0]!==r||e[1]!==s||e[2]!==n?(l=d=>r(Le(s,{[n]:{headers:d}})),e[0]=r,e[1]=s,e[2]=n,e[3]=l):l=e[3];let a;return e[4]!==i.headers||e[5]!==l?(a=o.jsx(Rr,{className:"headers",data:i.headers,onChange:l}),e[4]=i.headers,e[5]=l,e[6]=a):a=e[6],a}function Va(t){const e=k.c(9),{flow:s,message:i}=t,r=G(),n=s.request===i?"request":"response";if(!!!we.get_first_header(i,/^trailer$/i))return null;let a,d;e[0]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("hr",{}),d=o.jsx("h5",{children:"HTTP Trailers"}),e[0]=a,e[1]=d):(a=e[0],d=e[1]);let f;e[2]!==r||e[3]!==s||e[4]!==n?(f=h=>r(Le(s,{[n]:{trailers:h}})),e[2]=r,e[3]=s,e[4]=n,e[5]=f):f=e[5];let p;return e[6]!==i.trailers||e[7]!==f?(p=o.jsxs(o.Fragment,{children:[a,d,o.jsx(Rr,{className:"trailers",data:i.trailers,onChange:f})]}),e[6]=i.trailers,e[7]=f,e[8]=p):p=e[8],p}const Pr=I.memo(function(e){const s=k.c(20),{flow:i,message:r}=e,n=i.request===r?"request":"response",l=i.request===r?La:Ma;let a;s[0]!==l||s[1]!==i?(a=o.jsx(l,{flow:i}),s[0]=l,s[1]=i,s[2]=a):a=s[2];let d;s[3]!==i||s[4]!==r?(d=o.jsx(Ha,{flow:i,message:r}),s[3]=i,s[4]=r,s[5]=d):d=s[5];let f;s[6]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("hr",{}),s[6]=f):f=s[6];const p=i.id+n;let h;s[7]!==i||s[8]!==r||s[9]!==p?(h=o.jsx(Ta,{flow:i,message:r},p),s[7]=i,s[8]=r,s[9]=p,s[10]=h):h=s[10];let g;s[11]!==i||s[12]!==r?(g=o.jsx(Va,{flow:i,message:r}),s[11]=i,s[12]=r,s[13]=g):g=s[13];let _;return s[14]!==n||s[15]!==a||s[16]!==d||s[17]!==h||s[18]!==g?(_=o.jsxs("section",{className:n,children:[a,d,f,h,g]}),s[14]=n,s[15]=a,s[16]=d,s[17]=h,s[18]=g,s[19]=_):_=s[19],_});function Or(){const t=k.c(2),e=D(Ua);let s;return t[0]!==e?(s=o.jsx(Pr,{flow:e,message:e.request}),t[0]=e,t[1]=s):s=t[1],s}function Ua(t){return t.flows.selected[0]}Or.displayName="Request";function Mr(){const t=k.c(2),e=D(Ba);let s;return t[0]!==e?(s=o.jsx(Pr,{flow:e,message:e.response}),t[0]=e,t[1]=s):s=t[1],s}function Ba(t){return t.flows.selected[0]}Mr.displayName="Response";const Wa=t=>{const e=k.c(3),{message:s}=t,i=s.query?s.op_code:s.response_code,r=s.truncation?"(Truncated)":"";let n;return e[0]!==i||e[1]!==r?(n=o.jsxs("div",{children:[i," ",r]}),e[0]=i,e[1]=r,e[2]=n):n=e[2],n},Ka=t=>{const e=k.c(10),{message:s}=t,i=s.recursion_desired?"Recursive ":"";let r;e[0]!==i?(r=o.jsxs("h5",{children:[i,"Question"]}),e[0]=i,e[1]=r):r=e[1];let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("thead",{children:o.jsxs("tr",{children:[o.jsx("th",{children:"Name"}),o.jsx("th",{children:"Type"}),o.jsx("th",{children:"Class"})]})}),e[2]=n):n=e[2];let l;e[3]!==s.questions?(l=s.questions.map(Ya),e[3]=s.questions,e[4]=l):l=e[4];let a;e[5]!==l?(a=o.jsxs("table",{children:[n,o.jsx("tbody",{children:l})]}),e[5]=l,e[6]=a):a=e[6];let d;return e[7]!==r||e[8]!==a?(d=o.jsxs(o.Fragment,{children:[r,a]}),e[7]=r,e[8]=a,e[9]=d):d=e[9],d},ls=t=>{const e=k.c(7),{name:s,values:i}=t;let r;e[0]!==s?(r=o.jsx("h5",{children:s}),e[0]=s,e[1]=r):r=e[1];let n;e[2]!==i?(n=i.length>0?o.jsxs("table",{children:[o.jsx("thead",{children:o.jsxs("tr",{children:[o.jsx("th",{children:"Name"}),o.jsx("th",{children:"Type"}),o.jsx("th",{children:"Class"}),o.jsx("th",{children:"TTL"}),o.jsx("th",{children:"Data"})]})}),o.jsx("tbody",{children:i.map(Ja)})]}):"—",e[2]=i,e[3]=n):n=e[3];let l;return e[4]!==r||e[5]!==n?(l=o.jsxs(o.Fragment,{children:[r,n]}),e[4]=r,e[5]=n,e[6]=l):l=e[6],l},qr=t=>{const e=k.c(24),{type:s,message:i}=t,r="dns-"+s,n=`first-line ${s}-line`;let l;e[0]!==i?(l=o.jsx(Wa,{message:i}),e[0]=i,e[1]=l):l=e[1];let a;e[2]!==n||e[3]!==l?(a=o.jsx("div",{className:n,children:l}),e[2]=n,e[3]=l,e[4]=a):a=e[4];let d;e[5]!==i?(d=o.jsx(Ka,{message:i}),e[5]=i,e[6]=d):d=e[6];let f;e[7]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("hr",{}),e[7]=f):f=e[7];const p=`${i.authoritative_answer?"Authoritative ":""}${i.recursion_available?"Recursive ":""}Answer`;let h;e[8]!==i.answers||e[9]!==p?(h=o.jsx(ls,{name:p,values:i.answers}),e[8]=i.answers,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("hr",{}),e[11]=g):g=e[11];let _;e[12]!==i.authorities?(_=o.jsx(ls,{name:"Authority",values:i.authorities}),e[12]=i.authorities,e[13]=_):_=e[13];let j;e[14]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsx("hr",{}),e[14]=j):j=e[14];let y;e[15]!==i.additionals?(y=o.jsx(ls,{name:"Additional",values:i.additionals}),e[15]=i.additionals,e[16]=y):y=e[16];let w;return e[17]!==r||e[18]!==_||e[19]!==y||e[20]!==a||e[21]!==d||e[22]!==h?(w=o.jsxs("section",{className:r,children:[a,d,f,h,g,_,j,y]}),e[17]=r,e[18]=_,e[19]=y,e[20]=a,e[21]=d,e[22]=h,e[23]=w):w=e[23],w};function Hr(){const t=k.c(2),e=D(za);let s;return t[0]!==e.request?(s=o.jsx(qr,{type:"request",message:e.request}),t[0]=e.request,t[1]=s):s=t[1],s}function za(t){return t.flows.selected[0]}Hr.displayName="Request";function Vr(){const t=k.c(2),e=D(Ga);let s;return t[0]!==e.response?(s=o.jsx(qr,{type:"response",message:e.response}),t[0]=e.response,t[1]=s):s=t[1],s}function Ga(t){return t.flows.selected[0]}Vr.displayName="Response";function Ya(t,e){return o.jsxs("tr",{children:[o.jsx("td",{children:t.name}),o.jsx("td",{children:t.type}),o.jsx("td",{children:t.class})]},e)}function Ja(t,e){return o.jsxs("tr",{children:[o.jsx("td",{children:t.name}),o.jsx("td",{children:t.type}),o.jsx("td",{children:t.class}),o.jsx("td",{children:t.ttl}),o.jsx("td",{children:JSON.stringify(t.data).replace(/^"|"$/g,"")})]},e)}function Mt(t,e){return e?(e=[e[0],e[1]],e[0].includes(":")&&(e[0]=`[${e[0]}]`),o.jsxs("tr",{children:[o.jsxs("td",{children:[t,":"]}),o.jsx("td",{children:e.join(":")})]})):o.jsx(o.Fragment,{})}function si(t){const e=k.c(26),{conn:s}=t;let i;if("address"in s){let f;e[0]!==s.address?(f=Mt("Address",s.address),e[0]=s.address,e[1]=f):f=e[1];let p;e[2]!==s.peername?(p=Mt("Resolved address",s.peername),e[2]=s.peername,e[3]=p):p=e[3];let h;e[4]!==s.sockname?(h=Mt("Source address",s.sockname),e[4]=s.sockname,e[5]=h):h=e[5];let g;e[6]!==f||e[7]!==p||e[8]!==h?(g=o.jsxs(o.Fragment,{children:[f,p,h]}),e[6]=f,e[7]=p,e[8]=h,e[9]=g):g=e[9],i=g}else{let f;e[10]!==s.peername?(f=Mt("Address",s.peername),e[10]=s.peername,e[11]=f):f=e[11],i=f}let r;e[12]!==s.sni?(r=s.sni?o.jsxs("tr",{children:[o.jsxs("td",{children:[o.jsx("abbr",{title:"TLS Server Name Indication",children:"SNI"}),":"]}),o.jsx("td",{children:s.sni})]}):null,e[12]=s.sni,e[13]=r):r=e[13];let n;e[14]!==s.alpn?(n=s.alpn?o.jsxs("tr",{children:[o.jsxs("td",{children:[o.jsx("abbr",{title:"ALPN protocol negotiated",children:"ALPN"}),":"]}),o.jsx("td",{children:s.alpn})]}):null,e[14]=s.alpn,e[15]=n):n=e[15];let l;e[16]!==s.tls_version?(l=s.tls_version?o.jsxs("tr",{children:[o.jsx("td",{children:"TLS Version:"}),o.jsx("td",{children:s.tls_version})]}):null,e[16]=s.tls_version,e[17]=l):l=e[17];let a;e[18]!==s.cipher?(a=s.cipher?o.jsxs("tr",{children:[o.jsx("td",{children:"TLS Cipher:"}),o.jsx("td",{children:s.cipher})]}):null,e[18]=s.cipher,e[19]=a):a=e[19];let d;return e[20]!==i||e[21]!==r||e[22]!==n||e[23]!==l||e[24]!==a?(d=o.jsx("table",{className:"connection-table",children:o.jsxs("tbody",{children:[i,r,n,l,a]})}),e[20]=i,e[21]=r,e[22]=n,e[23]=l,e[24]=a,e[25]=d):d=e[25],d}function ni(t){return o.jsx("dl",{className:"cert-attributes",children:t.map(([e,s])=>o.jsxs(I.Fragment,{children:[o.jsx("dt",{children:e}),o.jsx("dd",{children:s})]},e))})}function Qa(t){const e=k.c(46),{flow:s}=t,i=s.server_conn?.cert;if(!i){let W;return e[0]===Symbol.for("react.memo_cache_sentinel")?(W=o.jsx(o.Fragment,{}),e[0]=W):W=e[0],W}let r;e[1]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("h4",{children:"Server Certificate"},"name"),e[1]=r):r=e[1];let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("td",{children:"Type"}),e[2]=n):n=e[2];let l;e[3]!==i.keyinfo[0]||e[4]!==i.keyinfo[1]?(l=o.jsxs("tr",{children:[n,o.jsxs("td",{children:[i.keyinfo[0],", ",i.keyinfo[1]," bits"]})]}),e[3]=i.keyinfo[0],e[4]=i.keyinfo[1],e[5]=l):l=e[5];let a;e[6]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("td",{children:"SHA256 digest"}),e[6]=a):a=e[6];let d;e[7]!==i.sha256?(d=o.jsxs("tr",{children:[a,o.jsx("td",{children:i.sha256})]}),e[7]=i.sha256,e[8]=d):d=e[8];let f;e[9]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("td",{children:"Valid from"}),e[9]=f):f=e[9];let p;e[10]!==i.notbefore?(p=at(i.notbefore,{includeMilliseconds:!1}),e[10]=i.notbefore,e[11]=p):p=e[11];let h;e[12]!==p?(h=o.jsxs("tr",{children:[f,o.jsx("td",{children:p})]}),e[12]=p,e[13]=h):h=e[13];let g;e[14]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("td",{children:"Valid to"}),e[14]=g):g=e[14];let _;e[15]!==i.notafter?(_=at(i.notafter,{includeMilliseconds:!1}),e[15]=i.notafter,e[16]=_):_=e[16];let j;e[17]!==_?(j=o.jsxs("tr",{children:[g,o.jsx("td",{children:_})]}),e[17]=_,e[18]=j):j=e[18];let y;e[19]===Symbol.for("react.memo_cache_sentinel")?(y=o.jsx("td",{children:"Subject Alternative Names"}),e[19]=y):y=e[19];let w;e[20]!==i.altnames?(w=i.altnames.join(", "),e[20]=i.altnames,e[21]=w):w=e[21];let $;e[22]!==w?($=o.jsxs("tr",{children:[y,o.jsx("td",{children:w})]}),e[22]=w,e[23]=$):$=e[23];let N;e[24]===Symbol.for("react.memo_cache_sentinel")?(N=o.jsx("td",{children:"Subject"}),e[24]=N):N=e[24];let E;e[25]!==i.subject?(E=ni(i.subject),e[25]=i.subject,e[26]=E):E=e[26];let T;e[27]!==E?(T=o.jsxs("tr",{children:[N,o.jsx("td",{children:E})]}),e[27]=E,e[28]=T):T=e[28];let P;e[29]===Symbol.for("react.memo_cache_sentinel")?(P=o.jsx("td",{children:"Issuer"}),e[29]=P):P=e[29];let L;e[30]!==i.issuer?(L=ni(i.issuer),e[30]=i.issuer,e[31]=L):L=e[31];let O;e[32]!==L?(O=o.jsxs("tr",{children:[P,o.jsx("td",{children:L})]}),e[32]=L,e[33]=O):O=e[33];let M;e[34]===Symbol.for("react.memo_cache_sentinel")?(M=o.jsx("td",{children:"Serial"}),e[34]=M):M=e[34];let U;e[35]!==i.serial?(U=o.jsxs("tr",{children:[M,o.jsx("td",{children:i.serial})]}),e[35]=i.serial,e[36]=U):U=e[36];let V;return e[37]!==j||e[38]!==$||e[39]!==T||e[40]!==O||e[41]!==U||e[42]!==l||e[43]!==d||e[44]!==h?(V=o.jsxs(o.Fragment,{children:[r,o.jsx("table",{className:"certificate-table",children:o.jsxs("tbody",{children:[l,d,h,j,$,T,O,U]})})]}),e[37]=j,e[38]=$,e[39]=T,e[40]=O,e[41]=U,e[42]=l,e[43]=d,e[44]=h,e[45]=V):V=e[45],V}function Ur(t){const e=k.c(11),{flow:s}=t;let i;e[0]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsx("h4",{children:"Client Connection"}),e[0]=i):i=e[0];let r;e[1]!==s.client_conn?(r=o.jsx(si,{conn:s.client_conn}),e[1]=s.client_conn,e[2]=r):r=e[2];let n;e[3]!==s.server_conn?(n=s.server_conn?.address&&o.jsxs(o.Fragment,{children:[o.jsx("h4",{children:"Server Connection"}),o.jsx(si,{conn:s.server_conn})]}),e[3]=s.server_conn,e[4]=n):n=e[4];let l;e[5]!==s?(l=o.jsx(Qa,{flow:s}),e[5]=s,e[6]=l):l=e[6];let a;return e[7]!==r||e[8]!==n||e[9]!==l?(a=o.jsxs("section",{className:"detail",children:[i,r,n,l]}),e[7]=r,e[8]=n,e[9]=l,e[10]=a):a=e[10],a}Ur.displayName="Connection";function Br(t){const e=k.c(7),{flow:s}=t,i=s.error.msg;let r;e[0]!==s.error.timestamp?(r=at(s.error.timestamp),e[0]=s.error.timestamp,e[1]=r):r=e[1];let n;e[2]!==r?(n=o.jsx("div",{children:o.jsx("small",{children:r})}),e[2]=r,e[3]=n):n=e[3];let l;return e[4]!==s.error.msg||e[5]!==n?(l=o.jsx("section",{className:"error",children:o.jsxs("div",{className:"alert alert-warning",children:[i,n]})}),e[4]=s.error.msg,e[5]=n,e[6]=l):l=e[6],l}Br.displayName="Error";function Xa(t){const e=k.c(4),{t:s,deltaTo:i,title:r}=t;let n;return e[0]!==i||e[1]!==s||e[2]!==r?(n=s?o.jsxs("tr",{children:[o.jsxs("td",{children:[r,":"]}),o.jsxs("td",{children:[at(s),i&&o.jsxs("span",{className:"text-muted",children:["(",mi(1e3*(s-i)),")"]})]})]}):o.jsx("tr",{}),e[0]=i,e[1]=s,e[2]=r,e[3]=n):n=e[3],n}function Wr(t){const e=k.c(26),{flow:s}=t;let i;s.type==="http"?i=s.request.timestamp_start:i=s.client_conn.timestamp_start;const r=s.server_conn?.timestamp_start;let n,l,a,d;if(e[0]!==s.client_conn.timestamp_end||e[1]!==s.client_conn.timestamp_start||e[2]!==s.client_conn.timestamp_tls_setup||e[3]!==s.request||e[4]!==s.response?.timestamp_end||e[5]!==s.response?.timestamp_start||e[6]!==s.server_conn?.timestamp_end||e[7]!==s.server_conn?.timestamp_tcp_setup||e[8]!==s.server_conn?.timestamp_tls_setup||e[9]!==s.type||e[10]!==i||e[11]!==r){const g=[{title:"Server conn. initiated",t:r,deltaTo:i},{title:"Server conn. TCP handshake",t:s.server_conn?.timestamp_tcp_setup,deltaTo:i},{title:"Server conn. TLS handshake",t:s.server_conn?.timestamp_tls_setup,deltaTo:i},{title:"Server conn. closed",t:s.server_conn?.timestamp_end,deltaTo:i},{title:"Client conn. established",t:s.client_conn.timestamp_start,deltaTo:s.type==="http"?i:void 0},{title:"Client conn. TLS handshake",t:s.client_conn.timestamp_tls_setup,deltaTo:i},{title:"Client conn. closed",t:s.client_conn.timestamp_end,deltaTo:i}];s.type==="http"&&g.push({title:"First request byte",t:s.request.timestamp_start},{title:"Request complete",t:s.request.timestamp_end,deltaTo:i},{title:"First response byte",t:s.response?.timestamp_start,deltaTo:i},{title:"Response complete",t:s.response?.timestamp_end,deltaTo:i}),a="timing",e[16]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("h4",{children:"Timing"}),e[16]=d):d=e[16],l="timing-table",n=g.filter(td).sort(ed).map(Za),e[0]=s.client_conn.timestamp_end,e[1]=s.client_conn.timestamp_start,e[2]=s.client_conn.timestamp_tls_setup,e[3]=s.request,e[4]=s.response?.timestamp_end,e[5]=s.response?.timestamp_start,e[6]=s.server_conn?.timestamp_end,e[7]=s.server_conn?.timestamp_tcp_setup,e[8]=s.server_conn?.timestamp_tls_setup,e[9]=s.type,e[10]=i,e[11]=r,e[12]=n,e[13]=l,e[14]=a,e[15]=d}else n=e[12],l=e[13],a=e[14],d=e[15];let f;e[17]!==n?(f=o.jsx("tbody",{children:n}),e[17]=n,e[18]=f):f=e[18];let p;e[19]!==l||e[20]!==f?(p=o.jsx("table",{className:l,children:f}),e[19]=l,e[20]=f,e[21]=p):p=e[21];let h;return e[22]!==a||e[23]!==d||e[24]!==p?(h=o.jsxs("section",{className:a,children:[d,p]}),e[22]=a,e[23]=d,e[24]=p,e[25]=h):h=e[25],h}function Za(t){const{title:e,t:s,deltaTo:i}=t;return o.jsx(Xa,{title:e,t:s,deltaTo:i},e)}function ed(t,e){return t.t-e.t}function td(t){return!!t.t}Wr.displayName="Timing";function ks({flow:t,messages_meta:e}){const s=G(),i=D(f=>f.ui.flow.contentViewFor[t.id+"messages"]||"Auto"),[r,n]=I.useState(D(f=>f.options.content_view_lines_cutoff)),l=I.useCallback(()=>n(Math.max(1024,r*2)),[r]),a=Dr(t,"messages",i,r+1,t.id+e.count)??[];let d=r;return o.jsxs("div",{className:"contentview",children:[o.jsxs("div",{className:"controls",children:[o.jsxs("h5",{children:[e.count," Messages"]}),o.jsx(Lr,{value:i,onChange:f=>s(pi({messageId:t.id+"messages",contentView:f}))})]}),a.map((f,p)=>{const h=`fa fa-fw fa-arrow-${f.from_client?"right text-primary":"left text-danger"}`,g=o.jsxs("div",{children:[o.jsxs("small",{children:[o.jsx("i",{className:h}),o.jsx("span",{className:"pull-right",children:f.timestamp&&at(f.timestamp)})]}),o.jsx(Ir,{content:f.text,maxLines:d,showMore:l})]},p);return d-=f.text.split(`
`).length,g})]})}function Kr(t){const e=k.c(8),{flow:s}=t;let i;e[0]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsx("h4",{children:"WebSocket"}),e[0]=i):i=e[0];let r;e[1]!==s?(r=o.jsx(ks,{flow:s,messages_meta:s.websocket.messages_meta}),e[1]=s,e[2]=r):r=e[2];let n;e[3]!==s.websocket?(n=o.jsx(sd,{websocket:s.websocket}),e[3]=s.websocket,e[4]=n):n=e[4];let l;return e[5]!==r||e[6]!==n?(l=o.jsxs("section",{className:"websocket",children:[i,r,n]}),e[5]=r,e[6]=n,e[7]=l):l=e[7],l}Kr.displayName="WebSocket";function sd(t){const e=k.c(10),{websocket:s}=t;if(!s.timestamp_end)return null;const i=s.close_reason?`(${s.close_reason})`:"";let r;e[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("i",{className:"fa fa-fw fa-window-close text-muted"}),e[0]=r):r=e[0];const n=s.closed_by_client?"client":"server",l=s.close_code;let a;e[1]!==s.timestamp_end?(a=at(s.timestamp_end),e[1]=s.timestamp_end,e[2]=a):a=e[2];let d;e[3]!==a?(d=o.jsx("small",{className:"pull-right",children:a}),e[3]=a,e[4]=d):d=e[4];let f;return e[5]!==i||e[6]!==n||e[7]!==d||e[8]!==s.close_code?(f=o.jsxs("div",{children:[r," Closed by ",n," ","with code ",l," ",i,".",d]}),e[5]=i,e[6]=n,e[7]=d,e[8]=s.close_code,e[9]=f):f=e[9],f}function zr(t){const e=k.c(7),{flow:s}=t,i=G();let r;e[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("h4",{children:"Comment"}),e[0]=r):r=e[0];let n;e[1]!==i||e[2]!==s?(n=a=>{i(Le(s,{comment:a}))},e[1]=i,e[2]=s,e[3]=n):n=e[3];let l;return e[4]!==s.comment||e[5]!==n?(l=o.jsxs("section",{className:"timing",children:[r,o.jsx(ce,{className:"kv-value",content:s.comment,onEditDone:n,placeholder:"empty",selectAllOnClick:!0})]}),e[4]=s.comment,e[5]=n,e[6]=l):l=e[6],l}zr.displayName="Comment";function Gr(t){const e=k.c(2),{flow:s}=t;let i;return e[0]!==s?(i=o.jsx("section",{className:"tcp",children:o.jsx(ks,{flow:s,messages_meta:s.messages_meta})}),e[0]=s,e[1]=i):i=e[1],i}Gr.displayName="Stream Data";function Yr(t){const e=k.c(2),{flow:s}=t;let i;return e[0]!==s?(i=o.jsx("section",{className:"udp",children:o.jsx(ks,{flow:s,messages_meta:s.messages_meta})}),e[0]=s,e[1]=i):i=e[1],i}Yr.displayName="Datagrams";const ii={request:Or,response:Mr,error:Br,connection:Ur,timing:Wr,websocket:Kr,tcpmessages:Gr,udpmessages:Yr,dnsrequest:Hr,dnsresponse:Vr,comment:zr};function vs(t){let e;switch(t.type){case"http":e=["request","response","websocket"].filter(s=>t[s]);break;case"tcp":e=["tcpmessages"];break;case"udp":e=["udpmessages"];break;case"dns":e=["request","response"].filter(s=>t[s]).map(s=>"dns"+s);break}return t.error&&e.push("error"),e.push("connection"),e.push("timing"),e.push("comment"),e}function nd(){const t=k.c(15),e=G(),s=D(rd);let i=D(id);if(s==null){let y;return t[0]===Symbol.for("react.memo_cache_sentinel")?(y=o.jsx(o.Fragment,{}),t[0]=y):y=t[0],y}const r=vs(s);r.indexOf(i)<0&&(i==="response"&&s.error?i="error":i==="error"&&"response"in s?i="response":i=r[0]);const n=ii[i],l="flow-detail",a="nav-tabs nav-tabs-sm";let d;t[1]!==e?(d=()=>e(Ve([])),t[1]=e,t[2]=d):d=t[2];let f;t[3]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("i",{className:"fa fa-times-circle"}),t[3]=f):f=t[3];let p;t[4]!==d?(p=o.jsx("button",{"data-testid":"close-button-id",className:"close-button",onClick:d,children:f}),t[4]=d,t[5]=p):p=t[5];const h=r.map(y=>o.jsx("a",{href:"#",className:je({active:i===y}),onClick:w=>{w.preventDefault(),e(Ut(y))},children:ii[y].displayName},y));let g;t[6]!==p||t[7]!==h?(g=o.jsxs("nav",{className:a,children:[p,h]}),t[6]=p,t[7]=h,t[8]=g):g=t[8];let _;t[9]!==n||t[10]!==s?(_=o.jsx(n,{flow:s}),t[9]=n,t[10]=s,t[11]=_):_=t[11];let j;return t[12]!==g||t[13]!==_?(j=o.jsxs("div",{className:l,children:[g,_]}),t[12]=g,t[13]=_,t[14]=j):j=t[14],j}function id(t){return t.ui.flow.tab}function rd(t){return t.flows.selected[0]}function od(t){if(t.ctrlKey||t.metaKey)return()=>{};const e=t.key;return t.preventDefault(),(s,i)=>{const{flows:r}=i(),n=r.selected,l=n[0];switch(e){case"k":case"ArrowUp":s(ht(r,-1));break;case"j":case"ArrowDown":s(ht(r,1));break;case" ":case"PageDown":s(ht(r,10));break;case"PageUp":s(ht(r,-10));break;case"End":s(ht(r,1e10));break;case"Home":s(ht(r,-1e10));break;case"Escape":i().ui.modal.activeModal?s(Wi()):s(Ve([]));break;case"ArrowLeft":{if(!l)break;const a=vs(l),d=i().ui.flow.tab,f=a[(Math.max(0,a.indexOf(d))-1+a.length)%a.length];s(Ut(f));break}case"Tab":case"ArrowRight":{if(!l)break;const a=vs(l),d=i().ui.flow.tab,f=a[(Math.max(0,a.indexOf(d))+1)%a.length];s(Ut(f));break}case"Delete":case"d":{s(Ii(n));break}case"n":{Bt("view.flows.create","get","https://example.com/");break}case"D":{s(Li(n));break}case"a":{s(ys(n));break}case"A":{s(Di());break}case"r":{s(ws(n));break}case"v":{s(Pi(n));break}case"x":{s(Fi(n));break}case"X":{s(Zl());break}case"z":{s(Oi());break}default:return}}}class ld extends I.Component{static defaultProps={axis:"x"};node=Te.createRef();constructor(e,s){super(e,s),this.state={applied:!1,startPos:0,dragPointer:.1},this.onLostPointerCapture=this.onLostPointerCapture.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this)}onPointerDown(e){this.state.dragPointer===.1&&(e.target.setPointerCapture(e.pointerId),this.setState({startPos:this.props.axis==="x"?e.pageX:e.pageY,dragPointer:e.pointerId}))}onLostPointerCapture(e){if(this.state.dragPointer!==e.pointerId)return;const s=this.node.current,i=s.previousElementSibling,r=s.nextElementSibling;s.style.transform="",i.style.flex=`0 0 ${Math.max(0,(this.props.axis==="x"?i.offsetWidth+e.pageX:i.offsetHeight+e.pageY)-this.state.startPos)}px`,r.style.flex="1 1 auto",this.setState({applied:!0,dragPointer:.1}),this.onResize()}onPointerMove(e){this.state.dragPointer===e.pointerId&&(this.node.current.style.transform=this.props.axis==="x"?`translateX(${e.pageX-this.state.startPos}px)`:`translateY(${e.pageY-this.state.startPos}px)`)}onResize(){window.setTimeout(()=>window.dispatchEvent(new CustomEvent("resize")),1)}reset(e){this.state.applied&&(this.node.current?.previousElementSibling instanceof HTMLElement&&(this.node.current.previousElementSibling.style.flex=""),this.node.current?.nextElementSibling instanceof HTMLElement&&(this.node.current.nextElementSibling.style.flex=""),e||this.setState({applied:!1}),this.onResize())}componentWillUnmount(){this.reset(!0)}render(){return o.jsx("div",{ref:this.node,className:je("splitter",this.props.axis==="x"?"splitter-x":"splitter-y"),children:o.jsx("div",{onLostPointerCapture:this.onLostPointerCapture,onPointerDown:this.onPointerDown,onPointerMove:this.onPointerMove})})}}const Es=t=>{const e=t.current;return e===null||e.scrollTop===0?!1:Math.ceil(e.scrollTop)+e.clientHeight>=e.scrollHeight},Jr=t=>{t.current&&!Es(t)&&(t.current.scrollTop=t.current.scrollHeight)};function kt(t=void 0){if(!t)return{start:0,end:0,paddingTop:0,paddingBottom:0};const{itemCount:e,rowHeight:s,viewportTop:i,viewportHeight:r,itemHeights:n}=t,l=i+r;let a=0,d=0,f=0,p=0;if(n){let h=0;for(let g=0;g0&&ho.jsx("td",{className:je("col-tls",t.client_conn.tls_established?"col-tls-https":"col-tls-http")});Ts.headerName="";const Rs=({rowNumber:t})=>o.jsx("td",{className:"col-index",children:t+1});Rs.headerName="#";const As=({flow:t})=>o.jsx("td",{className:"col-icon",children:o.jsx("div",{className:je("resource-icon",Si(t))})});As.headerName="";const Ds=({flow:t})=>{let e;return t.error&&(t.error.msg==="Connection killed."?e=o.jsx("i",{className:"fa fa-fw fa-times pull-right"}):e=o.jsx("i",{className:"fa fa-fw fa-exclamation pull-right"})),o.jsxs("td",{className:"col-path",children:[t.is_replay==="request"&&o.jsx("i",{className:"fa fa-fw fa-repeat pull-right"}),t.intercepted&&o.jsx("i",{className:"fa fa-fw fa-pause pull-right"}),e,o.jsx("span",{className:"marker pull-right",children:t.marked}),$i(t)]})};Ds.headerName="Path";const Fs=({flow:t})=>o.jsx("td",{className:"col-method",children:Ni(t)});Fs.headerName="Method";const Is=({flow:t})=>o.jsx("td",{className:"col-http-version",children:ki(t)});Is.headerName="Version";const Ls=({flow:t})=>{let e="darkred";return t.type!=="http"&&t.type!="dns"||!t.response?o.jsx("td",{className:"col-status"}):(100<=t.response.status_code&&t.response.status_code<200?e="green":200<=t.response.status_code&&t.response.status_code<300?e="darkgreen":300<=t.response.status_code&&t.response.status_code<400?e="lightblue":(400<=t.response.status_code&&t.response.status_code<500||500<=t.response.status_code&&t.response.status_code<600)&&(e="red"),o.jsx("td",{className:"col-status",style:{color:e},children:Ci(t)}))};Ls.headerName="Status";const Ps=({flow:t})=>o.jsx("td",{className:"col-size",children:hi(wi(t))});Ps.headerName="Size";const Os=({flow:t})=>{const e=Wt(t),s=yi(t);return o.jsx("td",{className:"col-time",children:e&&s?mi(1e3*(s-e)):"..."})};Os.headerName="Time";const Ms=({flow:t})=>{const e=Wt(t);return o.jsx("td",{className:"col-timestamp",children:e?at(e):"..."})};Ms.headerName="Start time";const Qt=({flow:t})=>{const e=G();let s=null;return t.intercepted?s=o.jsx("a",{href:"#",className:"quickaction",onClick:()=>e(ys([t])),children:o.jsx("i",{className:"fa fa-fw fa-play text-success"})}):xs(t)&&(s=o.jsx("a",{href:"#",className:"quickaction",onClick:()=>e(ws([t])),children:o.jsx("i",{className:"fa fa-fw fa-repeat text-primary"})})),o.jsx("td",{className:"col-quickactions",children:s?o.jsx("div",{children:s}):o.jsx(o.Fragment,{})})};Qt.headerName="";const qs=({flow:t})=>{const e=t.comment;return o.jsx("td",{className:"col-comment",children:e})};qs.headerName="Comment";const Qr={icon:As,index:Rs,method:Fs,version:Is,path:Ds,quickactions:Qt,size:Ps,status:Ls,time:Os,timestamp:Ms,tls:Ts,comment:qs},cd=Object.freeze(Object.defineProperty({__proto__:null,comment:qs,default:Qr,icon:As,index:Rs,method:Fs,path:Ds,quickactions:Qt,size:Ps,status:Ls,time:Os,timestamp:Ms,tls:Ts,version:Is},Symbol.toStringTag,{value:"Module"})),ad=I.memo(function(){const e=k.c(13),s=G(),i=D(dd),r=D(ud),n=D(fd),l=i?"sort-desc":"sort-asc";let a;if(e[0]!==s||e[1]!==n||e[2]!==r||e[3]!==i||e[4]!==l){const f=n.filter(zl).concat("quickactions");let p;e[6]!==s||e[7]!==r||e[8]!==i||e[9]!==l?(p=h=>o.jsx("th",{className:je(`col-${h}`,r===h&&l),onClick:()=>s(Ui({column:h===r&&i?void 0:h,desc:h!==r?!1:!i})),children:Qr[h].headerName},h),e[6]=s,e[7]=r,e[8]=i,e[9]=l,e[10]=p):p=e[10],a=f.map(p),e[0]=s,e[1]=n,e[2]=r,e[3]=i,e[4]=l,e[5]=a}else a=e[5];let d;return e[11]!==a?(d=o.jsx("tr",{children:a}),e[11]=a,e[12]=d):d=e[12],d});function dd(t){return t.flows.sort.desc}function ud(t){return t.flows.sort.column}function fd(t){return t.options.web_columns}const pd=Te.memo(function({flow:e,selected:s,highlighted:i,displayColumnNames:r,rowNumber:n}){const l=G(),a=je({selected:s,highlighted:i,intercepted:e.intercepted,"has-request":e.type==="http"&&e.request,"has-response":e.type==="http"&&e.response}),d=I.useCallback(p=>{let h=p.target;for(;h.parentNode;){if(h.classList.contains("col-quickactions"))return;h=h.parentNode}p.metaKey||p.ctrlKey?l(ic(e)):p.shiftKey?(window.getSelection()?.empty(),l(rc(e))):l(Ve([e]))},[e]),f=r.map(p=>cd[p]).filter(p=>p).concat(Qt);return o.jsx("tr",{className:a,onClick:d,children:f.map(p=>o.jsx(p,{flow:e,rowNumber:n},p.name))})});class hd extends I.Component{static defaultProps={rowHeight:32};viewport=I.createRef();head=I.createRef();constructor(e,s){super(e,s),this.state={vScroll:kt(),viewportTop:0},this.onViewportUpdate=this.onViewportUpdate.bind(this)}componentDidMount(){window.addEventListener("resize",this.onViewportUpdate),this.onViewportUpdate()}componentWillUnmount(){window.removeEventListener("resize",this.onViewportUpdate)}getSnapshotBeforeUpdate(){return Es(this.viewport)}componentDidUpdate(e,s,i){i&&Jr(this.viewport),this.onViewportUpdate();const{onlySelectedId:r}=this.props;if(r&&r!==e.onlySelectedId){const{rowHeight:l,firstSelectedIndex:a}=this.props,d=this.viewport.current,f=this.head.current,p=f?f.offsetHeight:0,h=a*l+p,g=h+l,_=d.scrollTop,j=d.offsetHeight;h-p<_?d.scrollTop=h-p:g>_+j&&(d.scrollTop=g-j),this.onViewportUpdate()}}onViewportUpdate(){const e=this.viewport.current,s=e.scrollTop||0,i=kt({viewportTop:s,viewportHeight:e.offsetHeight||0,itemCount:this.props.flowView.length,rowHeight:this.props.rowHeight});if(this.state.viewportTop!==s||!Kt(this.state.vScroll,i)){const r=Math.min(s,i.end*this.props.rowHeight);this.setState({vScroll:i,viewportTop:r})}}render(){const{vScroll:e,viewportTop:s}=this.state,{flowView:i,selectedIds:r,highlightedIds:n,displayColumnNames:l,listIndex:a}=this.props;return o.jsx("div",{className:"flow-table",onScroll:this.onViewportUpdate,ref:this.viewport,children:o.jsxs("table",{children:[o.jsx("thead",{ref:this.head,style:{transform:`translateY(${s}px)`},children:o.jsx(ad,{})}),o.jsxs("tbody",{children:[o.jsx("tr",{style:{height:e.paddingTop}}),i.slice(e.start,e.end).map(d=>o.jsx(pd,{flow:d,selected:r.has(d.id),highlighted:n.has(d.id),displayColumnNames:l,rowNumber:a.get(d.id)},d.id)),o.jsx("tr",{style:{height:e.paddingBottom}})]})]})})}}const md=zt(t=>({flowView:t.flows.view,highlightedIds:t.flows.highlightedIds,selectedIds:t.flows.selectedIds,onlySelectedId:t.flows.selected.length===1&&t.flows.selected[0].id,firstSelectedIndex:t.flows._viewIndex.get(t.flows.selected[0]?.id),displayColumnNames:t.options.web_columns,listIndex:t.flows._listIndex}))(hd);function gd(){const t=k.c(3);let e,s;t[0]===Symbol.for("react.memo_cache_sentinel")?(e={padding:"1em 2em"},s=o.jsx("h3",{children:"mitmproxy is running."}),t[0]=e,t[1]=s):(e=t[0],s=t[1]);let i;return t[2]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsxs("div",{style:e,children:[s,o.jsxs("p",{children:["No flows have been recorded yet.",o.jsx("br",{}),"To start capturing traffic, please configure your settings in the Capture tab."]})]}),t[2]=i):i=t[2],i}function vd(t){const e=k.c(20);let{description:s,listen_addrs:i,is_running:r,wireguard_conf:n,type:l}=t;const a=I.useRef(null);let d,f;e[0]!==n?(d=()=>{n&&a.current&&Ll.toCanvas(a.current,n,{margin:0,scale:3})},f=[n],e[0]=n,e[1]=d,e[2]=f):(d=e[1],f=e[2]),I.useEffect(d,f);let p;const h=i.length===1||i.length===2&&i[0][1]===i[1][1],g=i.every(xd);if(h&&g){let y;e[3]!==i[0][1]?(y=Hn(["*",i[0][1]]),e[3]=i[0][1],e[4]=y):y=e[4],p=y}else{let y;e[5]!==i?(y=i.map(Hn).join(" and "),e[5]=i,e[6]=y):y=e[6],p=y}s=s[0].toUpperCase()+s.substr(1);let _;if(r){let y;e[9]!==s||e[10]!==p||e[11]!==l?(y=l==="local"?o.jsxs("div",{className:"text-success",children:[s," is active."]}):o.jsxs("div",{className:"text-success",children:[s," listening at ",p,"."]}),e[9]=s,e[10]=p,e[11]=l,e[12]=y):y=e[12];let w;e[13]!==n?(w=n&&o.jsxs("div",{className:"wireguard-config",children:[o.jsx("pre",{children:n}),o.jsx("canvas",{ref:a})]}),e[13]=n,e[14]=w):w=e[14];let $;e[15]!==y||e[16]!==w?($=o.jsxs(o.Fragment,{children:[y,w]}),e[15]=y,e[16]=w,e[17]=$):$=e[17],_=$}else{let y;e[7]!==s?(y=o.jsx(o.Fragment,{children:o.jsxs("div",{className:"text-warning",children:[s," starting..."]})}),e[7]=s,e[8]=y):y=e[8],_=y}let j;return e[18]!==_?(j=o.jsx("div",{children:_}),e[18]=_,e[19]=j):j=e[19],j}function xd(t){return["::","0.0.0.0"].includes(t[0])}function et(t){const e=k.c(5),{error:s,backendState:i}=t;let r;e[0]!==i||e[1]!==s?(r=s?o.jsx("div",{className:"text-danger",children:s}):i&&o.jsx(vd,{...i}),e[0]=i,e[1]=s,e[2]=r):r=e[2];let n;return e[3]!==r?(n=o.jsx("div",{className:"mode-status",children:r}),e[3]=r,e[4]=n):n=e[4],n}function tt(t){const e=k.c(13),{value:s,onChange:i,children:r,label:n}=t,l=I.useId(),a=`mode-checkbox-${l}`,d=`mode-checkbox-${l}`;let f;e[0]!==i||e[1]!==a||e[2]!==d||e[3]!==s?(f=o.jsx("input",{type:"checkbox",name:a,id:d,checked:s,onChange:i}),e[0]=i,e[1]=a,e[2]=d,e[3]=s,e[4]=f):f=e[4];const p=`mode-checkbox-${l}`;let h;e[5]===Symbol.for("react.memo_cache_sentinel")?(h={marginBottom:0,fontWeight:"normal"},e[5]=h):h=e[5];let g;e[6]!==n||e[7]!==p?(g=o.jsx("label",{htmlFor:p,style:h,children:n}),e[6]=n,e[7]=p,e[8]=g):g=e[8];let _;return e[9]!==r||e[10]!==f||e[11]!==g?(_=o.jsxs("div",{className:"mode-entry",children:[f,g,r]}),e[9]=r,e[10]=f,e[11]=g,e[12]=_):_=e[12],_}function st(t){const e=k.c(22),{children:s,iconClass:i,classname:r,isVisible:n}=t,l=I.useId();let a;e[0]!==l?(a=[...l].map(_d),e[0]=l,e[1]=a):a=e[1];const d="--"+a.join(""),f=I.useRef(null),p=I.useRef(null);let h;e[2]!==d?(h=()=>{f.current.style.anchorName=d,p.current.style.positionAnchor=d},e[2]=d,e[3]=h):h=e[3];let g;e[4]===Symbol.for("react.memo_cache_sentinel")?(g=[],e[4]=g):g=e[4],I.useEffect(h,g);let _;e[5]!==l||e[6]!==n?(_=()=>{n===!0&&document.getElementById(l)?.showPopover()},e[5]=l,e[6]=n,e[7]=_):_=e[7];let j;e[8]!==n?(j=[n],e[8]=n,e[9]=j):j=e[9],I.useEffect(_,j);const y=r?`mode-popover ${r}`:"mode-popover";let w;e[10]!==i?(w=o.jsx("i",{className:i,"aria-hidden":"true"}),e[10]=i,e[11]=w):w=e[11];let $;e[12]!==l||e[13]!==w?($=o.jsx("button",{popoverTarget:l,ref:f,children:w}),e[12]=l,e[13]=w,e[14]=$):$=e[14];let N;e[15]!==s||e[16]!==l?(N=o.jsx("div",{id:l,popover:"auto",ref:p,children:s}),e[15]=s,e[16]=l,e[17]=N):N=e[17];let E;return e[18]!==y||e[19]!==$||e[20]!==N?(E=o.jsxs("div",{className:y,children:[$,N]}),e[18]=y,e[19]=$,e[20]=N,e[21]=E):E=e[21],E}function _d(t){return t.charCodeAt(0).toString(16)}function jd(t){const e=k.c(44),{server:s}=t,{currentProcesses:i,isLoading:r}=D(bd),{selectedProcesses:n}=D(wd);let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l=[],e[0]=l):l=e[0];const[a,d]=I.useState(l),[f,p]=I.useState(""),h=G(),{platform:g}=D(yd);let _;e[1]===Symbol.for("react.memo_cache_sentinel")?(_=B=>{p(B.target.value)},e[1]=_):_=e[1];const j=_;let y;e[2]!==g?(y=B=>{const oe=g.startsWith("win32")?"\\":"/";return ps(B.executable,oe)[1]},e[2]=g,e[3]=y):y=e[3];const w=y;let $;e[4]!==h||e[5]!==w||e[6]!==n||e[7]!==s?($=B=>{const oe=typeof B=="string"?B:w(B),q=n?`${n}, ${oe}`:oe;h(St({server:s,value:q}))},e[4]=h,e[5]=w,e[6]=n,e[7]=s,e[8]=$):$=e[8];const N=$;let E;e[9]!==h||e[10]!==w||e[11]!==n||e[12]!==s?(E=B=>{const oe=n?.split(/,\s*/).filter(q=>q!==w(B)).join(", ");h(St({server:s,value:oe}))},e[9]=h,e[10]=w,e[11]=n,e[12]=s,e[13]=E):E=e[13];const T=E,P=B=>{L(B)&&n?T(B):N(B)},L=B=>{const oe=w(B);return n?.includes(oe)};let O;e[14]!==i||e[15]!==h?(O=()=>{i.length===0&&h($t())},e[14]=i,e[15]=h,e[16]=O):O=e[16];let M;e[17]===Symbol.for("react.memo_cache_sentinel")?(M=[],e[17]=M):M=e[17],I.useEffect(O,M);let U;e[18]!==i||e[19]!==f||e[20]!==w||e[21]!==a?(U=()=>{if(f){const B=i.filter(oe=>w(oe).toLowerCase().includes(f.toLowerCase()));d(B)}else a!==i&&d(i)},e[18]=i,e[19]=f,e[20]=w,e[21]=a,e[22]=U):U=e[22];let V;e[23]!==i||e[24]!==f?(V=[f,i],e[23]=i,e[24]=f,e[25]=V):V=e[25],I.useEffect(U,V);let W;e[26]!==N||e[27]!==f?(W=B=>{B.stopPropagation(),B.key==="Enter"&&(N(f),p(""))},e[26]=N,e[27]=f,e[28]=W):W=e[28];const J=W,[z,te]=I.useState(!1),Y="local-dropdown",Q="dropdown-header",X=n&&n?.length>0?"Add more":"all applications";let Z,ae;e[29]===Symbol.for("react.memo_cache_sentinel")?(Z=()=>te(!0),ae=()=>te(!1),e[29]=Z,e[30]=ae):(Z=e[29],ae=e[30]);let le;e[31]!==f||e[32]!==J||e[33]!==X?(le=o.jsx("input",{type:"text",className:"autocomplete-input",placeholder:X,value:f,onChange:j,onKeyDown:J,onClick:Z,onBlur:ae}),e[31]=f,e[32]=J,e[33]=X,e[34]=le):le=e[34];const de=st,ye="fa fa-chevron-down",Pe="local-popover";let Se;e[35]===Symbol.for("react.memo_cache_sentinel")?(Se=o.jsx("h4",{children:"Current Applications running on machine"}),e[35]=Se):Se=e[35];const Ee=r?o.jsx("i",{className:"fa fa-spinner","aria-hidden":"true"}):a.length>0?o.jsxs("ul",{className:"dropdown-list",children:[o.jsxs("li",{className:`dropdown-item ${n===""?"selected":""}`,onClick:()=>{h(St({server:s,value:""}))},role:"menuitem",children:[o.jsxs("div",{className:"process-details",children:[o.jsx("div",{className:"process-icon"}),o.jsx("span",{className:"process-name",children:"All applications"})]}),n===""&&o.jsx("i",{className:"fa fa-check","aria-hidden":"true"})]}),o.jsx("hr",{className:"process-separator"}),a.map((B,oe)=>o.jsxs("li",{className:`dropdown-item ${L(B)?"selected":""}`,onClick:()=>P(B),role:"menuitem",children:[o.jsxs("div",{className:"process-details",children:[o.jsx("img",{className:"process-icon",src:`./executable-icon?path=${B.executable}`,loading:"lazy"}),o.jsx("span",{className:"process-name",children:w(B)})]}),L(B)&&o.jsx("i",{className:"fa fa-check","aria-hidden":"true"})]},oe))]}):o.jsxs("span",{children:["Press ",o.jsx("strong",{children:"Enter"})," to capture traffic for programs matching: ",o.jsx("strong",{children:f})]});let C;e[36]!==de||e[37]!==z||e[38]!==Se||e[39]!==Ee?(C=o.jsxs(de,{iconClass:ye,classname:Pe,isVisible:z,children:[Se,Ee]}),e[36]=de,e[37]=z,e[38]=Se,e[39]=Ee,e[40]=C):C=e[40];let he;return e[41]!==le||e[42]!==C?(he=o.jsx("div",{className:Y,children:o.jsxs("div",{className:Q,children:[le,C]})}),e[41]=le,e[42]=C,e[43]=he):he=e[43],he}function yd(t){return t.backendState}function wd(t){return t.modes.local[0]}function bd(t){return t.processes}function Sd(){const t=k.c(9),e=D(Cd),s=D($d);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Nd,{server:f,backendState:s[Zi(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Local Applications"}),l=o.jsx("p",{className:"mode-description",children:"Transparently Intercept local application(s)."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function $d(t){return t.backendState.servers}function Cd(t){return t.modes.local}function Nd(t){const e=k.c(31),{server:s,backendState:i}=t,r=G(),n=D(Ed),l=s.error||i?.last_exception||n||void 0;let a;e[0]!==r||e[1]!==s?(a=E=>{const T=s.selectedProcesses?.split(/,\s*/).filter(P=>P!==E).join(", ");r(St({server:s,value:T}))},e[0]=r,e[1]=s,e[2]=a):a=e[2];const d=a;let f;e[3]!==r||e[4]!==s?(f=()=>r(cr({server:s,value:!s.active})),e[3]=r,e[4]=s,e[5]=f):f=e[5];let p;e[6]!==d||e[7]!==s.selectedProcesses?(p=s.selectedProcesses?.split(/,\s*/).filter(kd).map(E=>o.jsxs("div",{className:"selected-process",children:[E,o.jsx("i",{className:"fa fa-times","aria-hidden":"true",onClick:()=>d(E)})]},E)),e[6]=d,e[7]=s.selectedProcesses,e[8]=p):p=e[8];let h;e[9]!==p?(h=o.jsx("div",{className:"selected-processes",children:p}),e[9]=p,e[10]=h):h=e[10];let g;e[11]!==s?(g=o.jsx(jd,{server:s}),e[11]=s,e[12]=g):g=e[12];let _;e[13]!==r?(_=o.jsx("i",{className:"fa fa-refresh","aria-hidden":"true",onClick:()=>r($t())}),e[13]=r,e[14]=_):_=e[14];let j;e[15]!==g||e[16]!==_?(j=o.jsxs("div",{className:"dropdown-container",children:[g,_]}),e[15]=g,e[16]=_,e[17]=j):j=e[17];let y;e[18]!==h||e[19]!==j?(y=o.jsxs("div",{className:"processes-container",children:[h,j]}),e[18]=h,e[19]=j,e[20]=y):y=e[20];let w;e[21]!==s.active||e[22]!==f||e[23]!==y?(w=o.jsx(tt,{value:s.active,label:"Intercept traffic for",onChange:f,children:y}),e[21]=s.active,e[22]=f,e[23]=y,e[24]=w):w=e[24];let $;e[25]!==i||e[26]!==l?($=o.jsx(et,{error:l,backendState:i}),e[25]=i,e[26]=l,e[27]=$):$=e[27];let N;return e[28]!==$||e[29]!==w?(N=o.jsxs("div",{className:"mode-local",children:[w,$]}),e[28]=$,e[29]=w,e[30]=N):N=e[30],N}function kd(t){return t.trim()!==""}function Ed(t){return t.processes.error}function Td(){const t=k.c(9),e=D(Ad),s=D(Rd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Dd,{server:f,backendState:s[Xi(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Explicit HTTP(S) Proxy"}),l=o.jsx("p",{className:"mode-description",children:"You manually configure your client application or device to use an HTTP(S) proxy."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Rd(t){return t.backendState.servers}function Ad(t){return t.modes.regular}function Dd(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(rr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(or({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(lr({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run HTTP/S Proxy",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function Fd(){const t=k.c(9),e=D(Ld),s=D(Id);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Pd,{server:f,backendState:s[er(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"WireGuard Server"}),l=o.jsx("p",{className:"mode-description",children:"Start a WireGuard™ server and connect an external device for transparent proxying."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Id(t){return t.backendState.servers}function Ld(t){return t.modes.wireguard}function Pd(t){const e=k.c(41),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(ar({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=M=>r(dr({server:s,value:M})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,placeholder:"(all interfaces)",onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=M=>r(ur({server:s,value:parseInt(M)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"51820",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]===Symbol.for("react.memo_cache_sentinel")?(w=o.jsx("p",{children:"Configuration File"}),e[20]=w):w=e[20];const $=s.file_path||"";let N;e[21]!==r||e[22]!==s?(N=M=>r(fr({server:s,value:M})),e[21]=r,e[22]=s,e[23]=N):N=e[23];let E;e[24]!==$||e[25]!==N?(E=o.jsx(ce,{className:"mode-input",content:$,placeholder:"~/.mitmproxy/wireguard.conf",onEditDone:N}),e[24]=$,e[25]=N,e[26]=E):E=e[26];let T;e[27]!==y||e[28]!==E||e[29]!==h?(T=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y,w,E]}),e[27]=y,e[28]=E,e[29]=h,e[30]=T):T=e[30];let P;e[31]!==s.active||e[32]!==l||e[33]!==T?(P=o.jsx(tt,{value:s.active,label:"Run WireGuard Server",onChange:l,children:T}),e[31]=s.active,e[32]=l,e[33]=T,e[34]=P):P=e[34];let L;e[35]!==i||e[36]!==n?(L=o.jsx(et,{error:n,backendState:i}),e[35]=i,e[36]=n,e[37]=L):L=e[37];let O;return e[38]!==P||e[39]!==L?(O=o.jsxs("div",{children:[P,L]}),e[38]=P,e[39]=L,e[40]=O):O=e[40],O}function Od(){const t=k.c(15),e=G(),s=D(qd),i=D(Md);let r,n;t[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("h4",{className:"mode-title",children:"Reverse Proxy"}),n=o.jsx("p",{className:"mode-description",children:"Requests are forwarded to a preconfigured destination."}),t[0]=r,t[1]=n):(r=t[0],n=t[1]);let l;if(t[2]!==i||t[3]!==s){let h;t[5]!==i?(h=(g,_)=>o.jsx(Hd,{removable:_>0,server:g,backendState:i[Ns(g)]},g.ui_id),t[5]=i,t[6]=h):h=t[6],l=s.map(h),t[2]=i,t[3]=s,t[4]=l}else l=t[4];let a;t[7]!==e?(a=()=>e(na()),t[7]=e,t[8]=a):a=t[8];let d;t[9]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("i",{className:"fa fa-plus-square-o","aria-hidden":"true"}),t[9]=d):d=t[9];let f;t[10]!==a?(f=o.jsxs("div",{className:"mode-reverse-add-server",onClick:a,children:[d,"Add additional server"]}),t[10]=a,t[11]=f):f=t[11];let p;return t[12]!==l||t[13]!==f?(p=o.jsxs("div",{children:[r,n,o.jsxs("div",{className:"mode-reverse-servers",children:[l,f]})]}),t[12]=l,t[13]=f,t[14]=p):p=t[14],p}function Md(t){return t.backendState.servers}function qd(t){return t.modes.reverse}function Hd(t){const e=k.c(56),{removable:s,server:i,backendState:r}=t,n=G();let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l=Object.values(Jt),e[0]=l):l=e[0];const a=l;let d;e[1]!==n||e[2]!==i?(d=async()=>{i.active&&await n(ms({server:i,value:!1})).unwrap(),await n(ia(i))},e[1]=n,e[2]=i,e[3]=d):d=e[3];const f=d,p=i.error||r?.last_exception||void 0,h=i.active;let g;e[4]!==n||e[5]!==i?(g=()=>{n(ms({server:i,value:!i.active}))},e[4]=n,e[5]=i,e[6]=g):g=e[6];const _=i.protocol;let j;e[7]!==n||e[8]!==i?(j=Z=>{n(mr({server:i,value:Z.target.value}))},e[7]=n,e[8]=i,e[9]=j):j=e[9];let y;e[10]===Symbol.for("react.memo_cache_sentinel")?(y=a.map(Vd),e[10]=y):y=e[10];let w;e[11]!==i.protocol||e[12]!==j?(w=o.jsx("select",{name:"protocols",className:"mode-reverse-dropdown",value:_,onChange:j,children:y}),e[11]=i.protocol,e[12]=j,e[13]=w):w=e[13];let $;e[14]!==i.destination?($=i.destination?.toString()||"",e[14]=i.destination,e[15]=$):$=e[15];let N;e[16]!==n||e[17]!==i?(N=Z=>n(gr({server:i,value:Z})),e[16]=n,e[17]=i,e[18]=N):N=e[18];let E;e[19]!==N||e[20]!==$?(E=o.jsx(ce,{className:"mode-reverse-input",content:$,onEditDone:N,placeholder:"example.com"}),e[19]=N,e[20]=$,e[21]=E):E=e[21];let T,P;e[22]===Symbol.for("react.memo_cache_sentinel")?(T=o.jsx("h4",{children:"Advanced Configuration"}),P=o.jsx("p",{children:"Listen Host"}),e[22]=T,e[23]=P):(T=e[22],P=e[23]);const L=i.listen_host||"";let O;e[24]!==n||e[25]!==i?(O=Z=>n(pr({server:i,value:Z})),e[24]=n,e[25]=i,e[26]=O):O=e[26];let M;e[27]!==L||e[28]!==O?(M=o.jsx(ce,{className:"mode-input",content:L,onEditDone:O,placeholder:"*"}),e[27]=L,e[28]=O,e[29]=M):M=e[29];let U;e[30]===Symbol.for("react.memo_cache_sentinel")?(U=o.jsx("p",{children:"Listen Port"}),e[30]=U):U=e[30];const V=String(i.listen_port||"");let W;e[31]!==n||e[32]!==i?(W=Z=>n(hr({server:i,value:Z})),e[31]=n,e[32]=i,e[33]=W):W=e[33];let J;e[34]!==V||e[35]!==W?(J=o.jsx(ce,{className:"mode-input",content:V,onEditDone:W,placeholder:"8080"}),e[34]=V,e[35]=W,e[36]=J):J=e[36];let z;e[37]!==M||e[38]!==J?(z=o.jsxs(st,{iconClass:"fa fa-cog",children:[T,P,M,U,J]}),e[37]=M,e[38]=J,e[39]=z):z=e[39];let te;e[40]!==f||e[41]!==s?(te=s&&o.jsx("i",{className:"fa fa-fw fa-trash fa-lg","aria-hidden":"true",onClick:f}),e[40]=f,e[41]=s,e[42]=te):te=e[42];let Y;e[43]!==i.active||e[44]!==E||e[45]!==z||e[46]!==te||e[47]!==g||e[48]!==w?(Y=o.jsxs(tt,{value:h,label:"Forward",onChange:g,children:[w,"traffic to",E,z,te]}),e[43]=i.active,e[44]=E,e[45]=z,e[46]=te,e[47]=g,e[48]=w,e[49]=Y):Y=e[49];let Q;e[50]!==r||e[51]!==p?(Q=o.jsx(et,{error:p,backendState:r}),e[50]=r,e[51]=p,e[52]=Q):Q=e[52];let X;return e[53]!==Y||e[54]!==Q?(X=o.jsxs("div",{children:[Y,Q]}),e[53]=Y,e[54]=Q,e[55]=X):X=e[55],X}function Vd(t){return o.jsx("option",{value:t,children:t},t)}function Ud(){const t=k.c(9),e=D(Wd),s=D(Bd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Kd,{server:f,backendState:s[tr(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Transparent Proxy"}),t[5]=n):n=t[5];let l;t[6]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsxs("p",{className:"mode-description",children:["You"," ",o.jsx("a",{href:"https://docs.mitmproxy.org/stable/howto-transparent/",style:{textDecoration:"underline",color:"inherit"},children:"configure your routing table"})," ","to send traffic through mitmproxy."]}),t[6]=l):l=t[6];let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Bd(t){return t.backendState.servers}function Wd(t){return t.modes.transparent}function Kd(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(xr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(_r({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(jr({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run Transparent Proxy",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function zd(){const t=k.c(9),e=D(Yd),s=D(Gd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Jd,{server:f,backendState:s[sr(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"SOCKS Proxy"}),l=o.jsx("p",{className:"mode-description",children:"You manually configure your client application or device to use a SOCKS5 proxy."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Gd(t){return t.backendState.servers}function Yd(t){return t.modes.socks}function Jd(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(yr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(wr({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(br({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run SOCKS Proxy",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function Qd(){const t=k.c(9),e=D(Zd),s=D(Xd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(eu,{server:f,backendState:s[nr(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Explicit HTTP(S) Proxy (With Upstream Proxy)"}),l=o.jsx("p",{className:"mode-description",children:"All requests are forwarded to a second HTTP(S) proxy server."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Xd(t){return t.backendState.servers}function Zd(t){return t.modes.upstream}function eu(t){const e=k.c(42),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>{r(Sr({server:s,value:!s.active}))},e[0]=r,e[1]=s,e[2]=l):l=e[2];let a;e[3]!==s.destination?(a=s.destination?.toString()||"",e[3]=s.destination,e[4]=a):a=e[4];let d;e[5]!==r||e[6]!==s?(d=O=>r(Nr({server:s,value:O})),e[5]=r,e[6]=s,e[7]=d):d=e[7];let f;e[8]!==a||e[9]!==d?(f=o.jsx(ce,{className:"mode-upstream-input",content:a,onEditDone:d,placeholder:"http://example.com:8080"}),e[8]=a,e[9]=d,e[10]=f):f=e[10];let p,h;e[11]===Symbol.for("react.memo_cache_sentinel")?(p=o.jsx("h4",{children:"Advanced Configuration"}),h=o.jsx("p",{children:"Listen Host"}),e[11]=p,e[12]=h):(p=e[11],h=e[12]);const g=s.listen_host||"";let _;e[13]!==r||e[14]!==s?(_=O=>r($r({server:s,value:O})),e[13]=r,e[14]=s,e[15]=_):_=e[15];let j;e[16]!==g||e[17]!==_?(j=o.jsx(ce,{className:"mode-input",content:g,onEditDone:_}),e[16]=g,e[17]=_,e[18]=j):j=e[18];let y;e[19]===Symbol.for("react.memo_cache_sentinel")?(y=o.jsx("p",{children:"Listen Port"}),e[19]=y):y=e[19];let w;e[20]!==s.listen_port?(w=s.listen_port?s.listen_port.toString():"",e[20]=s.listen_port,e[21]=w):w=e[21];let $;e[22]!==r||e[23]!==s?($=O=>r(Cr({server:s,value:parseInt(O)})),e[22]=r,e[23]=s,e[24]=$):$=e[24];let N;e[25]!==w||e[26]!==$?(N=o.jsx(ce,{className:"mode-input",content:w,placeholder:"8080",onEditDone:$}),e[25]=w,e[26]=$,e[27]=N):N=e[27];let E;e[28]!==N||e[29]!==j?(E=o.jsxs(st,{iconClass:"fa fa-cog",children:[p,h,j,y,N]}),e[28]=N,e[29]=j,e[30]=E):E=e[30];let T;e[31]!==s.active||e[32]!==l||e[33]!==E||e[34]!==f?(T=o.jsxs(tt,{value:s.active,label:"Run HTTP/S Proxy and forward requests to",onChange:l,children:[f,E]}),e[31]=s.active,e[32]=l,e[33]=E,e[34]=f,e[35]=T):T=e[35];let P;e[36]!==i||e[37]!==n?(P=o.jsx(et,{error:n,backendState:i}),e[36]=i,e[37]=n,e[38]=P):P=e[38];let L;return e[39]!==T||e[40]!==P?(L=o.jsxs("div",{children:[T,P]}),e[39]=T,e[40]=P,e[41]=L):L=e[41],L}function tu(){const t=k.c(9),e=D(nu),s=D(su);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(iu,{server:f,backendState:s[ir(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"DNS Server"}),l=o.jsx("p",{className:"mode-description",children:"A recursive DNS resolver using the host's DNS configuration."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function su(t){return t.backendState.servers}function nu(t){return t.modes.dns}function iu(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(kr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(Er({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(Tr({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run DNS Server",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function ri(t){const e=k.c(10),{title:s,description:i}=t;let r;e[0]!==s?(r=o.jsx("h4",{className:"mode-title",children:s}),e[0]=s,e[1]=r):r=e[1];let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("i",{className:"fa fa-exclamation-triangle","aria-hidden":"true"}),e[2]=n):n=e[2];let l;e[3]!==r?(l=o.jsxs("div",{className:"title-icon-container",children:[r,n]}),e[3]=r,e[4]=l):l=e[4];let a;e[5]!==i?(a=o.jsx("p",{className:"mode-description",children:i}),e[5]=i,e[6]=a):a=e[6];let d;return e[7]!==l||e[8]!==a?(d=o.jsxs("div",{className:"missing-mode-container",children:[l,a]}),e[7]=l,e[8]=a,e[9]=d):d=e[9],d}function ru(){const t=k.c(19),{platform:e,localModeUnavailable:s}=D(ou);let i,r;t[0]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsx("h2",{children:"Intercept Traffic"}),r=o.jsx("p",{children:"Configure how you want to intercept traffic with mitmproxy."}),t[0]=i,t[1]=r):(i=t[0],r=t[1]);let n;t[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h3",{children:"Recommended"}),t[2]=n):n=t[2];let l;t[3]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsx(Td,{}),t[3]=l):l=t[3];let a;t[4]!==s?(a=s!==null?o.jsx(ri,{title:"Local Redirect Mode",description:s}):o.jsx(Sd,{}),t[4]=s,t[5]=a):a=t[5];let d,f;t[6]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx(Fd,{}),f=o.jsx(Od,{}),t[6]=d,t[7]=f):(d=t[6],f=t[7]);let p;t[8]!==a?(p=o.jsxs("div",{className:"modes-category green-left-border",children:[n,o.jsxs("div",{className:"modes-container",children:[l,a,d,f]})]}),t[8]=a,t[9]=p):p=t[9];let h;t[10]===Symbol.for("react.memo_cache_sentinel")?(h=o.jsx("h3",{children:"Advanced"}),t[10]=h):h=t[10];let g,_,j;t[11]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsx(zd,{}),g=o.jsx(Qd,{}),_=o.jsx(tu,{}),t[11]=g,t[12]=_,t[13]=j):(g=t[11],_=t[12],j=t[13]);let y;t[14]!==e?(y=o.jsxs("div",{className:"modes-category gray-left-border",children:[h,o.jsxs("div",{className:"modes-container",children:[j,g,_,e.startsWith("win32")?o.jsx(ri,{title:"Transparent Proxy",description:"This mode is only supported on Linux and MacOS."}):o.jsx(Ud,{})]})]}),t[14]=e,t[15]=y):y=t[15];let w;return t[16]!==y||t[17]!==p?(w=o.jsxs("div",{className:"modes",children:[i,r,p,y]}),t[16]=y,t[17]=p,t[18]=w):w=t[18],w}function ou(t){return t.backendState}function lu(){const t=k.c(4),e=D(du),s=D(au),i=D(cu);let r;return t[0]!==i||t[1]!==s||t[2]!==e?(r=o.jsx("div",{className:"main-view",children:i===xe.Capture?o.jsx(ru,{}):o.jsxs(o.Fragment,{children:[s?o.jsx(md,{}):o.jsx(gd,{}),e&&o.jsxs(o.Fragment,{children:[o.jsx(ld,{},"splitter"),o.jsx(nd,{},"flowDetails")]})]})}),t[0]=i,t[1]=s,t[2]=e,t[3]=r):r=t[3],r}function cu(t){return t.ui.tabs.current}function au(t){return t.flows.list.length>0}function du(t){return t.flows.selected.length===1}function gt(t){const e=k.c(2),{children:s}=t;let i;return e[0]!==s?(i=window.MITMWEB_STATIC?null:o.jsx(o.Fragment,{children:s}),e[0]=s,e[1]=i):i=e[1],i}const uu=I.memo(function(){const e=k.c(20),s=G(),i=D(fu);let r;e[0]===Symbol.for("react.memo_cache_sentinel")?(r={placement:"bottom-start"},e[0]=r):r=e[0];let n;e[1]!==s?(n=o.jsx("li",{children:o.jsx(Fr,{icon:"fa-folder-open",text:" Open...",onClick:pu,onOpenFile:w=>{s(tc(w)),document.body.click()}})}),e[1]=s,e[2]=n):n=e[2];let l;e[3]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsxs(ke,{onClick:hu,children:[o.jsx("i",{className:"fa fa-fw fa-floppy-o"})," Save"]}),e[3]=l):l=e[3];let a;e[4]!==i?(a=()=>location.replace("/flows/dump?filter="+i),e[4]=i,e[5]=a):a=e[5];let d;e[6]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("i",{className:"fa fa-fw fa-floppy-o"}),e[6]=d):d=e[6];let f;e[7]!==a?(f=o.jsxs(ke,{onClick:a,children:[d," Save filtered"]}),e[7]=a,e[8]=f):f=e[8];let p;e[9]!==s?(p=()=>confirm("Delete all flows?")&&s(Oi()),e[9]=s,e[10]=p):p=e[10];let h;e[11]===Symbol.for("react.memo_cache_sentinel")?(h=o.jsx("i",{className:"fa fa-fw fa-trash"}),e[11]=h):h=e[11];let g;e[12]!==p?(g=o.jsxs(ke,{onClick:p,children:[h," Clear All"]}),e[12]=p,e[13]=g):g=e[13];let _;e[14]===Symbol.for("react.memo_cache_sentinel")?(_=o.jsx(ka,{}),e[14]=_):_=e[14];let j;e[15]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsxs(gt,{children:[_,o.jsx("li",{children:o.jsxs("a",{href:"http://mitm.it/",target:"_blank",rel:"noreferrer",children:[o.jsx("i",{className:"fa fa-fw fa-external-link"})," Install Certificates..."]})})]}),e[15]=j):j=e[15];let y;return e[16]!==n||e[17]!==f||e[18]!==g?(y=o.jsxs(Et,{className:"pull-left special",text:"File",options:r,children:[n,l,f,g,j]}),e[16]=n,e[17]=f,e[18]=g,e[19]=y):y=e[19],y});function fu(t){return t.ui.filter[ve.Search]}function pu(t){return t.stopPropagation()}function hu(){return location.replace("/flows/dump")}const mu=I.memo(function(){const e=k.c(5),s=D(gu),i=D(vu);switch(s){case wt.INIT:{let r;return e[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("span",{className:"connection-indicator init",children:"connecting…"}),e[0]=r):r=e[0],r}case wt.FETCHING:{let r;return e[1]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("span",{className:"connection-indicator fetching",children:"fetching data…"}),e[1]=r):r=e[1],r}case wt.ESTABLISHED:{let r;return e[2]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("span",{className:"connection-indicator established",children:"connected"}),e[2]=r):r=e[2],r}case wt.ERROR:{let r;return e[3]!==i?(r=o.jsx("span",{className:"connection-indicator error",title:i,children:"connection lost"}),e[3]=i,e[4]=r):r=e[4],r}default:Ct(s)}});function gu(t){return t.connection.state}function vu(t){return t.connection.message}Xr.title="Capture";function Xr(){const t=k.c(1);let e;return t[0]===Symbol.for("react.memo_cache_sentinel")?(e=o.jsx(o.Fragment,{}),t[0]=e):e=t[0],e}const oi=function(){function t(i,r){function n(){this.constructor=i}n.prototype=r.prototype,i.prototype=new n}function e(i,r,n,l){this.message=i,this.expected=r,this.found=n,this.location=l,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e)}t(e,Error);function s(i){var r=arguments.length>1?arguments[1]:{},n={},l={start:_n},a=_n,d={type:"other",description:"filter expression"},f=function(c){return c},p={type:"other",description:"whitespace"},h=/^[ \t\n\r]/,g={type:"class",value:"[ \\t\\n\\r]",description:"[ \\t\\n\\r]"},_={type:"other",description:"control character"},j=/^[|&!()~"]/,y={type:"class",value:'[|&!()~"]',description:'[|&!()~"]'},w={type:"other",description:"optional whitespace"},$="|",N={type:"literal",value:"|",description:'"|"'},E=function(c,u){return il(c,u)},T="&",P={type:"literal",value:"&",description:'"&"'},L=function(c,u){return rl(c,u)},O="!",M={type:"literal",value:"!",description:'"!"'},U=function(c){return ol(c)},V="(",W={type:"literal",value:"(",description:'"("'},J=")",z={type:"literal",value:")",description:'")"'},te=function(c){return ll(c)},Y="~all",Q={type:"literal",value:"~all",description:'"~all"'},X=function(){return Sn},Z="~a",ae={type:"literal",value:"~a",description:'"~a"'},le=function(){return Cn},de="~b",ye={type:"literal",value:"~b",description:'"~b"'},Pe=function(c){return cl(c)},Se="~bq",Ee={type:"literal",value:"~bq",description:'"~bq"'},C=function(c){return al(c)},he="~bs",B={type:"literal",value:"~bs",description:'"~bs"'},oe=function(c){return dl(c)},q="~c",$e={type:"literal",value:"~c",description:'"~c"'},We=function(c){return ul(c)},Oe="~comment",ee={type:"literal",value:"~comment",description:'"~comment"'},Me=function(c){return fl(c)},Re="~d",re={type:"literal",value:"~d",description:'"~d"'},ue=function(c){return pl(c)},ge="~dns",Ae={type:"literal",value:"~dns",description:'"~dns"'},nt=function(){return Nn},Je="~dst",Zt={type:"literal",value:"~dst",description:'"~dst"'},b=function(c){return hl(c)},S="~e",A={type:"literal",value:"~e",description:'"~e"'},H=function(){return kn},Tt="~h",es={type:"literal",value:"~h",description:'"~h"'},Ce=function(c){return ml(c)},De="~hq",ut={type:"literal",value:"~hq",description:'"~hq"'},Ke=function(c){return gl(c)},vt="~hs",Rt={type:"literal",value:"~hs",description:'"~hs"'},it=function(c){return vl(c)},At="~http",ft={type:"literal",value:"~http",description:'"~http"'},Fe=function(){return En},Us="~marked",no={type:"literal",value:"~marked",description:'"~marked"'},io=function(){return Tn},Bs="~marker",ro={type:"literal",value:"~marker",description:'"~marker"'},oo=function(c){return xl(c)},Ws="~m",lo={type:"literal",value:"~m",description:'"~m"'},co=function(c){return _l(c)},Ks="~q",ao={type:"literal",value:"~q",description:'"~q"'},uo=function(){return Rn},zs="~replayq",fo={type:"literal",value:"~replayq",description:'"~replayq"'},po=function(){return An},Gs="~replays",ho={type:"literal",value:"~replays",description:'"~replays"'},mo=function(){return Dn},Ys="~replay",go={type:"literal",value:"~replay",description:'"~replay"'},vo=function(){return Fn},Js="~src",xo={type:"literal",value:"~src",description:'"~src"'},_o=function(c){return jl(c)},Qs="~s",jo={type:"literal",value:"~s",description:'"~s"'},yo=function(){return In},Xs="~tcp",wo={type:"literal",value:"~tcp",description:'"~tcp"'},bo=function(){return Ln},Zs="~udp",So={type:"literal",value:"~udp",description:'"~udp"'},$o=function(){return Pn},en="~tq",Co={type:"literal",value:"~tq",description:'"~tq"'},No=function(c){return yl(c)},tn="~ts",ko={type:"literal",value:"~ts",description:'"~ts"'},Eo=function(c){return wl(c)},sn="~t",To={type:"literal",value:"~t",description:'"~t"'},Ro=function(c){return bl(c)},nn="~u",Ao={type:"literal",value:"~u",description:'"~u"'},rn=function(c){return Sl(c)},on="~websocket",Do={type:"literal",value:"~websocket",description:'"~websocket"'},Fo=function(){return On},Io={type:"other",description:"integer"},ln=/^['"]/,cn={type:"class",value:`['"]`,description:`['"]`},an=/^[0-9]/,dn={type:"class",value:"[0-9]",description:"[0-9]"},Lo=function(c){return parseInt(c.join(""),10)},Po={type:"other",description:"string"},un='"',fn={type:"literal",value:'"',description:'"\\""'},ts=function(c){return c.join("")},pn="'",hn={type:"literal",value:"'",description:`"'"`},Oo=/^["\\]/,Mo={type:"class",value:'["\\\\]',description:'["\\\\]'},ss={type:"any",description:"any character"},xt=function(c){return c},mn="\\",gn={type:"literal",value:"\\",description:'"\\\\"'},qo=/^['\\]/,Ho={type:"class",value:"['\\\\]",description:"['\\\\]"},Vo=/^['"\\]/,Uo={type:"class",value:`['"\\\\]`,description:`['"\\\\]`},Bo="n",Wo={type:"literal",value:"n",description:'"n"'},Ko=function(){return`
`},zo="r",Go={type:"literal",value:"r",description:'"r"'},Yo=function(){return"\r"},Jo="t",Qo={type:"literal",value:"t",description:'"t"'},Xo=function(){return" "},m=0,Dt=[{line:1,column:1,seenCR:!1}],qe=0,ns=[],R=0,Ft;if("startRule"in r){if(!(r.startRule in l))throw new Error(`Can't start parsing from rule "`+r.startRule+'".');a=l[r.startRule]}function vn(c){var u=Dt[c],v,x;if(u)return u;for(v=c-1;!Dt[v];)v--;for(u=Dt[v],u={line:u.line,column:u.column,seenCR:u.seenCR};v bool:
# Cut off at ~100 chars, but do it smartly so that if the input is UTF-8, we don't
# chop a multibyte code point in half.
if len(s) > 100:
- for cut in range(100, 104):
+ for cut in range(100, min(104, len(s))):
is_continuation_byte = (s[cut] >> 6) == 0b10
if not is_continuation_byte:
# A new character starts here, so we cut off just before that.
@@ -163,8 +163,10 @@ def is_mostly_bin(s: bytes) -> bool:
def is_xml(s: bytes) -> bool:
+ # XML 1.0 §2.3 defines whitespace as (#x20 | #x9 | #xD | #xA), so a
+ # leading \r before "<" should also be skipped here.
for char in s:
- if char in (9, 10, 32): # is space?
+ if char in (9, 10, 13, 32): # is whitespace?
continue
return char == 60 # is a "<"?
return False
diff --git a/mitmproxy/version.py b/mitmproxy/version.py
index 758fc02c73..e4842b025c 100644
--- a/mitmproxy/version.py
+++ b/mitmproxy/version.py
@@ -2,7 +2,7 @@
import subprocess
import sys
-VERSION = "12.2.2"
+VERSION = "13.0.0.dev"
MITMPROXY = "mitmproxy " + VERSION
# Serialization format version. This is displayed nowhere, it just needs to be incremented by one
diff --git a/pyproject.toml b/pyproject.toml
index 7ddc3b8346..ab0583f302 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -33,11 +33,11 @@ classifiers = [
dependencies = [
"aioquic>=1.2.0,<=1.2.0",
"argon2-cffi>=23.1.0,<=25.1.0",
- "asgiref>=3.2.10,<=3.11.0",
+ "asgiref>=3.2.10,<=3.11.1",
"bcrypt>=5.0.0,<=5.0.0",
"Brotli>=1.0,<=1.2.0",
"certifi>=2019.9.11", # no upper bound here to get latest CA bundle
- "cryptography>=42.0,<=46.1", # relaxed upper bound here to get security fixes
+ "cryptography>=42.0,<=48.1", # relaxed upper bound here to get security fixes
"flask>=3.0,<=3.1.3",
"h11>=0.16.0,<=0.16.0",
"h2>=4.3.0,<=4.3.0",
@@ -47,14 +47,14 @@ dependencies = [
"mitmproxy_rs>=0.12.6,<0.13", # relaxed upper bound here: we control this
"msgpack>=1.0.0,<=1.1.2",
"pydivert>=2.0.3,<=2.1.0; sys_platform == 'win32'",
- "pyOpenSSL>=24.3,<=25.3.0",
+ "pyOpenSSL>=24.3,<=27.0.0",
"pyparsing>=2.4.2,<=3.3.2",
"pyperclip>=1.9.0,<=1.11.0",
"ruamel.yaml>=0.18.10,<=0.19.1",
"sortedcontainers>=2.3,<=2.4.0",
"tornado>=6.5.0,<=6.5.5",
"typing-extensions>=4.13.2,<=4.14; python_version < '3.13'",
- "urwid>=2.6.14,<=3.0.5",
+ "urwid>=2.6.14,<=4.0.0",
"wsproto>=1.0,<=1.3.2",
"publicsuffix2>=2.20190812,<=2.20191221",
"zstandard>=0.25,<=0.25.0",
@@ -67,29 +67,29 @@ dev = [
"maturin==1.12.6",
"pdoc==16.0.0",
"pyinstaller==6.19.0",
- "pyinstaller-hooks-contrib==2026.2",
+ "pyinstaller-hooks-contrib==2026.3",
"pytest-asyncio==1.2.0",
"pytest-cov==7.0.0",
"pytest-timeout==2.4.0",
"pytest-xdist==3.8.0",
"pytest==8.4.2",
- "requests==2.32.5",
+ "requests==2.33.1",
"wheel==0.46.3",
"build==1.4.2",
"mypy==1.19.1",
- "types-requests==2.32.4.20260107",
+ "types-requests==2.33.0.20260327",
{include-group = "tox"},
{include-group = "ruff"},
]
tox = [
- "tox==4.49.0",
- "tox-uv==1.33.1",
+ "tox==4.52.0",
+ "tox-uv==1.34.0",
]
ruff = [
"ruff==0.15.8",
]
deploy = [
- "awscli==1.44.53",
+ "awscli==1.44.69",
"twine==6.2.0",
]
diff --git a/test/mitmproxy/test_certs.py b/test/mitmproxy/test_certs.py
index aba66a7337..b365cbf2ae 100644
--- a/test/mitmproxy/test_certs.py
+++ b/test/mitmproxy/test_certs.py
@@ -1,11 +1,16 @@
+import hashlib
import ipaddress
import os
from datetime import datetime
+from datetime import timedelta
from datetime import timezone
from pathlib import Path
import pytest
from cryptography import x509
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives import serialization
+from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509 import NameOID
from ..conftest import skip_windows
@@ -140,6 +145,17 @@ def test_asterisk_forms(self, input, output):
class TestDummyCert:
+ def test_validity_period(self, tstore):
+ r = certs.dummy_cert(
+ tstore.default_privatekey,
+ tstore.default_ca._cert,
+ "foo.com",
+ [],
+ )
+ validity_period = r.notafter - r.notbefore
+ assert validity_period == certs.CERT_EXPIRY
+ assert validity_period < timedelta(days=200)
+
def test_with_ca(self, tstore):
r = certs.dummy_cert(
tstore.default_privatekey,
@@ -176,6 +192,86 @@ def test_with_ca(self, tstore):
assert r.altnames == x509.GeneralNames([])
assert r.crl_distribution_points == []
+ @staticmethod
+ def _build_ca_with_ski(
+ ski_digest: bytes,
+ ) -> tuple[rsa.RSAPrivateKey, x509.Certificate]:
+ """Build a self-signed CA whose SubjectKeyIdentifier is `ski_digest`."""
+ key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
+ name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "test ca")])
+ now = datetime.now(timezone.utc)
+ cert = (
+ x509.CertificateBuilder()
+ .subject_name(name)
+ .issuer_name(name)
+ .public_key(key.public_key())
+ .serial_number(x509.random_serial_number())
+ .not_valid_before(now - timedelta(days=1))
+ .not_valid_after(now + timedelta(days=365))
+ .add_extension(
+ x509.BasicConstraints(ca=True, path_length=None), critical=True
+ )
+ .add_extension(x509.SubjectKeyIdentifier(digest=ski_digest), critical=False)
+ .sign(private_key=key, algorithm=hashes.SHA256())
+ )
+ return key, cert
+
+ def test_aki_copies_issuer_ski_non_sha1(self):
+ # RFC 5280 §4.2.1.2: a child cert's AKI keyIdentifier MUST be byte-equal
+ # to the issuer's stored SubjectKeyIdentifier. mitmproxy must therefore
+ # copy the issuer's SKI verbatim, not recompute it from the public key
+ # (which always produces a SHA-1 digest and so mismatches whenever the
+ # CA used a different method, e.g. cert-manager >=1.18 / Go >=1.25
+ # which default to truncated SHA-256 for FIPS 140-3 compliance).
+ pub_der = (
+ rsa.generate_private_key(public_exponent=65537, key_size=2048)
+ .public_key()
+ .public_bytes(
+ encoding=serialization.Encoding.DER,
+ format=serialization.PublicFormat.SubjectPublicKeyInfo,
+ )
+ )
+ sha256_ski_digest = hashlib.sha256(pub_der).digest()[:20]
+ ca_key, ca_cert = self._build_ca_with_ski(sha256_ski_digest)
+
+ leaf = certs.dummy_cert(ca_key, ca_cert, "example.com", [])
+
+ leaf_aki = leaf._cert.extensions.get_extension_for_class(
+ x509.AuthorityKeyIdentifier
+ ).value
+ assert leaf_aki.key_identifier == sha256_ski_digest
+
+ def test_aki_falls_back_when_issuer_has_no_ski(self):
+ # Legacy CAs may not have an SKI extension at all. Falling back to
+ # `from_issuer_public_key` keeps mitmproxy producing a usable AKI
+ # rather than raising.
+ key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
+ name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "no-ski ca")])
+ now = datetime.now(timezone.utc)
+ ca_cert = (
+ x509.CertificateBuilder()
+ .subject_name(name)
+ .issuer_name(name)
+ .public_key(key.public_key())
+ .serial_number(x509.random_serial_number())
+ .not_valid_before(now - timedelta(days=1))
+ .not_valid_after(now + timedelta(days=365))
+ .add_extension(
+ x509.BasicConstraints(ca=True, path_length=None), critical=True
+ )
+ .sign(private_key=key, algorithm=hashes.SHA256())
+ )
+
+ leaf = certs.dummy_cert(key, ca_cert, "example.com", [])
+
+ leaf_aki = leaf._cert.extensions.get_extension_for_class(
+ x509.AuthorityKeyIdentifier
+ ).value
+ expected = x509.AuthorityKeyIdentifier.from_issuer_public_key(
+ ca_cert.public_key() # type: ignore[arg-type]
+ ).key_identifier
+ assert leaf_aki.key_identifier == expected
+
class TestCert:
def test_simple(self, tdata):
diff --git a/test/mitmproxy/utils/test_strutils.py b/test/mitmproxy/utils/test_strutils.py
index 644e4ea0a1..dea991ae66 100644
--- a/test/mitmproxy/utils/test_strutils.py
+++ b/test/mitmproxy/utils/test_strutils.py
@@ -94,6 +94,11 @@ def test_is_mostly_bin():
assert not strutils.is_mostly_bin(b"aaaaa" + 50 * "𐍅".encode())
# only utf8 continuation chars
assert strutils.is_mostly_bin(150 * b"\x80")
+ # regression #8188: payloads with len 101-103 and a continuation byte at
+ # the 100-byte cutoff used to raise IndexError because the lookahead loop
+ # ran past the end of the string. Should not raise.
+ for tail in (1, 2, 3):
+ strutils.is_mostly_bin(b"a" * 100 + b"\x80" * tail)
def test_is_xml():
@@ -101,6 +106,11 @@ def test_is_xml():
assert not strutils.is_xml(b"foo")
assert strutils.is_xml(b"=6"
- }
- },
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
diff --git a/web/package.json b/web/package.json
index 07a623aa50..56a7a18c5a 100644
--- a/web/package.json
+++ b/web/package.json
@@ -18,7 +18,6 @@
"@reduxjs/toolkit": "^2.8.1",
"@types/react": "^19.2.6",
"@uiw/react-codemirror": "^4.23.12",
- "bootstrap": "^3.4.1",
"classnames": "^2.3.1",
"codemirror": "^6.0.1",
"lodash": "^4.17.21",
diff --git a/web/src/css/app.less b/web/src/css/app.less
index 49084ae714..165572e828 100644
--- a/web/src/css/app.less
+++ b/web/src/css/app.less
@@ -1,14 +1,4 @@
-// www.paulirish.com/2012/box-sizing-border-box-ftw/
-html {
- box-sizing: border-box;
-}
-
-*,
-*:before,
-*:after {
- box-sizing: inherit;
-}
-
+@import (less) "global.less";
@import (less) "sprites.less";
@import (less) "layout.less";
@import (less) "tabs.less";
diff --git a/web/src/css/contentview.less b/web/src/css/contentview.less
index da789730d4..043ab62938 100644
--- a/web/src/css/contentview.less
+++ b/web/src/css/contentview.less
@@ -1,4 +1,19 @@
.contentview {
+ pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ overflow: auto;
+ }
+
.header {
font-weight: bold;
}
diff --git a/web/src/css/dropdown.less b/web/src/css/dropdown.less
index bc1cebd5d2..5c56754a7c 100644
--- a/web/src/css/dropdown.less
+++ b/web/src/css/dropdown.less
@@ -1,11 +1,55 @@
.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: block;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ list-style: none;
+ font-size: 14px;
+ text-align: left;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 15%);
+ border-radius: 4px;
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 17.5%);
+ background-clip: padding-box;
+
// setting a margin is not compatible with popper.
margin: 0 !important;
+ > li {
+ display: block;
+ }
+
> li > a {
+ display: block;
padding: 3px 10px;
+ clear: both;
+ font-weight: 400;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap;
+ text-decoration: none;
+ }
+
+ > li > a:hover,
+ > li > a:focus {
+ text-decoration: none;
+ color: #262626;
+ background-color: #f5f5f5;
}
max-height: 250px;
overflow-y: scroll;
}
+
+.menu-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
diff --git a/web/src/css/eventlog.less b/web/src/css/eventlog.less
index bc38101c86..8321cc5b31 100644
--- a/web/src/css/eventlog.less
+++ b/web/src/css/eventlog.less
@@ -34,7 +34,7 @@
}
}
- .btn-toggle {
+ .toggle {
margin-top: -2px;
margin-left: 3px;
padding: 2px 2px;
diff --git a/web/src/css/flowdetail.less b/web/src/css/flowdetail.less
index fa256b749d..b525d4b577 100644
--- a/web/src/css/flowdetail.less
+++ b/web/src/css/flowdetail.less
@@ -67,6 +67,8 @@
}
hr {
+ border: 0;
+ border-top: 1px solid #eee;
margin: 0;
}
}
@@ -122,10 +124,8 @@
table-layout: fixed;
word-break: break-all;
- tr {
- &:not(:first-child) {
- border-top: 1px solid #f7f7f7;
- }
+ tr:not(:first-child) td {
+ border-top: 1px solid #f7f7f7;
}
td {
diff --git a/web/src/css/flowtable.less b/web/src/css/flowtable.less
index 652c0d54af..239f840763 100644
--- a/web/src/css/flowtable.less
+++ b/web/src/css/flowtable.less
@@ -15,6 +15,8 @@
table {
width: 100%;
table-layout: fixed;
+ border-collapse: collapse;
+ border-spacing: 0;
}
thead tr {
@@ -25,7 +27,10 @@
th {
font-weight: normal;
+ text-align: left;
+ vertical-align: bottom;
position: relative !important;
+ padding: 0;
padding-left: 1px;
.user-select(none);
@@ -86,6 +91,7 @@
}
td {
+ padding: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
diff --git a/web/src/css/global.less b/web/src/css/global.less
new file mode 100644
index 0000000000..add4778ff8
--- /dev/null
+++ b/web/src/css/global.less
@@ -0,0 +1,489 @@
+// www.paulirish.com/2012/box-sizing-border-box-ftw/
+html {
+ box-sizing: border-box;
+ font-size: 10px;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+@font-family-sans-serif:
+ system-ui,
+ -apple-system,
+ "Segoe UI",
+ Roboto,
+ "Helvetica Neue",
+ Arial,
+ "Noto Sans",
+ "Liberation Sans",
+ sans-serif,
+ "Apple Color Emoji",
+ "Segoe UI Emoji",
+ "Segoe UI Symbol",
+ "Noto Color Emoji";
+@font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas,
+ "Liberation Mono", "Courier New", monospace;
+
+body {
+ margin: 0;
+ font-family: @font-family-sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+
+h1,
+h2,
+h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+
+h4,
+h5,
+h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+h1 {
+ font-size: 36px;
+}
+
+h2 {
+ font-size: 30px;
+}
+
+h3 {
+ font-size: 24px;
+}
+
+h4 {
+ font-size: 18px;
+}
+
+h5 {
+ font-size: 14px;
+}
+
+h6 {
+ font-size: 12px;
+}
+
+p {
+ margin: 0 0 10px;
+}
+
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+
+ul ul,
+ul ol,
+ol ul,
+ol ol {
+ margin-bottom: 0;
+}
+
+input,
+button,
+select,
+textarea {
+ font: inherit;
+}
+
+.float-right {
+ float: right;
+}
+
+.text-primary {
+ color: #337ab7;
+}
+
+.docs-link,
+.docs-link:visited {
+ color: #337ab7;
+ text-decoration: none;
+}
+
+.docs-link:hover,
+.docs-link:focus {
+ color: #23527c;
+}
+
+.text-success {
+ color: #3c763d;
+}
+
+.text-info {
+ color: #31708f;
+}
+
+.text-warning {
+ color: #8a6d3b;
+}
+
+.text-danger {
+ color: #a94442;
+}
+
+.text-muted {
+ color: #777;
+}
+
+.hidden {
+ display: none !important;
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+
+.btn {
+ display: inline-block;
+ text-decoration: none;
+ margin-bottom: 0;
+ font-weight: 400;
+ text-align: center;
+ vertical-align: middle;
+ touch-action: manipulation;
+ cursor: pointer;
+ background-image: none;
+ border: 1px solid transparent;
+ white-space: nowrap;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ border-radius: 4px;
+ user-select: none;
+}
+
+.btn:focus,
+.btn:hover {
+ color: #333;
+ text-decoration: none;
+}
+
+.btn:active {
+ background-image: none;
+ outline: 0;
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 12.5%);
+}
+
+.btn:disabled,
+.btn.disabled {
+ cursor: not-allowed;
+ opacity: 0.65;
+ box-shadow: none;
+}
+
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+
+.btn-default:hover,
+.btn-default:focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+
+.btn-primary {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+
+.btn-primary:hover,
+.btn-primary:focus {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+
+.btn-info:hover,
+.btn-info:focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+
+.btn-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+.btn-xs {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+.label {
+ display: inline;
+ padding: 0.2em 0.6em 0.3em;
+ font-size: 75%;
+ font-weight: 700;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: 0.25em;
+}
+
+.label-default {
+ background-color: #777;
+}
+
+.label-primary {
+ background-color: #337ab7;
+}
+
+.label-success {
+ background-color: #5cb85c;
+}
+
+.label-danger {
+ background-color: #d9534f;
+}
+
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+
+.input-group .input,
+.input-group-addon {
+ display: table-cell;
+}
+
+.input-group .input {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+
+.input-group-addon {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 1;
+ color: #555;
+ text-align: center;
+ background-color: #eee;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+
+.input-group .input-group-addon:first-child {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-right: 0;
+}
+
+.input-group .input:last-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ text-align: left;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid rgba(0, 0, 0, 20%);
+ border-radius: 6px;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 20%);
+}
+
+.popover-content {
+ padding: 9px 14px;
+}
+
+.popover > .arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover > .arrow:after {
+ content: "";
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover.top {
+ margin-top: -10px;
+}
+
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-width: 11px 11px 0;
+ border-top-color: rgba(0, 0, 0, 25%);
+}
+
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ border-width: 10px 10px 0;
+ border-top-color: #fff;
+}
+
+.popover.bottom {
+ margin-top: 10px;
+}
+
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-width: 0 11px 11px;
+ border-bottom-color: rgba(0, 0, 0, 25%);
+}
+
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ border-width: 0 10px 10px;
+ border-bottom-color: #fff;
+}
+
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: 700;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ opacity: 0.2;
+ background: transparent;
+ border: 0;
+ padding: 0;
+ cursor: pointer;
+}
+
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ opacity: 0.5;
+}
+
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ transition: all 0.2s ease-in-out;
+}
+
+.input {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 7.5%);
+ transition:
+ border-color ease-in-out 0.15s,
+ box-shadow ease-in-out 0.15s;
+}
+
+.input:focus {
+ border-color: #66afe9;
+ outline: 0;
+ box-shadow:
+ inset 0 1px 1px rgba(0, 0, 0, 7.5%),
+ 0 0 8px rgba(102, 175, 233, 60%);
+}
+
+select.input {
+ padding-right: 24px;
+}
+
+textarea.input {
+ height: auto;
+}
+
+.has-error .input {
+ border-color: #a94442;
+}
diff --git a/web/src/css/header.less b/web/src/css/header.less
index 00d696853b..76f9e112e6 100644
--- a/web/src/css/header.less
+++ b/web/src/css/header.less
@@ -1,7 +1,21 @@
-@import (reference) "../../node_modules/bootstrap/less/variables.less";
-@import (reference) "../../node_modules/bootstrap/less/mixins/grid.less";
-@import (reference) "../../node_modules/bootstrap/less/mixins/labels.less";
-@import (reference) "../../node_modules/bootstrap/less/labels.less";
+@screen-xs-max: 767px;
+@label-info-bg: #5bc0de;
+@label-success-bg: #5cb85c;
+@label-danger-bg: #d9534f;
+@label-warning-bg: #f0ad4e;
+
+.connection-label-base() {
+ display: inline;
+ padding: 0.2em 0.6em 0.3em;
+ font-size: 75%;
+ font-weight: 700;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: 0.25em;
+}
@menu-height: 95px;
@@ -127,6 +141,37 @@ header {
max-height: 500px;
overflow-y: auto;
+ .table {
+ width: 100%;
+ margin-bottom: 0;
+ border-collapse: collapse;
+ border-spacing: 0;
+
+ td,
+ th {
+ padding: 5px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ }
+
+ a {
+ color: #337ab7;
+ }
+
+ a:hover,
+ a:focus {
+ color: #23527c;
+ }
+
+ tbody tr + tr {
+ border-top: 1px solid #ddd;
+ }
+
+ tbody tr:first-child {
+ border-top: 1px solid #ddd;
+ }
+ }
+
tr {
cursor: pointer;
&:hover {
@@ -137,7 +182,7 @@ header {
}
.connection-indicator {
- .label();
+ .connection-label-base();
float: right;
margin: 5px;
opacity: 1;
diff --git a/web/src/css/modal.less b/web/src/css/modal.less
index 13ef997f77..dc5ebaefb9 100644
--- a/web/src/css/modal.less
+++ b/web/src/css/modal.less
@@ -1,8 +1,11 @@
-.modal-visible {
+.modal.is-visible {
display: block;
}
.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 30px auto;
overflow-y: initial !important;
}
@@ -10,3 +13,122 @@
max-height: calc(100vh - 200px);
overflow-y: auto;
}
+
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000;
+}
+
+.modal-backdrop.is-visible {
+ opacity: 0.5;
+}
+
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ overflow-y: auto;
+ outline: 0;
+}
+
+.modal-lg {
+ width: 900px;
+}
+
+@media (max-width: 991px) {
+ .modal-lg {
+ width: auto;
+ margin-left: 10px;
+ margin-right: 10px;
+ }
+}
+
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ border: 1px solid rgba(0, 0, 0, 20%);
+ border-radius: 6px;
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 50%);
+ background-clip: padding-box;
+ outline: 0;
+}
+
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+ min-height: 16.42857143px;
+}
+
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+
+.form-horizontal .form-row {
+ margin-left: -15px;
+ margin-right: -15px;
+ margin-bottom: 15px;
+ display: flex;
+}
+
+.form-horizontal .col-6 {
+ width: 50%;
+ min-height: 1px;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.form-horizontal .checkbox {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 7px;
+}
+
+.form-horizontal .checkbox label {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin: 0;
+ font-weight: 400;
+}
+
+.form-horizontal .checkbox input[type="checkbox"] {
+ margin: 0;
+}
+
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373;
+}
+
+.control-label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: 700;
+}
+
+.text-small {
+ font-size: 85%;
+}
diff --git a/web/src/css/mode.less b/web/src/css/mode.less
index b165ea5cbf..caee8316b7 100644
--- a/web/src/css/mode.less
+++ b/web/src/css/mode.less
@@ -1,16 +1,11 @@
-@import (reference) "../../node_modules/bootstrap/less/variables.less";
-@import (reference) "../../node_modules/bootstrap/less/mixins/grid.less";
-@import (reference) "../../node_modules/bootstrap/less/mixins/labels.less";
-@import (reference) "../../node_modules/bootstrap/less/labels.less";
-
.modes {
padding: 1em 2em 2em 2em;
overflow-y: auto;
height: 100%;
width: 100vw;
- h3 {
- margin-bottom: 10px;
+ h2 {
+ margin-bottom: 0;
}
.modes-category {
@@ -123,11 +118,13 @@
align-items: center;
margin-right: 10px;
height: 30px;
+ overflow: hidden;
}
input {
border: none;
flex: 1;
+ min-width: 0;
outline: none;
color: black;
}
@@ -190,9 +187,22 @@
.local-popover {
button {
font-size: 1rem;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ width: 24px;
+ height: 24px;
}
- i {
- font-size: 1.5rem;
+
+ > button i {
+ font-size: 1.2rem;
+ line-height: 1;
+ }
+
+ .dropdown-item > .fa-check {
+ font-size: 1.2rem;
+ line-height: 1;
}
@supports (anchor-name: --test) {
@@ -281,6 +291,26 @@
font-size: 2rem;
}
+ > button i {
+ color: #777;
+ }
+
+ &.local-popover > button {
+ font-size: 1rem;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ width: 26px;
+ height: 26px;
+ flex: 0 0 auto;
+ }
+
+ &.local-popover > button i {
+ font-size: 1.5rem;
+ line-height: 1;
+ }
+
@supports (anchor-name: --test) {
> div {
margin: 0;
diff --git a/web/src/css/tabs.less b/web/src/css/tabs.less
index 5a19705e14..024b3aa02f 100644
--- a/web/src/css/tabs.less
+++ b/web/src/css/tabs.less
@@ -5,12 +5,19 @@
> a {
display: inline-block;
+ color: #337ab7;
border: solid transparent 1px;
text-decoration: none;
//text-transform: uppercase;
//font-family: Lato;
+ &:hover,
+ &:focus {
+ color: #23527c;
+ }
+
&.active {
+ color: #337ab7;
background-color: white;
border-color: @separator-color;
border-bottom-color: white;
diff --git a/web/src/css/vendor-bootstrap-variables.less b/web/src/css/vendor-bootstrap-variables.less
deleted file mode 100644
index 77ae785773..0000000000
--- a/web/src/css/vendor-bootstrap-variables.less
+++ /dev/null
@@ -1,21 +0,0 @@
-@navbar-height: 32px;
-@navbar-default-link-color: #303030;
-@navbar-default-color: #303030;
-@navbar-default-bg: #ffffff;
-@navbar-default-border: #e0e0e0;
-@font-family-sans-serif:
- system-ui,
- -apple-system,
- "Segoe UI",
- Roboto,
- "Helvetica Neue",
- Arial,
- "Noto Sans",
- "Liberation Sans",
- sans-serif,
- "Apple Color Emoji",
- "Segoe UI Emoji",
- "Segoe UI Symbol",
- "Noto Color Emoji";
-@font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas,
- "Liberation Mono", "Courier New", monospace;
diff --git a/web/src/css/vendor-bootstrap.less b/web/src/css/vendor-bootstrap.less
deleted file mode 100644
index 73d6bcdc27..0000000000
--- a/web/src/css/vendor-bootstrap.less
+++ /dev/null
@@ -1,45 +0,0 @@
-// Core variables and mixins
-@import "../../node_modules/bootstrap/less/variables.less";
-@import "vendor-bootstrap-variables.less";
-@import "../../node_modules/bootstrap/less/mixins.less";
-// Reset and dependencies
-@import "../../node_modules/bootstrap/less/normalize.less";
-@import "../../node_modules/bootstrap/less/print.less";
-// Core CSS
-@import "../../node_modules/bootstrap/less/scaffolding.less";
-@import "../../node_modules/bootstrap/less/type.less";
-@import "../../node_modules/bootstrap/less/code.less";
-@import "../../node_modules/bootstrap/less/grid.less";
-@import "../../node_modules/bootstrap/less/tables.less";
-@import "../../node_modules/bootstrap/less/forms.less";
-@import "../../node_modules/bootstrap/less/buttons.less";
-// Components
-@import "../../node_modules/bootstrap/less/component-animations.less";
-@import "../../node_modules/bootstrap/less/dropdowns.less";
-@import "../../node_modules/bootstrap/less/button-groups.less";
-@import "../../node_modules/bootstrap/less/input-groups.less";
-@import "../../node_modules/bootstrap/less/navs.less";
-@import "../../node_modules/bootstrap/less/navbar.less";
-@import "../../node_modules/bootstrap/less/breadcrumbs.less";
-@import "../../node_modules/bootstrap/less/pagination.less";
-@import "../../node_modules/bootstrap/less/pager.less";
-@import "../../node_modules/bootstrap/less/labels.less";
-@import "../../node_modules/bootstrap/less/badges.less";
-@import "../../node_modules/bootstrap/less/jumbotron.less";
-@import "../../node_modules/bootstrap/less/thumbnails.less";
-@import "../../node_modules/bootstrap/less/alerts.less";
-@import "../../node_modules/bootstrap/less/progress-bars.less";
-@import "../../node_modules/bootstrap/less/media.less";
-@import "../../node_modules/bootstrap/less/list-group.less";
-@import "../../node_modules/bootstrap/less/panels.less";
-@import "../../node_modules/bootstrap/less/responsive-embed.less";
-@import "../../node_modules/bootstrap/less/wells.less";
-@import "../../node_modules/bootstrap/less/close.less";
-// Components w/ JavaScript
-@import "../../node_modules/bootstrap/less/modals.less";
-@import "../../node_modules/bootstrap/less/tooltip.less";
-@import "../../node_modules/bootstrap/less/popovers.less";
-@import "../../node_modules/bootstrap/less/carousel.less";
-// Utility classes
-@import "../../node_modules/bootstrap/less/utilities.less";
-@import "../../node_modules/bootstrap/less/responsive-utilities.less";
diff --git a/web/src/css/vendor.less b/web/src/css/vendor.less
index eb6208842a..5c7ee9a18a 100644
--- a/web/src/css/vendor.less
+++ b/web/src/css/vendor.less
@@ -1,3 +1 @@
-// Bootstrap
-@import "vendor-bootstrap.less";
@import (less) "../fonts/font-awesome.css";
diff --git a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap
index 9330f72338..1f1963c451 100644
--- a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap
+++ b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap
@@ -237,10 +237,10 @@ exports[`Flowcolumns Components should render pathColumn 1`] = `
class="col-path"
>
http://address:22/path
@@ -259,13 +259,13 @@ exports[`Flowcolumns Components should render pathColumn 2`] = `
class="col-path"
>
http://address:22/path
@@ -350,10 +350,10 @@ exports[`should render columns: path 1`] = `
class="col-path"
>
http://address:22/path
diff --git a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap
index d9177c7959..4ea552d038 100644
--- a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap
+++ b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap
@@ -21,13 +21,13 @@ exports[`FlowRow 1`] = `
class="col-path"
>
http://address:22/path
@@ -84,10 +84,10 @@ exports[`FlowRow 1`] = `
class="col-path"
>
dns.google A = 8.8.8.8, 8.8.4.4
diff --git a/web/src/js/__tests__/components/FlowTableSpec.tsx b/web/src/js/__tests__/components/FlowTableSpec.tsx
index e0ec2640ae..79820b54bc 100644
--- a/web/src/js/__tests__/components/FlowTableSpec.tsx
+++ b/web/src/js/__tests__/components/FlowTableSpec.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import FlowTable, { PureFlowTable } from "../../components/FlowTable";
import { act, render } from "../test-utils";
-import { select } from "../../ducks/flows";
+import { FLOWS_REMOVE, select } from "../../ducks/flows";
window.addEventListener = jest.fn();
@@ -24,4 +24,42 @@ describe("FlowTable Component", () => {
act(() => store.dispatch(select([store.getState().flows.view[3]])));
expect(asFragment()).toMatchSnapshot();
});
+
+ it("does not call onViewportUpdate when flowView and rowHeight are unchanged", () => {
+ // Regression guard for an infinite componentDidUpdate -> setState
+ // cycle. Before the FlowTableProps-comparison gate in
+ // componentDidUpdate, onViewportUpdate was called on EVERY update —
+ // including the setState the previous call itself produced — so
+ // setState could feed itself indefinitely when state.viewportTop
+ // and viewport.scrollTop never converged.
+ const spy = jest.spyOn(PureFlowTable.prototype, "onViewportUpdate");
+ const { store } = render();
+ spy.mockClear(); // ignore the componentDidMount call
+
+ // A `select` dispatch changes connect-mapped props that reach
+ // FlowTable (onlySelectedId, firstSelectedIndex) and triggers
+ // componentDidUpdate, but does NOT change flowView or rowHeight —
+ // so onViewportUpdate must not run.
+ act(() => store.dispatch(select([store.getState().flows.view[0]])));
+ expect(spy).not.toHaveBeenCalled();
+
+ spy.mockRestore();
+ });
+
+ it("calls onViewportUpdate when flowView changes", () => {
+ // Complement of the previous test: removing a flow changes
+ // `state.flows.view`, so the connect-mapped `flowView` prop differs
+ // from `prevProps.flowView` on the resulting componentDidUpdate.
+ // The gate must let onViewportUpdate run in this branch — otherwise
+ // adding/removing flows would not refresh the virtual-scroll window.
+ const spy = jest.spyOn(PureFlowTable.prototype, "onViewportUpdate");
+ const { store } = render();
+ spy.mockClear();
+
+ const firstFlowId = store.getState().flows.view[0].id;
+ act(() => store.dispatch(FLOWS_REMOVE(firstFlowId)));
+ expect(spy).toHaveBeenCalled();
+
+ spy.mockRestore();
+ });
});
diff --git a/web/src/js/__tests__/components/Header/FilterInputSpec.tsx b/web/src/js/__tests__/components/Header/FilterInputSpec.tsx
index 8f0e5b4a07..43549978e3 100644
--- a/web/src/js/__tests__/components/Header/FilterInputSpec.tsx
+++ b/web/src/js/__tests__/components/Header/FilterInputSpec.tsx
@@ -3,7 +3,7 @@ import FilterInput, {
FilterIcon,
} from "../../../components/Header/FilterInput";
import FilterDocs from "../../../components/Header/FilterDocs";
-import { act, render } from "../../test-utils";
+import { act, fireEvent, render } from "../../test-utils";
describe("FilterInput Component", () => {
it("should render correctly", () => {
@@ -56,6 +56,37 @@ describe("FilterInput Component", () => {
expect(getByDisplayValue("bar")).toBeInTheDocument();
});
+ it("preserves user-typed text when the parent re-renders with an unchanged value prop", () => {
+ // `onChange` only propagates valid filters, so a half-typed
+ // invalid filter lives in local state while `props.value`
+ // remains the last valid filter. A parent re-render with the
+ // same `value` must not clobber the in-progress text.
+ const onChange = jest.fn();
+ const props = {
+ icon: FilterIcon.SEARCH,
+ color: "red",
+ placeholder: "Filter",
+ value: "",
+ onChange,
+ };
+ const { rerender, getByPlaceholderText } = render(
+ ,
+ );
+ const input = getByPlaceholderText("Filter") as HTMLInputElement;
+
+ // User types an invalid filter — `onChange` does not propagate
+ // it (see the existing `should handle isValid` test that
+ // asserts "~foo bar" is invalid).
+ act(() => fireEvent.change(input, { target: { value: "~foo bar" } }));
+ expect(input.value).toBe("~foo bar");
+ expect(onChange).not.toHaveBeenCalled();
+
+ // Parent re-renders with the same `value=""`. The input must
+ // retain the user's in-progress text.
+ rerender();
+ expect(input.value).toBe("~foo bar");
+ });
+
it("should handle isValid", () => {
const filterInput = dummyInput();
// valid
diff --git a/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap b/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap
index 88112df697..eabd6a6baf 100644
--- a/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap
+++ b/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap
@@ -14,7 +14,7 @@ exports[`FilterInput Component should render correctly 1`] = `
/>
Strip cache headers
Use host header for display
Don't verify server certificates