{
  "_meta": {
    "locale": "en",
    "status": "reviewed",
    "note": "Source language. The complete base every other pack layers onto. All public copy here is evidence-gated and em-dash-free per CONCORD guardrails."
  },
  "site": {
    "name": "ronutz",
    "tagline": "Network and security tools that run on your machine, not someone else's cloud."
  },
  "nav": {
    "tools": "Tools",
    "about": "About",
    "certifications": "Certifications",
    "training": "Training",
    "contact": "Contact",
    "skipToContent": "Skip to content",
    "openMenu": "Open menu",
    "closeMenu": "Close menu",
    "learn": "Learn",
    "endorsements": "Endorsements",
    "certs": "Certifications"
  },
  "languageSwitcher": {
    "label": "Language",
    "stubNotice": "This language is not translated yet. Showing English."
  },
  "home": {
    "hero": {
      "eyebrow": "Practitioner-built, privacy-first",
      "title": "The network and security toolbox that keeps your data on your machine.",
      "subtitle": "Subnet math, DNS and email diagnostics, certificate inspection, and more, computed locally in your browser. No upload, no logging, no account required for the everyday tools.",
      "ctaPrimary": "Try a tool",
      "ctaSecondary": "Who builds this"
    },
    "credibility": {
      "title": "Built by someone who has done the work since 1996.",
      "body": "Thirty years in enterprise networking and security, delivered as a working instructor rather than a marketing page. Certified across four platforms, so the comparisons here are made honestly, not sold.",
      "aboutCta": "More about who builds this"
    },
    "pillars": {
      "title": "Four platforms, taught and held current.",
      "f5": "F5",
      "fortinet": "Fortinet",
      "extreme": "Extreme Networks",
      "netskope": "Netskope"
    },
    "privacy": {
      "title": "Why local-first matters for security work.",
      "body": "When you paste a configuration, a packet capture, or a certificate into a tool, that data often contains secrets. Here, the everyday tools run entirely in your browser. The input never leaves your device, so there is nothing to log, leak, or subpoena."
    },
    "toolPreview": {
      "title": "Try a tool right now.",
      "body": "The CIDR calculator below runs locally. Type a network and prefix to see the address range, host count, and mask. Nothing is sent anywhere.",
      "learnHeading": "Learn the concepts",
      "toolboxCta": "Open the full toolbox",
      "seeAllArticles": "See all articles"
    },
    "provenance": {
      "title": "Credits & sources",
      "show": "Show",
      "hide": "Hide",
      "basisLabel": "How it works",
      "sourcesLabel": "Standards & sources"
    },
    "funding": {
      "title": "Support this tool",
      "pitch": "This tool is free and built to stay that way. If it earns a place in your workflow, you can help fund its upkeep and what comes next.",
      "purposeLabel": "Currently funding"
    },
    "stats": {
      "tools": "Tools",
      "articles": "Articles",
      "sectionLabel": "The toolbox at a glance"
    }
  },
  "tools": {
    "learnHeading": "Learn the concepts",
    "backToTools": "Tools",
    "references": "References",
    "jumpTo": "Jump to",
    "categories": {
      "identity": "Identity & tokens",
      "encoding": "Encoding & data",
      "hashing": "Hashing & crypto",
      "identifiers": "Identifiers",
      "pki": "Certificates & PKI",
      "networking": "Networking",
      "web": "Web & HTTP",
      "transport": "TLS & transport",
      "security": "Security & WAF",
      "text": "Text & utilities"
    },
    "jwt": {
      "name": "JWT Decoder & Verifier",
      "blurb": "Decode a JSON Web Token's header and claims, read its expiry and timing in plain language, and verify an HS256/384/512 signature with a pasted secret. Runs entirely in your browser.",
      "inputLabel": "JSON Web Token",
      "inputPlaceholder": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
      "runsLocally": "Decoding and signature checks run locally. The token and secret never leave your browser.",
      "errors": {
        "empty": "Paste a JSON Web Token to decode.",
        "format": "That does not look like a JWT. A token has three base64url parts separated by dots: header.payload.signature.",
        "header": "The header is not valid. It should be base64url-encoded JSON.",
        "payload": "The payload is not valid. It should be base64url-encoded JSON."
      },
      "panels": {
        "header": "Header",
        "payload": "Payload",
        "signature": "Signature",
        "noSignature": "No signature segment (unsecured token)."
      },
      "claims": {
        "iss": "Issuer (iss)",
        "sub": "Subject (sub)",
        "aud": "Audience (aud)",
        "jti": "JWT ID (jti)",
        "iat": "Issued at (iat)",
        "nbf": "Not before (nbf)",
        "exp": "Expires (exp)"
      },
      "status": {
        "expired": "Expired {rel}",
        "expiresIn": "Valid, expires {rel}",
        "notYetValid": "Not valid yet, starts {rel}",
        "noExpiry": "No expiry (exp) claim"
      },
      "verify": {
        "label": "Verify HMAC signature (HS256/384/512)",
        "placeholder": "shared secret",
        "button": "Verify",
        "valid": "Signature valid for this secret.",
        "invalid": "Signature does not match this secret.",
        "algNone": "This token is unsecured (alg: none), so there is no signature to verify.",
        "unsupportedAlg": "In-browser verification covers HS256/384/512 only. {alg} is asymmetric and needs a public key.",
        "hint": "The secret is used only to compute an HMAC in your browser. It is never sent anywhere."
      },
      "struct": {
        "heading": "Anatomy of a JWT",
        "signingInput": "Signing input",
        "note": "The header and payload are only base64url-encoded, not encrypted, so anyone can read them. The signature is computed over the header and payload joined by a dot, and is what a verifier checks."
      }
    },
    "base64": {
      "name": "Base64, Base32, Hex & Percent Codec",
      "blurb": "Encode text to Base64, URL-safe Base64, Base32, hexadecimal, or percent-encoding, and decode any of them back. Tolerant of missing padding and whitespace, and it flags binary (non-UTF-8) results. Runs entirely in your browser.",
      "directionLabel": "Direction",
      "direction": {
        "encode": "Encode",
        "decode": "Decode"
      },
      "inputLabelEncode": "Text to encode",
      "inputLabelDecode": "Encoded text to decode",
      "placeholderEncode": "Hello, World!",
      "placeholderDecode": "SGVsbG8sIFdvcmxkIQ==",
      "runsLocally": "Encoding and decoding run locally. Nothing you paste leaves your browser.",
      "decodeErrors": {
        "invalid-characters": "That input contains characters outside the selected codec's alphabet.",
        "invalid-length": "That input is not a valid length for the selected codec.",
        "invalid-escape": "That input has a malformed percent-escape (a % not followed by two hex digits)."
      },
      "outputEncode": "Encoded",
      "outputDecode": "Decoded text",
      "copy": "Copy",
      "copied": "Copied",
      "emptyOutput": "(empty)",
      "decodedBytes": "Decoded {bytes, plural, one {# byte} other {# bytes}}.",
      "notUtf8": "Decoded {bytes, plural, one {# byte} other {# bytes}}, but the result is not valid UTF-8 text (likely binary).",
      "codecLabel": "Codec",
      "codec": {
        "base64": "Base64",
        "base64url": "Base64URL",
        "base32": "Base32",
        "base16": "Hex",
        "percent": "Percent"
      }
    },
    "hash": {
      "name": "Hash Generator (SHA-1/256/384/512)",
      "blurb": "Compute SHA-1, SHA-256, SHA-384, and SHA-512 digests of any text, shown as hex and Base64, using the browser's native Web Crypto. Runs entirely in your browser.",
      "algorithmLabel": "Hash algorithm",
      "inputLabel": "Text to hash",
      "inputPlaceholder": "The quick brown fox jumps over the lazy dog",
      "runsLocally": "Hashing runs locally via Web Crypto. Nothing you type leaves your browser.",
      "bits": "{bits} bits ({bytes} bytes)",
      "sha1Note": "SHA-1 is broken for collision resistance and unsuitable for security (signatures, certificates). It is fine only for non-security checksums and legacy interop.",
      "hex": "Hex",
      "base64": "Base64",
      "copy": "Copy",
      "copied": "Copied"
    },
    "hmac": {
      "name": "HMAC Generator (SHA-256/384/512)",
      "blurb": "Compute a keyed HMAC over a message with your secret key, shown as hex and Base64, via the browser's native Web Crypto. The same construction the JWT verifier uses for HS256. Your key never leaves your browser.",
      "algorithmLabel": "HMAC algorithm",
      "messageLabel": "Message",
      "messagePlaceholder": "The message to authenticate",
      "keyLabel": "Secret key",
      "keyPlaceholder": "Your shared secret",
      "runsLocally": "HMAC runs locally via Web Crypto. Your message and key never leave your browser.",
      "hex": "Hex",
      "base64": "Base64",
      "copy": "Copy",
      "copied": "Copied",
      "struct": {
        "heading": "How HMAC is built",
        "innerHash": "inner hash",
        "note": "HMAC hashes the message twice. The key is XORed with a fixed inner pad before the first hash and with an outer pad before the second, and this two-pad construction is what prevents length-extension attacks. The key is first reduced to the hash's block size."
      }
    },
    "totp-hotp": {
      "name": "TOTP / HOTP Generator & Validator",
      "blurb": "Generate and check time-based (TOTP, RFC 6238) and counter-based (HOTP, RFC 4226) one-time passwords - the codes behind authenticator apps and hardware tokens such as FortiToken. SHA-1/256/512, configurable digits and step. Computed locally with Web Crypto; your secret never leaves your browser.",
      "modeLabel": "Mode",
      "modeTotp": "TOTP (time-based)",
      "modeHotp": "HOTP (counter-based)",
      "algorithmLabel": "Algorithm",
      "secretLabel": "Shared secret",
      "secretPlaceholder": "Base32 secret, e.g. JBSWY3DPEHPK3PXP",
      "secretEncodingLabel": "Secret encoding",
      "encBase32": "Base32",
      "encHex": "Hex",
      "encAscii": "ASCII",
      "digitsLabel": "Digits",
      "stepLabel": "Step (seconds)",
      "counterLabel": "Counter",
      "timeLabel": "Time",
      "useCurrentTime": "Use current time",
      "manualTime": "Unix time (seconds)",
      "runsLocally": "Computed in your browser. Your secret is never sent anywhere.",
      "secretError": "That secret could not be decoded with the selected encoding. Check the value and the Base32 / Hex / ASCII toggle.",
      "generatedCode": "One-time code",
      "copy": "Copy",
      "copied": "Copied",
      "expiresIn": "Valid for {seconds}s more",
      "validateLabel": "Validate a code",
      "validatePlaceholder": "Paste a code to check",
      "validMatch": "Match - this code is valid right now.",
      "validNoMatch": "No match for the current parameters.",
      "validWindowNote": "Real validators usually accept the adjacent steps too; this check allows +/-1 step of clock drift.",
      "explainHeading": "How this code was derived",
      "explainMovingFactor": "Moving factor (counter / time step)",
      "explainOffset": "Truncation offset",
      "explainTruncated": "Truncated value to code",
      "explainNote": "HMAC the 8-byte moving factor under your secret, take the low nibble of the last byte as an offset, read 4 bytes there as a 31-bit number, then take that modulo 10^digits. That is RFC 4226 dynamic truncation; TOTP just feeds the time step in as the counter."
    },
    "diff": {
      "name": "Text Diff",
      "blurb": "Compare two blocks of text and see exactly what changed, line by line, with inline word-level highlighting on edited lines. Optionally ignore whitespace or case. Everything is computed in your browser; your text is never sent anywhere.",
      "originalLabel": "Original",
      "originalPlaceholder": "Paste the original text",
      "changedLabel": "Changed",
      "changedPlaceholder": "Paste the changed text",
      "ignoreWhitespace": "Ignore whitespace",
      "ignoreCase": "Ignore case",
      "resultHeading": "Differences",
      "emptyState": "Paste text in both boxes to compare them.",
      "noChanges": "No differences found.",
      "tooLarge": "These inputs are too large to diff in the browser. Try comparing smaller sections."
    },
    "pkce": {
      "name": "OAuth PKCE Verifier & Challenge",
      "blurb": "Generate an OAuth 2.0 code_verifier and derive its S256 code_challenge, or paste your own and check it against RFC 7636's length and charset rules. The same SHA-256 base64url derivation your authorization server expects. Runs entirely in your browser.",
      "verifierLabel": "Code verifier",
      "verifierPlaceholder": "Paste a code_verifier, or generate one",
      "generate": "Generate",
      "runsLocally": "Generation and derivation run locally. Your verifier never leaves your browser.",
      "lengthBadge": "Length {length} (43-128)",
      "charsetOk": "Unreserved charset",
      "charsetBad": "Invalid characters",
      "s256Title": "Code challenge · S256",
      "plainTitle": "Code challenge · plain",
      "plainNote": "The plain method is discouraged. Use S256 wherever the client can compute SHA-256.",
      "encodingLabel": "base64url",
      "plainValueLabel": "= code_verifier",
      "copy": "Copy",
      "copied": "Copied",
      "flowHeading": "How PKCE works",
      "laneClient": "App / Client",
      "laneServer": "Authorization server",
      "s1": "Generate a random code_verifier",
      "s2": "Derive the code_challenge",
      "s3": "Authorization request carries the challenge",
      "s4": "Server stores the challenge",
      "s5": "Authorization code returned",
      "s6": "Token request carries the verifier",
      "s7": "Server re-derives and compares",
      "s8": "Access and refresh tokens issued"
    },
    "uuid": {
      "name": "UUID Generator & Inspector (v4 / v7)",
      "blurb": "Generate random v4 or time-ordered v7 UUIDs, or paste any UUID to read its version, variant, and (for v7) the embedded creation timestamp. Generation uses the browser's secure random source. Runs entirely in your browser.",
      "versionLabel": "UUID version",
      "generate": "Generate",
      "clear": "Clear",
      "emptyHint": "Pick a version and generate.",
      "runsLocally": "Generation and inspection run locally. Nothing is sent anywhere.",
      "copy": "Copy",
      "copied": "Copied",
      "inspectLabel": "Inspect a UUID",
      "inspectPlaceholder": "Paste any UUID to decode it",
      "valid": "Valid UUID",
      "invalid": "Not a valid UUID",
      "versionField": "Version",
      "variantField": "Variant",
      "timestampField": "Timestamp (v7)",
      "versionValue": "Version {version}"
    },
    "x509": {
      "name": "X.509 Certificate Decoder",
      "blurb": "Paste a PEM, base64, or hex certificate to read its subject, issuer, validity window, public key, and v3 extensions, with SHA-256 and SHA-1 fingerprints. Runs entirely in your browser.",
      "inputLabel": "X.509 certificate",
      "inputPlaceholder": "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----",
      "runsLocally": "Decoding and fingerprints run locally. The certificate never leaves your browser.",
      "errors": {
        "empty": "Paste an X.509 certificate to decode.",
        "format": "That does not look like a certificate. Paste PEM (-----BEGIN CERTIFICATE-----), base64, or hex.",
        "der": "The bytes are not valid DER. Check that the whole certificate was pasted, including the END line.",
        "structure": "This decodes as ASN.1 but is not an X.509 certificate. A certificate is a SEQUENCE of TBSCertificate, signatureAlgorithm, and signatureValue."
      },
      "status": {
        "valid": "Valid, expires {rel}",
        "expired": "Expired {rel}",
        "notYetValid": "Not valid yet, starts {rel}"
      },
      "panels": {
        "subject": "Subject",
        "issuer": "Issuer",
        "details": "Details",
        "publicKey": "Public key",
        "extensions": "Extensions",
        "sct": "Certificate Transparency",
        "revocation": "Revocation",
        "fingerprints": "Fingerprints"
      },
      "fields": {
        "version": "Version",
        "serial": "Serial number",
        "notBefore": "Not before",
        "notAfter": "Not after",
        "signatureAlgorithm": "Signature algorithm",
        "algorithm": "Algorithm",
        "keySize": "Key size",
        "exponent": "Exponent",
        "curve": "Curve",
        "bits": "{n}-bit",
        "selfSigned": "Self-issued"
      },
      "ext": {
        "san": "Subject alternative names",
        "keyUsage": "Key usage",
        "extKeyUsage": "Extended key usage",
        "basicConstraints": "Basic constraints",
        "subjectKeyId": "Subject key identifier",
        "authorityKeyId": "Authority key identifier",
        "caTrue": "Certificate authority (CA: true)",
        "caFalse": "Not a CA (CA: false)",
        "pathLen": "path length {n}",
        "critical": "critical"
      },
      "rev": {
        "crl": "CRL distribution",
        "ocsp": "OCSP responder",
        "caIssuers": "CA issuers",
        "mustStaple": "Must-Staple",
        "mustStapleYes": "Required (TLS Feature: status_request)",
        "none": "Revocation info",
        "noneDetail": "No CRL or OCSP pointers are present in this certificate.",
        "note": "These are the revocation endpoints named in the certificate. This tool reads them but never contacts them; the revocation status check happens in your client, not here."
      },
      "sct": {
        "intro": "Embedded SCTs: {n}. Each is a CT log's signed proof that it recorded this certificate; browsers require a minimum number for the certificate to be trusted.",
        "entry": "SCT {i}",
        "logId": "Log ID",
        "timestamp": "Logged at",
        "signature": "Signature",
        "note": "Signatures are shown but not verified here; verifying an SCT needs the log's public key and the precertificate."
      },
      "fp": {
        "sha256": "SHA-256",
        "sha1": "SHA-1",
        "computing": "Computing fingerprints..."
      },
      "chainHeading": "Chain of trust",
      "tierRoot": "Root CA",
      "tierIntermediate": "Intermediate CA",
      "tierLeaf": "End-entity certificate",
      "roleRoot": "Self-signed trust anchor",
      "roleIntermediate": "Signed by a root; signs leaf certificates",
      "roleLeaf": "Identifies a server or client",
      "thisCert": "this certificate",
      "issuedBy": "Issued by",
      "signs": "signs",
      "trustNote": "Trust flows downward: each certificate is signed by the one above, up to a root your system already trusts."
    },
    "ipv6": {
      "name": "IPv6 Toolkit",
      "blurb": "Parse an IPv6 address or prefix to see its canonical (RFC 5952) and fully expanded forms, special-use classification, prefix math, an EUI-64 MAC if present, and its ip6.arpa reverse-DNS name. Runs entirely in your browser.",
      "inputLabel": "IPv6 address or prefix",
      "inputPlaceholder": "2001:db8::1/64",
      "runsLocally": "Parsing runs locally. The address never leaves your browser.",
      "errors": {
        "empty": "Enter an IPv6 address or prefix to decode.",
        "format": "That is not a valid IPv6 address. Use eight hex groups, optionally compressed with :: once (for example 2001:db8::1).",
        "prefix": "The prefix length is not valid. For IPv6 it must be between 0 and 128."
      },
      "panels": {
        "forms": "Canonical forms",
        "classification": "Classification",
        "prefix": "Prefix",
        "identifiers": "Identifiers"
      },
      "fields": {
        "compressed": "Compressed (RFC 5952)",
        "expanded": "Expanded",
        "type": "Type",
        "scope": "Scope",
        "embeddedIpv4": "Embedded IPv4",
        "network": "Network",
        "firstAddress": "First address",
        "lastAddress": "Last address",
        "count": "Addresses",
        "hostBits": "Host bits",
        "eui64": "EUI-64 MAC",
        "reverseDns": "Reverse DNS (ip6.arpa)"
      },
      "badges": {
        "multicast": "multicast"
      },
      "segHeading": "Address structure",
      "networkSeg": "Network prefix",
      "ifaceId": "Interface ID",
      "hostBits": "Host bits",
      "prefixNote": "Bits left of the boundary are fixed by the prefix; bits to the right identify the host within it.",
      "conventionNote": "No prefix was given, so the dashed line marks the conventional /64 split: routing prefix and subnet on the left, the 64-bit interface identifier on the right."
    },
    "cidr": {
      "name": "CIDR / Subnet Calculator",
      "blurb": "Break down any IPv4 CIDR block into network and broadcast addresses, usable host range, host count, and netmask. Runs entirely in your browser.",
      "title": "CIDR Calculator",
      "description": "Compute the network and broadcast addresses, usable host range, host count, and netmask for an IPv4 CIDR block. Runs locally in your browser.",
      "inputLabel": "CIDR block",
      "inputPlaceholder": "192.168.1.0/24",
      "compute": "Calculate",
      "runsLocally": "Runs locally. Nothing is sent to any server.",
      "prefixSlider": "Prefix length",
      "bitsHeading": "Address bits",
      "bitsNetwork": "Network",
      "bitsHost": "Host",
      "bitsNote": "The highlighted bits identify the network — the rest address hosts within it.",
      "results": {
        "network": "Network address",
        "broadcast": "Broadcast address",
        "netmask": "Netmask",
        "wildcard": "Wildcard mask",
        "firstHost": "First usable host",
        "lastHost": "Last usable host",
        "totalAddresses": "Total addresses",
        "usableHosts": "Usable hosts"
      },
      "errors": {
        "empty": "Enter a CIDR block to calculate.",
        "invalid": "That does not look like a valid CIDR block. Try a format like 192.168.1.0/24."
      },
      "modes": {
        "subnet": "Subnet",
        "vlsm": "VLSM",
        "supernet": "Supernet",
        "overlap": "Overlap / gap"
      },
      "modeDesc": {
        "subnet": "Analyze a single IPv4 CIDR block: network, broadcast, mask, and host range.",
        "vlsm": "Carve variable-length subnets from a parent block to fit a list of host counts.",
        "supernet": "Summarize a list of prefixes into the smallest set of covering blocks.",
        "overlap": "Find overlaps and containment between prefixes, plus gaps within an optional scope."
      },
      "vlsm": {
        "parentLabel": "Parent block",
        "parentPlaceholder": "10.0.0.0/24",
        "reqsLabel": "Subnet requirements",
        "namePlaceholder": "Name (optional)",
        "hostsPlaceholder": "Hosts",
        "addRow": "Add subnet",
        "remove": "Remove",
        "run": "Allocate",
        "th": {
          "name": "Name",
          "hosts": "Hosts",
          "network": "Network",
          "prefix": "Prefix",
          "netmask": "Netmask",
          "range": "Usable range",
          "broadcast": "Broadcast",
          "usable": "Usable hosts"
        },
        "stat": {
          "parent": "Parent",
          "used": "Used",
          "free": "Free",
          "utilization": "Utilization"
        },
        "unfit": "Did not fit"
      },
      "supernet": {
        "label": "Prefixes to aggregate",
        "placeholder": "192.168.0.0/24\n192.168.1.0/24",
        "run": "Aggregate",
        "minimal": "Minimal covering set",
        "single": "Single supernet",
        "singleExtra": "Adds {extra} extra addresses beyond the inputs.",
        "stat": {
          "inputs": "Input prefixes",
          "addresses": "Addresses",
          "blocks": "Aggregated blocks"
        }
      },
      "overlap": {
        "label": "Prefixes to check",
        "placeholder": "10.0.0.0/24\n10.0.0.128/25",
        "scopeLabel": "Scope (optional, enables gap detection)",
        "scopePlaceholder": "10.0.0.0/16",
        "run": "Check",
        "overlapsTitle": "Overlaps",
        "noOverlaps": "No overlaps found.",
        "gapsTitle": "Gaps in scope",
        "noGaps": "No gaps in the given scope.",
        "kind": {
          "identical": "identical to",
          "contains": "contains",
          "contained": "is inside",
          "partial": "partially overlaps"
        },
        "addresses": "addresses",
        "stat": {
          "covered": "Covered",
          "scope": "Scope"
        }
      },
      "err": {
        "ipv4": "Not a valid IPv4 address. Use four octets 0-255, like 192.168.1.0.",
        "octet": "An octet is out of range (each must be 0-255).",
        "format": "Expected the form A.B.C.D/prefix, like 192.168.1.0/24.",
        "prefix": "The prefix length must be between 0 and 32.",
        "tooMany": "Too many entries. Trim the list and try again.",
        "noReqs": "Add at least one subnet requirement with a host count.",
        "noPrefixes": "Enter at least one prefix, one per line."
      },
      "rangeHeading": "Address layout",
      "usableShort": "usable",
      "rfcNote": "/31 and /32 reserve nothing: every address is usable (RFC 3021).",
      "reservedNote": "The first address is the network and the last is the broadcast; both are reserved, so usable = total − 2."
    },
    "secure-headers": {
      "name": "Secure Headers Analyzer",
      "blurb": "Paste an HTTP response and get a graded breakdown of its security headers, cookie flags, and cross-origin policy, checked against OWASP, RFC 6797, CSP Level 3, and RFC 6265bis.",
      "inputLabel": "HTTP response or header block",
      "inputPlaceholder": "HTTP/2 200\nstrict-transport-security: max-age=63072000; includeSubDomains; preload\ncontent-security-policy: default-src 'self'; object-src 'none'\nx-content-type-options: nosniff\nset-cookie: id=abc; Secure; HttpOnly; SameSite=Lax",
      "runsLocally": "Analysis runs locally in your browser. Nothing is sent anywhere.",
      "gradeLabel": "Grade {grade}",
      "gradeAria": "Overall security-header grade: {grade}",
      "scoreLabel": "{score} / {max} points",
      "recommendedLabel": "Recommended:",
      "cookieUnnamed": "(unnamed cookie)",
      "errors": {
        "empty": "Paste an HTTP response or a block of headers to analyze.",
        "no-headers": "No headers found. Paste a response with header lines like 'Header-Name: value'."
      },
      "ratings": {
        "strong": "Strong",
        "adequate": "Adequate",
        "weak": "Weak",
        "missing": "Missing",
        "info": "Info"
      },
      "panels": {
        "headers": "Headers",
        "cookies": "Cookies"
      },
      "reasons": {
        "HSTS_MISSING": "No Strict-Transport-Security header. Browsers may use plain HTTP, leaving the first request open to downgrade attacks.",
        "HSTS_MAXAGE_ZERO": "max-age is {value}, which disables HSTS. Set a positive max-age such as 31536000 (one year).",
        "HSTS_MAXAGE_LOW": "max-age is only {value} seconds, under the recommended six-month minimum.",
        "HSTS_MAXAGE_OK": "max-age is {value} seconds, acceptable but below the one-year baseline.",
        "HSTS_MAXAGE_STRONG": "max-age is {value} seconds (one year or more), the recommended baseline.",
        "HSTS_SUBDOMAINS": "includeSubDomains is set, extending HTTPS enforcement to every subdomain.",
        "HSTS_NO_SUBDOMAINS": "includeSubDomains is not set, so subdomains are not covered.",
        "HSTS_PRELOAD": "preload is set, making the host eligible for the browser HSTS preload list.",
        "CSP_MISSING": "No Content-Security-Policy. The main defence-in-depth control against cross-site scripting is absent.",
        "CSP_HAS_DEFAULT_SRC": "A default-src directive is set, giving every resource type a baseline policy.",
        "CSP_NO_DEFAULT_SRC": "No default-src directive, so resource types without their own directive are unrestricted.",
        "CSP_HAS_OBJECT_SRC": "object-src is set, restricting legacy plugin content.",
        "CSP_HAS_BASE_URI": "base-uri is set, preventing base-tag injection.",
        "CSP_FRAME_ANCESTORS": "frame-ancestors is set, the modern control against framing and clickjacking.",
        "CSP_UNSAFE_INLINE": "Uses 'unsafe-inline', which permits inline scripts or styles and largely defeats the XSS protection of CSP.",
        "CSP_UNSAFE_EVAL": "Uses 'unsafe-eval', which permits eval() and similar dynamic code execution.",
        "CSP_WILDCARD": "A wildcard '*' source allows content from any origin, weakening the policy.",
        "CSP_RO_ABSENT": "No report-only policy is set. This is optional and used to stage a CSP before enforcing it.",
        "CSP_RO_ONLY": "A report-only CSP is present but there is no enforced Content-Security-Policy. Report-only does not protect the page.",
        "CSP_RO_WITH_ENFORCED": "A report-only CSP is present alongside the enforced policy, useful for testing changes.",
        "XCTO_MISSING": "No X-Content-Type-Options. Browsers may MIME-sniff responses, risking content being run as script.",
        "XCTO_NOSNIFF": "Set to nosniff, which stops MIME-type sniffing.",
        "XCTO_INVALID": "Unexpected value '{value}'. The only valid value is nosniff.",
        "XFO_MISSING": "No X-Frame-Options. Without it, or CSP frame-ancestors, the page can be framed for clickjacking.",
        "XFO_DENY": "Set to DENY, preventing the page from being framed by any site.",
        "XFO_SAMEORIGIN": "Set to SAMEORIGIN, allowing framing only by same-origin pages.",
        "XFO_ALLOWFROM_DEPRECATED": "Uses ALLOW-FROM, which is obsolete and ignored by modern browsers. Use CSP frame-ancestors instead.",
        "XFO_INVALID": "Unexpected value '{value}'. Use DENY or SAMEORIGIN.",
        "REFERRER_MISSING": "No Referrer-Policy. The browser default applies, which may leak full URLs to other origins.",
        "REFERRER_STRONG": "Set to '{value}', a privacy-preserving policy.",
        "REFERRER_WEAK": "Set to '{value}', which still sends the origin or more to other sites.",
        "REFERRER_OTHER": "Set to '{value}'.",
        "REFERRER_UNSAFE_URL": "Set to unsafe-url, which sends the full URL, including path and query, to every destination.",
        "PERMISSIONS_MISSING": "No Permissions-Policy. Powerful features such as camera, microphone, and geolocation are not restricted.",
        "PERMISSIONS_PRESENT": "Present, restricting access to powerful browser features.",
        "COOP_MISSING": "No Cross-Origin-Opener-Policy. The page shares a browsing-context group with cross-origin openers.",
        "COOP_SAME_ORIGIN": "Set to same-origin, isolating the page from cross-origin windows.",
        "COOP_ALLOW_POPUPS": "Set to same-origin-allow-popups, isolating the page while keeping popups it opens.",
        "COOP_UNSAFE_NONE": "Set to unsafe-none, which provides no opener isolation.",
        "COEP_ABSENT": "No Cross-Origin-Embedder-Policy. This is optional and required only for cross-origin isolation.",
        "COEP_PRESENT": "Set to '{value}', requiring embedded resources to opt in.",
        "CORP_ABSENT": "No Cross-Origin-Resource-Policy. This is optional and limits who may embed this resource.",
        "CORP_SAME_ORIGIN": "Set to same-origin, the tightest setting.",
        "CORP_SAME_SITE": "Set to same-site, allowing same-site embedding.",
        "CORP_CROSS_ORIGIN": "Set to cross-origin, allowing any site to embed this resource. Make sure that is intended.",
        "CACHE_ABSENT": "No Cache-Control header. Set no-store on responses that carry sensitive data.",
        "CACHE_RESTRICTED": "Caching is restricted (no-store, no-cache, or private), appropriate for sensitive responses.",
        "CACHE_PERMISSIVE": "Caching is permissive. Make sure the response contains no sensitive data.",
        "CORS_WILDCARD": "Access-Control-Allow-Origin is '*', letting any site read the response. This is safe only for public, credential-free data.",
        "CORS_WILDCARD_CREDENTIALS": "Access-Control-Allow-Origin is '*' together with credentials. This exposes credentialed data to any origin, a serious misconfiguration.",
        "CORS_NULL_ORIGIN": "Access-Control-Allow-Origin is 'null', which several contexts can forge. Avoid the null origin.",
        "CORS_SPECIFIC_ORIGIN": "Access-Control-Allow-Origin allows '{value}'. Confirm that origin is trusted.",
        "CORS_CREDENTIALS_TRUE": "Access-Control-Allow-Credentials is true, so the response may carry cookies cross-origin. Pair this only with a specific, trusted origin.",
        "CORS_CREDENTIALS_OTHER": "Access-Control-Allow-Credentials is '{value}'.",
        "XPCDP_ABSENT": "No X-Permitted-Cross-Domain-Policies. OWASP recommends setting it to none.",
        "XPCDP_NONE": "Set to none, the hardened value.",
        "XPCDP_ALL": "Set to all, the most permissive value. Prefer none.",
        "XPCDP_OTHER": "Set to '{value}'.",
        "CLEAR_SITE_DATA_PRESENT": "Clear-Site-Data is set ('{value}'), telling the browser to clear site data. Use it on logout endpoints.",
        "FEATURE_POLICY_DEPRECATED": "Feature-Policy is deprecated. Migrate to Permissions-Policy.",
        "HPKP_DEPRECATED": "HTTP Public Key Pinning is deprecated and removed from browsers. Remove this header.",
        "EXPECT_CT_OBSOLETE": "Expect-CT is obsolete ('{value}'). Certificate Transparency is enforced by default, so remove it.",
        "XSS_PROTECTION_LEGACY": "X-XSS-Protection is '{value}'. The legacy auditor is gone from modern browsers. Remove it, or set it to 0, and rely on CSP.",
        "XSS_PROTECTION_DISABLED_OK": "X-XSS-Protection is 0, which correctly disables the obsolete auditor.",
        "SERVER_VERSION_DISCLOSED": "Server reveals version detail ('{value}'), helping attackers target known flaws. Minimise it.",
        "SERVER_PRODUCT_DISCLOSED": "Server names the product ('{value}'). Consider removing or minimising it.",
        "XPOWEREDBY_PRESENT": "X-Powered-By reveals the stack ('{value}'). Remove it.",
        "XASPNETVERSION_PRESENT": "X-AspNet-Version reveals the runtime version ('{value}'). Remove it.",
        "XASPNETMVCVERSION_PRESENT": "X-AspNetMvc-Version reveals the framework version ('{value}'). Remove it.",
        "HEADER_PRESENT": "Present.",
        "COOKIE_COUNT": "{value} cookie(s) set.",
        "COOKIE_WEAK_COUNT": "{value} cookie(s) have weak attributes.",
        "COOKIE_SECURE": "Secure is set, so the cookie is sent only over HTTPS.",
        "COOKIE_NO_SECURE": "Secure is not set, so the cookie can be sent over plain HTTP.",
        "COOKIE_HTTPONLY": "HttpOnly is set, hiding the cookie from JavaScript.",
        "COOKIE_NO_HTTPONLY": "HttpOnly is not set, so script can read the cookie and an XSS flaw could steal it.",
        "COOKIE_SAMESITE_STRICT": "SameSite=Strict, the strongest cross-site request protection.",
        "COOKIE_SAMESITE_LAX": "SameSite=Lax, reasonable cross-site request protection.",
        "COOKIE_SAMESITE_NONE": "SameSite=None with Secure, allowing cross-site sending.",
        "COOKIE_SAMESITE_NONE_INSECURE": "SameSite=None without Secure. Browsers reject this and it is insecure. Add Secure.",
        "COOKIE_NO_SAMESITE": "No SameSite attribute. Set Lax or Strict for cross-site request resistance.",
        "COOKIE_HOST_PREFIX_OK": "The __Host- prefix requirements are met (Secure, Path=/, and no Domain).",
        "COOKIE_HOST_PREFIX_VIOLATION": "The __Host- prefix requires Secure, Path=/, and no Domain. Those conditions are not all met.",
        "COOKIE_SECURE_PREFIX_OK": "The __Secure- prefix requirement is met (Secure is set).",
        "COOKIE_SECURE_PREFIX_VIOLATION": "The __Secure- prefix requires Secure, which is not set.",
        "OVERALL_MISSING_CRITICAL": "Critical headers missing or weak: {value}.",
        "OVERALL_INFO_LEAK": "{value} header(s) disclose server or stack details.",
        "OVERALL_WEAK_COOKIES": "{value} cookie(s) have weak attributes.",
        "OVERALL_CORS_RISK": "A cross-origin (CORS) policy exposes data to other sites.",
        "OVERALL_STRONG": "Strong overall security-header posture.",
        "OVERALL_POOR": "Several core security headers are missing."
      }
    },
    "saml-decoder": {
      "name": "SAML Decoder",
      "blurb": "Paste a SAML Response or assertion (raw, base64, or URL-encoded) and decode its issuer, status, subject, conditions, audience, and attributes, with signature and weak-algorithm checks. Hardened against XXE.",
      "inputLabel": "SAML message (XML, base64, or URL-encoded)",
      "inputPlaceholder": "Paste a SAML Response, an assertion, or the base64 SAMLResponse value",
      "runsLocally": "Decoding runs locally in your browser. Nothing is sent anywhere.",
      "attrUnnamed": "(unnamed)",
      "attrNoValue": "(no value)",
      "encryptedNote": "{n} encrypted assertion(s) detected. Decrypting requires the service provider's private key and is out of scope for this decoder.",
      "notVerifiedNote": "This tool decodes and explains structure only. It does not verify signatures, validate the message, or decrypt encrypted content.",
      "errors": {
        "empty": "Paste a SAML message to decode.",
        "not-decodable": "This does not look like XML or base64. Paste a SAML Response, an assertion, or its base64 form.",
        "deflated": "This decodes to compressed (DEFLATE) bytes, which is the HTTP-Redirect binding. Paste the raw XML or the base64 HTTP-POST form instead.",
        "doctype-forbidden": "This message contains a DOCTYPE or entity declaration, which a SAML message must not have. It is rejected to prevent XML external entity (XXE) attacks.",
        "not-xml": "The input could not be parsed as XML.",
        "no-saml": "This is XML, but not a recognizable SAML message.",
        "malformed": "The XML is malformed (an unclosed or mismatched tag).",
        "too-large": "The message is too large to decode here.",
        "too-deep": "The XML is nested too deeply to decode.",
        "too-many-nodes": "The XML has too many elements to decode."
      },
      "badges": {
        "signed": "Signed",
        "unsigned": "Unsigned",
        "encrypted": "Encrypted",
        "statusSuccess": "Status: Success",
        "statusFailure": "Status: {code}",
        "weakAlgo": "weak algorithm",
        "weakDigest": "weak digest"
      },
      "panels": {
        "message": "Message",
        "assertion": "Assertion {n}"
      },
      "blocks": {
        "subject": "Subject",
        "conditions": "Conditions",
        "authn": "Authentication",
        "attributes": "Attributes",
        "responseSignature": "Response signature"
      },
      "fields": {
        "docType": "Type",
        "issuer": "Issuer",
        "id": "ID",
        "issueInstant": "Issued at",
        "destination": "Destination",
        "inResponseTo": "In response to",
        "status": "Status",
        "statusMessage": "Status message",
        "nameId": "NameID",
        "nameIdFormat": "NameID format",
        "confirmationMethod": "Confirmation method",
        "notOnOrAfter": "Not on or after",
        "recipient": "Recipient",
        "notBefore": "Not before",
        "audience": "Audience",
        "authnContext": "Authn context",
        "authnInstant": "Authn instant",
        "sessionIndex": "Session index",
        "algorithm": "Signature algorithm",
        "digest": "Digest algorithm",
        "c14n": "Canonicalization"
      },
      "reasons": {
        "SIGNED_RESPONSE": "The response is signed at the top level.",
        "SIGNED_ASSERTION": "An assertion signature is present ({value} signed).",
        "UNSIGNED": "Nothing in this message is signed. Its authenticity cannot be established, so it must be treated as untrusted until a signature is added and verified.",
        "WEAK_SIG_ALGO": "The signature uses {value}, a weak algorithm. Prefer RSA-SHA256 or stronger.",
        "WEAK_DIGEST_ALGO": "The signature digest uses {value}, a weak hash. Prefer SHA-256 or stronger.",
        "ENCRYPTED_ASSERTION": "{value} assertion(s) are encrypted. This tool reports their presence but does not decrypt them.",
        "STATUS_SUCCESS": "The response status is Success.",
        "STATUS_NOT_SUCCESS": "The response status is {value}, not Success. The login did not succeed.",
        "NO_CONDITIONS": "An assertion has no Conditions element, so it carries no validity window or audience restriction.",
        "NO_AUDIENCE_RESTRICTION": "An assertion has Conditions but no AudienceRestriction, so it is not bound to a specific service provider.",
        "BEARER_NO_NOTONORAFTER": "A bearer SubjectConfirmation has no NotOnOrAfter, so the confirmation does not expire. This weakens replay protection.",
        "BEARER_NO_RECIPIENT": "A bearer SubjectConfirmation has no Recipient, so it is not bound to the intended endpoint.",
        "MULTIPLE_ASSERTIONS": "The message contains {value} assertions. Confirm your service provider processes the one it expects, since multiple assertions can be used in wrapping attacks."
      },
      "flow": {
        "heading": "Web browser SSO (SP-initiated)",
        "laneSp": "Service Provider",
        "laneIdp": "Identity Provider",
        "s1": "A user requests a protected resource at the service provider",
        "s2": "The SP builds an AuthnRequest and redirects the browser to the IdP",
        "s3": "The IdP receives the AuthnRequest over the Redirect binding",
        "s4": "The IdP authenticates the user",
        "s5": "The IdP issues a signed Response carrying an Assertion",
        "s6": "The browser POSTs the SAMLResponse back to the SP's ACS",
        "s7": "The SP checks the signature, conditions, and audience",
        "s8": "The SP establishes a session and grants access"
      }
    },
    "oidc": {
      "name": "OIDC Decoder",
      "blurb": "Paste an OpenID Connect ID token or a .well-known/openid-configuration document and decode it: the core claims, profile claims, endpoints, and capabilities, with checks for required claims, signing algorithm, nonce, and PKCE.",
      "inputLabel": "ID token (JWT) or openid-configuration JSON",
      "inputPlaceholder": "Paste an ID token, or an OIDC discovery JSON document",
      "runsLocally": "Decoding runs locally in your browser. It never calls the jwks_uri or any endpoint, and nothing is sent anywhere.",
      "notVerifiedNote": "This tool decodes and explains. It does not verify the token signature, fetch the signing keys, or check expiry against the clock.",
      "errors": {
        "empty": "Paste an ID token or an openid-configuration document to decode.",
        "malformed-json": "This starts like JSON but could not be parsed. Check for a missing brace, comma, or quote.",
        "json-not-oidc": "This is JSON, but not an OpenID Connect discovery document. Paste an ID token, or a .well-known/openid-configuration document.",
        "not-jwt": "This does not look like a JWT or an OIDC document. Paste an ID token or a discovery document.",
        "jwt-header": "The token header could not be decoded. A JWT is three base64url parts separated by dots.",
        "jwt-payload": "The token payload could not be decoded as JSON."
      },
      "badges": {
        "idToken": "ID Token",
        "discovery": "Discovery",
        "signed": "Signed",
        "unsigned": "Unsigned",
        "algNone": "alg: none",
        "algUnknown": "alg: ?"
      },
      "panels": {
        "header": "Header",
        "coreClaims": "Core ID token claims",
        "metadata": "Provider",
        "endpoints": "Endpoints",
        "capabilities": "Capabilities"
      },
      "categories": {
        "binding": "Token binding",
        "profile": "Profile claims",
        "email": "Email",
        "address": "Address",
        "phone": "Phone",
        "oauth": "OAuth / session",
        "other": "Other claims"
      },
      "fields": {
        "alg": "Algorithm",
        "typ": "Type",
        "kid": "Key ID",
        "iss": "Issuer (iss)",
        "sub": "Subject (sub)",
        "aud": "Audience (aud)",
        "azp": "Authorized party (azp)",
        "nonce": "Nonce",
        "acr": "Auth context (acr)",
        "amr": "Auth methods (amr)",
        "authTime": "Auth time",
        "iat": "Issued at (iat)",
        "nbf": "Not before (nbf)",
        "exp": "Expires (exp)",
        "issuer": "Issuer"
      },
      "reasons": {
        "MISSING_REQUIRED_CLAIM": "Missing required claim {value}. An ID token must contain iss, sub, aud, exp, and iat.",
        "ALG_NONE": "The token uses alg none, meaning it is unsigned. An unsigned ID token proves nothing and must be rejected.",
        "ALG_SYMMETRIC": "Signed with {value}, a symmetric (HMAC) algorithm. ID tokens from a public provider normally use an asymmetric algorithm like RS256 or ES256 so the relying party can verify with the public key.",
        "ALG_UNKNOWN": "Signed with {value}, an algorithm this tool does not recognize. Confirm it is an expected, strong algorithm.",
        "SIGNED_ASYMMETRIC": "Signed with {value}, an asymmetric algorithm. The relying party verifies it against the provider's public key from the JWKS.",
        "NO_NONCE": "No nonce claim. The nonce binds the token to the authentication request and protects against replay. It should be present when the request sent one.",
        "MULTI_AUD_NO_AZP": "The token has multiple audiences but no azp (authorized party). With more than one audience, azp should name the client the token is for.",
        "DISCOVERY_MISSING_FIELD": "Missing required discovery field {value}.",
        "DISCOVERY_ALG_NONE": "The provider advertises the none signing algorithm for ID tokens, which would allow unsigned tokens. This should not be offered.",
        "DISCOVERY_NO_PKCE": "No code_challenge_methods_supported. The provider does not advertise PKCE, which is recommended for the authorization code flow.",
        "DISCOVERY_NO_PKCE_S256": "PKCE is advertised but without the S256 method. S256 is the recommended code challenge method."
      },
      "flow": {
        "heading": "Authorization code flow",
        "laneRp": "Relying Party",
        "laneOp": "OpenID Provider",
        "s1": "Redirect the user to the provider with scope=openid",
        "s2": "Provider authenticates the user and gets consent",
        "s3": "Provider redirects back with an authorization code",
        "s4": "Relying Party exchanges the code at the token endpoint",
        "s5": "Provider returns an ID token plus an access token",
        "s6": "Relying Party validates the ID token signature against the JWKS",
        "s7": "Relying Party may call UserInfo with the access token",
        "s8": "Provider returns the user's claims"
      }
    },
    "bigip-persistence-cookie": {
      "name": "BIG-IP Persistence Cookie Decoder",
      "blurb": "Decode an F5 BIGipServer persistence cookie into the backend pool member's IP and port, or encode one from an address and port. Runs entirely in your browser.",
      "inputLabel": "BIGipServer cookie",
      "inputPlaceholder": "Paste a cookie value, a name=value pair, or a full Set-Cookie line. Example: 1677787402.20480.0000",
      "runsLocally": "Decoded in your browser. The cookie is never sent anywhere.",
      "mode": {
        "label": "Decode or encode",
        "decode": "Decode",
        "encode": "Encode"
      },
      "errors": {
        "empty": "Enter a BIGipServer cookie value to decode.",
        "unrecognized": "This does not match any known BIG-IP persistence cookie format. Check that you pasted the cookie value, not just the name."
      },
      "encodeErrors": {
        "address": "Enter a valid IPv4 or IPv6 address.",
        "port": "Enter a port between 0 and 65535.",
        "routedomain": "Route domain must be a number between 0 and 65535."
      },
      "badges": {
        "ipv4": "Default IPv4",
        "ipv4Rd": "IPv4 in route domain",
        "ipv6": "IPv6",
        "ipv6Rd": "IPv6 in route domain",
        "encrypted": "Encrypted",
        "internal": "Internal address",
        "public": "Public address"
      },
      "panels": {
        "result": "Decoded pool member",
        "encrypted": "Encrypted cookie"
      },
      "fields": {
        "cookieName": "Cookie name",
        "address": "IP address",
        "port": "Port",
        "routeDomain": "Route domain",
        "addressType": "Address type",
        "endpoint": "Pool member"
      },
      "reasons": {
        "INFO_DISCLOSURE": "This cookie exposes a backend pool member's IP address and port to anyone who can read the response. Enable cookie encryption on the persistence profile to prevent this.",
        "INTERNAL_ADDRESS": "The decoded address is {value}, confirming an internal pool member and revealing part of your internal topology.",
        "ROUTE_DOMAIN": "The pool member sits in route domain {value}.",
        "ENCRYPTED": "This cookie is AES-encrypted. The pool member cannot be recovered without the BIG-IP's key, which is the recommended secure configuration."
      },
      "disclosureNote": "Decoding uses only the public encoding scheme (F5 K6917). It confirms what any client can already read from the cookie; the fix is to encrypt the persistence cookie.",
      "encryptedNote": "An encrypted persistence cookie is the recommended configuration. There is nothing to decode without the key, and that is by design.",
      "encode": {
        "addressLabel": "Pool member address",
        "addressPlaceholder": "10.1.1.100 or 2001:112::30",
        "portLabel": "Port",
        "routeDomainLabel": "Route domain (optional)",
        "routeDomainPlaceholder": "e.g. 0",
        "resultLabel": "Cookie value",
        "resultNote": "This is the value a BIG-IP would set for that pool member using the default (unencrypted) encoding."
      }
    },
    "url-inspector": {
      "name": "URL Inspector",
      "blurb": "Dissect any URL into its named parts: scheme, host, port, path, query parameters, and fragment. Decodes percent-escapes and internationalized hosts, and flags credentials and other issues. Runs entirely in your browser.",
      "inputLabel": "URL",
      "inputPlaceholder": "Paste a URL. Example: https://user@host.example.com:8443/path?q=hello%20world#section",
      "runsLocally": "Parsed in your browser. The URL is never sent anywhere.",
      "panels": {
        "components": "Components",
        "query": "Query parameters",
        "assessment": "Assessment"
      },
      "fields": {
        "scheme": "Scheme",
        "userinfo": "User info",
        "host": "Host",
        "hostUnicode": "Host (Unicode)",
        "port": "Port",
        "isDefault": "(default for the scheme)",
        "defaultImplied": "not set; defaults to {port}",
        "path": "Path",
        "segments": "Path segments",
        "fragment": "Fragment"
      },
      "hostType": {
        "ipv4": "IPv4",
        "ipv6": "IPv6",
        "registeredName": "domain name"
      },
      "credentials": "password present",
      "emptyValue": "(no value)",
      "emptyString": "(empty)",
      "emptyQuery": "The query string is present but empty.",
      "errors": {
        "empty": "Enter a URL to inspect."
      },
      "reasons": {
        "RELATIVE_REFERENCE": "This is a relative reference, not an absolute URL: it has no scheme and no host.",
        "NO_SCHEME": "No scheme is present, so this URL is not absolute.",
        "CREDENTIALS_IN_URL": "This URL embeds a username and password. Credentials in a URL are easily logged, cached, and shared, and should be avoided.",
        "USERINFO_PRESENT": "This URL includes a userinfo component (a username before the host).",
        "PLAINTEXT_SCHEME": "The {value} scheme is not encrypted in transit. Anything sent over it can be read on the network.",
        "NON_DEFAULT_PORT": "The port {value} is not the default for this scheme.",
        "REDUNDANT_DEFAULT_PORT": "The port {value} is the default for this scheme and can be omitted.",
        "IDN_HOST": "The host is internationalized and stored in punycode; the Unicode form is shown above. Watch for look-alike characters in untrusted links.",
        "UPPERCASE_SCHEME": "The scheme contains uppercase letters. Schemes are case-insensitive and are normally written in lowercase.",
        "UPPERCASE_HOST": "The host contains uppercase letters. Host names are case-insensitive and are normally written in lowercase.",
        "PERCENT_ENCODED": "This URL contains percent-encoded characters, which have been decoded in the breakdown above.",
        "PLUS_IN_QUERY": "The query contains a plus sign. Under form encoding (application/x-www-form-urlencoded) a plus means a space; under strict RFC 3986 it is a literal plus. The values above keep it literal."
      },
      "note": "Components are shown exactly as written, without normalization. Parsing follows RFC 3986; the query is split on & and =, and each part is percent-decoded."
    },
    "json-formatter": {
      "name": "JSON Formatter & Validator",
      "blurb": "Validate, pretty-print, minify, and sort JSON. Parse errors point to the exact line, column, and path; duplicate keys are flagged; and large numbers are preserved exactly. Runs entirely in your browser.",
      "inputLabel": "JSON",
      "inputPlaceholder": "Paste JSON to validate and format. Example: [\"id\", 42, true]",
      "runsLocally": "Validated and formatted in your browser. Nothing is sent anywhere.",
      "controlsLabel": "Formatting options",
      "controls": {
        "mode": "Mode",
        "indent": "Indent",
        "sortKeys": "Sort keys"
      },
      "modePretty": "Pretty",
      "modeMinify": "Minify",
      "indentSpaces": "{n} spaces",
      "indentTab": "Tabs",
      "errorTitle": "Invalid JSON",
      "errorLocation": "Line {line}, column {column}",
      "errorAt": "at {pointer}",
      "rootPointer": "the document root",
      "outputTitle": "Formatted",
      "copy": "Copy",
      "copied": "Copied",
      "duplicatesTitle": "Duplicate keys found ({count})",
      "duplicateItem": "{key} at {pointer}",
      "statsValid": "Valid JSON",
      "statBytes": "{n} chars",
      "statKeys": "{n} keys",
      "statObjects": "{n} objects",
      "statArrays": "{n} arrays",
      "statDepth": "depth {n}"
    },
    "json-yaml-convert": {
      "name": "JSON ↔ YAML Converter",
      "blurb": "Convert JSON to block-style YAML or YAML back to JSON, entirely in your browser. Parse errors point to the exact line and column, and conversion notes flag the lossy edges like dropped comments and expanded anchors.",
      "inputLabel": "Source",
      "inputPlaceholder": "Paste JSON or YAML to convert.",
      "runsLocally": "Converted in your browser. Nothing is sent anywhere.",
      "controlsLabel": "Conversion options",
      "controls": {
        "direction": "Direction",
        "indent": "Indent"
      },
      "dirJsonToYaml": "JSON → YAML",
      "dirYamlToJson": "YAML → JSON",
      "indentSpaces": "{n} spaces",
      "mismatchJson": "This input looks like JSON.",
      "mismatchYaml": "This input looks like YAML.",
      "switchTo": "Switch direction",
      "errorTitle": "Could not convert",
      "errorLocation": "Line {line}, column {column}",
      "errorAt": "at {pointer}",
      "rootPointer": "the document root",
      "notesTitle": "Conversion notes",
      "notes": {
        "COMMENTS_DROPPED": "Comments were dropped. JSON has no way to represent them.",
        "ANCHORS_EXPANDED": "Anchors and aliases were expanded inline; the repeated values are written out in full.",
        "MERGE_KEYS_LITERAL": "YAML merge keys were kept as literal keys rather than flattened into the surrounding map.",
        "LARGE_NUMBER": "This document has a very large number. Conversion uses JavaScript number precision, so values beyond about sixteen digits may be rounded; use the JSON formatter when exact digits matter."
      },
      "outputYaml": "YAML",
      "outputJson": "JSON",
      "copy": "Copy",
      "copied": "Copied"
    },
    "tmsh-config-explainer": {
      "name": "tmsh config explainer",
      "blurb": "Paste a BIG-IP bigip.conf snippet and get a plain-English breakdown of every object, plus the structure, entirely in your browser.",
      "inputLabel": "bigip.conf snippet",
      "inputPlaceholder": "Paste a bigip.conf snippet: ltm virtual, ltm pool, ltm monitor, an iRule, and so on.",
      "runsLocally": "Parsed in your browser. Nothing is uploaded.",
      "errorTitle": "Could not parse the configuration",
      "lineLabel": "Line {line}",
      "emptyState": "No configuration objects found. Paste a bigip.conf snippet to see it explained.",
      "summaryLabel": "Objects found",
      "unknownType": "object",
      "notExplained": "not yet explained",
      "blockTag": "block",
      "iruleLabel": "This is a Tcl iRule, shown verbatim. It is code that runs on events, not tmsh configuration.",
      "notesHeading": "Things to notice"
    },
    "persistence-method-explainer": {
      "name": "Persistence-method explainer",
      "blurb": "Paste BIG-IP persistence profiles and virtual servers and get the method behind each, its failure modes, and the primary-to-fallback chain, all in your browser.",
      "inputLabel": "Persistence config (profiles and virtuals)",
      "inputPlaceholder": "Paste ltm persistence profiles and ltm virtual servers with their persist and fallback-persistence settings.",
      "runsLocally": "Parsed in your browser. Nothing is uploaded.",
      "errorTitle": "Could not parse the configuration",
      "lineLabel": "Line {line}",
      "emptyState": "No persistence profiles or virtual-server persistence found. Paste a persistence profile or a virtual with a persist setting.",
      "chainsHeading": "Persistence chains",
      "primaryLabel": "Primary",
      "fallbackLabel": "Fallback",
      "noneLabel": "none",
      "profilesHeading": "Persistence profiles",
      "keysOnLabel": "Keys on",
      "goodForLabel": "Good for",
      "caveatsHeading": "Watch out for",
      "notExplained": "not yet explained",
      "unknownMethod": "method",
      "blockTag": "block"
    },
    "f5-cipher-string-expander": {
      "name": "F5 cipher-string explainer",
      "blurb": "Paste an F5 BIG-IP cipher string and get every keyword and operator explained plus a security read, all in your browser.",
      "inputLabel": "F5 cipher string or rule name",
      "inputPlaceholder": "Paste an F5 cipher string such as ECDHE:RSA:!SSLv3:!RC4:@STRENGTH, or a rule name like f5-secure.",
      "runsLocally": "Parsed in your browser. Nothing is uploaded.",
      "expansionNote": "This explains the keywords, operators, and security posture of the string. It does not reproduce the exact ordered suite list, which depends on the TMOS version; run tmm --clientciphers on the target box for that.",
      "errorTitle": "Could not read the cipher string",
      "ruleExpands": "Pre-built rule {name} uses the cipher string:",
      "securityHeading": "Security read",
      "pfsYes": "Forward secrecy",
      "pfsNo": "No forward secrecy",
      "goodHeading": "Good",
      "concernsHeading": "Concerns",
      "setsHeading": "Cipher sets, in order",
      "opInclude": "select",
      "opExclude": "exclude",
      "opDelete": "remove",
      "opLowerPriority": "lower priority",
      "opSort": "sort",
      "notRecognized": "not recognized"
    },
    "syslog-pri-decoder": {
      "name": "Syslog PRI decoder + encoder",
      "blurb": "Decode a syslog PRI such as 134 into its facility and severity, or encode them back, all in your browser.",
      "modeLabel": "Decode or encode",
      "modeDecode": "Decode PRI",
      "modeEncode": "Encode PRI",
      "formula": "PRI = facility × 8 + severity",
      "decodeInputLabel": "PRI value",
      "decodeInputPlaceholder": "Enter a PRI, for example 134",
      "runsLocally": "Computed in your browser. Nothing is uploaded.",
      "priLabel": "PRI",
      "wireLabel": "On the wire",
      "facilityHeading": "Facility",
      "severityHeading": "Severity",
      "facilityVaries": "Facilities 12 to 15 are not standardized in RFC 5424 and vary by implementation.",
      "encodeFacilityLabel": "Facility",
      "encodeSeverityLabel": "Severity",
      "struct": {
        "heading": "How a PRI splits into facility and severity",
        "note": "A single PRI integer carries both fields. Dividing by 8 gives the facility, and the remainder gives the severity, so PRI 134 is facility 16 and severity 6. Encoding runs the other way: facility × 8 + severity."
      }
    },
    "jwks-explainer": {
      "name": "JWKS explainer + key matcher",
      "blurb": "Paste a JSON Web Key Set to break down every key, flag any private material, and match a JWT to its key by kid. Nothing leaves your browser.",
      "modeLabel": "Explain or match",
      "modeExplain": "Explain a JWKS",
      "modeMatch": "Match a JWT",
      "jwksInputLabel": "JWK Set (or a single JWK)",
      "jwksInputPlaceholder": "Paste a JWKS here",
      "runsLocally": "Parsed in your browser. No jwks_uri is fetched.",
      "jwtInputLabel": "JWT to match",
      "jwtInputPlaceholder": "Paste a JWT, or just its header",
      "noKid": "no kid",
      "useField": "Use",
      "useSig": "Signature",
      "useEnc": "Encryption",
      "algField": "Algorithm",
      "sizeField": "Size",
      "publicParamsField": "Public parameters",
      "privateParamsField": "Private parameters",
      "keySingular": "key",
      "keyPlural": "keys",
      "privateBanner": "This set contains private key material. A JWKS should only ever contain public keys.",
      "headerKidField": "Header kid",
      "headerAlgField": "Header alg",
      "algMismatch": "The JWT alg does not match the matched key alg.",
      "diag": {
        "heading": "How a key is matched by kid",
        "jwtHeader": "JWT header",
        "matchLabel": "matched by kid",
        "note": "When a JWT arrives, the verifier reads its kid and finds the one key in the set with the same kid, then uses that key to check the signature. Each key needs a distinct kid for this to be unambiguous."
      }
    },
    "regex": {
      "name": "Regex Toolkit",
      "blurb": "Test, explain, and debug regular expressions with live matches and a backtracking-risk check.",
      "title": "Regex Toolkit",
      "description": "Compile a JavaScript regular expression, test it against your own text with every match and capture group highlighted, and read a plain-language breakdown of what the pattern does — all in your browser.",
      "patternLabel": "Pattern and flags",
      "patternPlaceholder": "\\w+@\\w+\\.\\w+",
      "flagsLabel": "Flags",
      "flagsPlaceholder": "gim",
      "testLabel": "Test text",
      "testPlaceholder": "Paste text to match against...",
      "valid": "Valid pattern",
      "invalid": "Invalid pattern:",
      "redosTitle": "Possible catastrophic backtracking",
      "redosBody": "This pattern nests an unbounded quantifier inside another (the (a+)+ shape), which can be slow or hang on some inputs. Run it against a short string first.",
      "runAnyway": "Run anyway",
      "explanationHeading": "What this pattern does",
      "matchesHeading": "Matches",
      "noMatches": "No matches in the test text.",
      "atWord": "at",
      "groupsWord": "Groups",
      "namedWord": "Named",
      "showingFirst": "Showing the first",
      "matchesWord": "matches",
      "tooLong": "The test text is too long to run; shorten it and try again.",
      "runsLocally": "Runs entirely in your browser."
    },
    "title": "Tools",
    "lede": "Small, fast, privacy-first utilities that run entirely in your browser. Nothing you type is sent anywhere. More are on the way.",
    "open": "Open",
    "comingSoon": "Coming soon",
    "note": "This toolbox is growing. New tools are added here as they ship, each one local-first and free to use.",
    "cipher": {
      "name": "Cipher Suite Decoder",
      "blurb": "Enter a TLS cipher suite, as an IANA name, an OpenSSL or GnuTLS name, or a hex code point, to break it into its key exchange, authentication, cipher, mode, and MAC, with a plain-language security read-out and the official IANA recommendation. Runs entirely in your browser against a bundled copy of the IANA registry.",
      "inputLabel": "Cipher suite",
      "inputPlaceholder": "TLS_AES_128_GCM_SHA256, ECDHE-RSA-AES128-GCM-SHA256, or 0x1301",
      "runsLocally": "Decoding runs locally against a bundled copy of the IANA TLS Cipher Suite registry. Nothing is sent anywhere.",
      "notInRegistryNote": "This name parsed structurally but was not found in the bundled IANA registry snapshot, so its code point and cross-names are not shown.",
      "errors": {
        "empty": "Enter a cipher suite to decode.",
        "format": "That is not a cipher suite. Enter an IANA name (TLS_...), an OpenSSL name, or a hex code point such as 0x1301.",
        "unknown": "That is a valid code-point format, but it is not an assigned cipher suite in the IANA registry."
      },
      "ratings": {
        "recommended": "Recommended",
        "secure": "Secure",
        "weak": "Weak",
        "insecure": "Insecure",
        "unknown": "Unknown"
      },
      "iana": {
        "Y": "IANA: Recommended",
        "N": "IANA: not recommended",
        "D": "IANA: discouraged"
      },
      "badges": {
        "tls13": "TLS 1.3",
        "notInRegistry": "Not in IANA snapshot"
      },
      "panels": {
        "identity": "Identity",
        "components": "Components",
        "security": "Security"
      },
      "fields": {
        "codePoint": "Code point",
        "name": "IANA name",
        "openssl": "OpenSSL name",
        "gnutls": "GnuTLS name",
        "protocol": "Protocol",
        "dtls": "DTLS-OK",
        "references": "References"
      },
      "protocol": {
        "tls13": "TLS 1.3",
        "legacy": "TLS 1.2 and earlier"
      },
      "comp": {
        "keyExchange": "Key exchange",
        "authentication": "Authentication",
        "forwardSecrecy": "Forward secrecy",
        "cipher": "Cipher",
        "mode": "Mode",
        "aead": "AEAD",
        "prf": "PRF / KDF hash",
        "mac": "MAC",
        "yes": "Yes",
        "no": "No",
        "bits": "{n}-bit",
        "negotiatedSeparately": "Negotiated separately (TLS 1.3)"
      },
      "reasons": {
        "nullCipher": "NULL cipher: the traffic is not encrypted at all.",
        "anon": "Anonymous key exchange: the peer is not authenticated, so it gives no protection against an active man-in-the-middle.",
        "export40": "Export-grade 40-bit key: trivially brute-forced, a relic of 1990s export rules.",
        "rc4": "RC4 stream cipher: a biased keystream makes it broken, and RFC 7465 prohibits it for TLS.",
        "singleDes": "Single DES with a 56-bit key: brute-forceable in hours.",
        "rc2": "RC2: an obsolete 40/64-bit cipher that is not safe for modern use.",
        "tripleDes": "3DES has a 64-bit block, which exposes it to the Sweet32 birthday attack (CVE-2016-2183). RFC 8429 deprecates it.",
        "md5Mac": "MD5 MAC: MD5 is cryptographically broken.",
        "cbcMac": "CBC with an HMAC-SHA1 or MD5 MAC uses MAC-then-encrypt, which is exposed to padding-oracle attacks such as BEAST and Lucky13.",
        "ccm8": "CCM_8 truncates the authentication tag to 8 bytes, weakening integrity. IANA does not mark it Recommended.",
        "noFs": "No forward secrecy: with a static key exchange, one compromised long-term key can decrypt past sessions. Modern guidance requires ECDHE or DHE.",
        "legacyCipher": "{value} is a legacy cipher that is deprecated for TLS.",
        "aead": "AEAD cipher (authenticated encryption): confidentiality and integrity in one primitive, with no separate MAC to misuse.",
        "fs": "Forward secrecy: an ephemeral key exchange keeps past traffic safe even if the long-term key is later compromised.",
        "tls13": "TLS 1.3 suite: only modern AEAD ciphers, with the key exchange negotiated separately and always ephemeral.",
        "ianaD": "IANA marks this suite \"D\" (discouraged): it SHOULD NOT or MUST NOT be used, depending on the situation.",
        "ianaN": "IANA does not mark this suite \"Recommended\": it has limited applicability or has not been through the IETF consensus process.",
        "signalling": "Signalling suite (SCSV): not an actual cipher, it carries a protocol signal such as fallback protection or renegotiation info."
      },
      "groups": {
        "title": "Key-exchange groups",
        "intro": "TLS negotiates the actual key-agreement group separately from the cipher suite, in the supported_groups extension. As \"harvest now, decrypt later\" drives the move to post-quantum key agreement, the hybrid groups below pair a classical curve with ML-KEM.",
        "kind": {
          "ecdhe": "ECDHE curve",
          "ffdhe": "Finite-field DH",
          "pq-hybrid": "PQ hybrid"
        },
        "pq": {
          "classical": "Classical",
          "hybrid-pq": "Hybrid PQ"
        },
        "recommended": "Recommended",
        "obsolete": "Obsolete",
        "legacy": "Legacy",
        "combines": "Combines {classical} with {pq}",
        "foot": "X25519MLKEM768 is the hybrid most browsers now send by default."
      }
    },
    "f5-ssl-profile-explainer": {
      "name": "F5 SSL profile explainer",
      "blurb": "Paste a tmsh client-ssl or server-ssl profile and get its role, the TLS protocol matrix, and a security read covering chain, renegotiation, SNI, OCSP, and mutual TLS — all in your browser.",
      "inputLabel": "SSL profile (tmsh)",
      "inputPlaceholder": "ltm profile client-ssl /Common/name ...",
      "runsLocally": "Parsed in your browser. Nothing is sent anywhere.",
      "scopeNote": "Decodes a pasted profile block. It never contacts a BIG-IP.",
      "errorTitle": "Could not read the profile",
      "err_empty": "Paste an SSL profile to begin.",
      "err_noHeader": "Expected a line like: ltm profile client-ssl /Common/name ...",
      "err_noBody": "No opening brace was found in the profile.",
      "err_tooLong": "That input is too large to parse.",
      "err_invalid": "That does not look like a client-ssl or server-ssl profile.",
      "protocolsHeading": "TLS protocol versions",
      "permitted": "permitted",
      "disabled": "disabled",
      "findingsHeading": "Security assessment",
      "settingsHeading": "Settings explained",
      "topoHeading": "In the data path",
      "nodeClient": "Client",
      "nodeBigip": "BIG-IP",
      "nodePool": "Pool member",
      "clientLeg": "Client-side TLS",
      "serverLeg": "Server side",
      "thisProfile": "this profile",
      "clientNote": "A client-ssl profile terminates the client's TLS at the BIG-IP. The connection on to the pool member is re-encrypted only if a server-ssl profile is applied; with none, that leg is cleartext (SSL offload).",
      "serverNote": "A server-ssl profile lets the BIG-IP open a fresh TLS connection to the pool member (re-encryption). The client side is handled by a separate client-ssl profile."
    },
    "epoch": {
      "name": "Unix time converter",
      "blurb": "Type a Unix timestamp — seconds, milliseconds, microseconds, or nanoseconds, detected automatically — or an ISO-8601 date, and read it back in every common format. All in your browser.",
      "inputLabel": "Timestamp or date",
      "inputPlaceholder": "1700000000  or  2023-11-14T22:13:20Z",
      "runsLocally": "Converted in your browser. Nothing is sent anywhere.",
      "scopeNote": "Pure date math. The unit is guessed from the number's size; correct it if needed.",
      "nowButton": "Now",
      "errorTitle": "Could not read that",
      "err_empty": "Enter a timestamp or date to begin.",
      "err_invalid": "That is not a Unix timestamp or an ISO-8601 date.",
      "err_tooLong": "That input is too long.",
      "err_outOfRange": "That timestamp is outside the representable date range.",
      "utcHeading": "UTC date and time",
      "formatsHeading": "Every format",
      "dayOfYearLabel": "day of year",
      "relativeNote": "relative to your device clock"
    },
    "irules-event-order": {
      "name": "iRule event order",
      "blurb": "Pick the profile stack on a BIG-IP virtual server — client-SSL, HTTP, server-SSL, pool — and see the order the common iRule events fire, from CLIENT_ACCEPTED to CLIENT_CLOSED, as a timeline and a list. All in your browser.",
      "stackLabel": "Virtual server profile stack",
      "tog_clientssl": "Client-SSL profile",
      "tog_http": "HTTP profile",
      "tog_serverssl": "Server-SSL profile",
      "tog_pool": "Pool (load balancing)",
      "tog_fastl4": "FastL4 (packet fast path)",
      "presetsLabel": "Presets:",
      "preset_https": "HTTPS re-encrypt",
      "preset_offload": "SSL offload",
      "preset_http": "HTTP",
      "preset_tcp": "Raw TCP",
      "runsLocally": "Computed in your browser. Nothing is sent anywhere.",
      "scopeNote": "A model of documented F5 behavior for a Standard virtual server. It never contacts a BIG-IP.",
      "diagramHeading": "Event sequence",
      "listHeading": "Events in order",
      "conditionalHeading": "Conditional events",
      "conditionalNote": "These fire only under specific conditions: a TCP::collect or HTTP::collect, a load-balancing failure, or a 100 Continue response.",
      "sideClient": "client side",
      "sideServer": "server side",
      "sideGlobal": "global"
    },
    "cert-renewal-planner": {
      "name": "Certificate renewal planner",
      "blurb": "Work out a TLS certificate's validity, whether it fits the CA/Browser Forum 47-day schedule, and the renewal cadence it implies — all offline.",
      "notBeforeLabel": "Issued (notBefore)",
      "notAfterLabel": "Expires (notAfter)",
      "runsLocally": "Everything runs in your browser; nothing is uploaded.",
      "exampleLabel": "Try a 90-day example",
      "summaryHeading": "This certificate",
      "validity": "{days}-day validity",
      "compliantBadge": "Within the cap",
      "overCapBadge": "Over the cap",
      "maxForPhase": "Maximum for its issuance date: {max} days.",
      "overByText": "{days} days over the {max}-day maximum for its issuance date — a public CA would not issue it.",
      "renewalsValue": "About {n} renewals per year at this validity.",
      "remainingHeading": "From your device clock",
      "daysRemaining": "{days} days until it expires.",
      "expiredText": "Expired {days} days ago.",
      "renewByText": "Renew by {date} (about {lead} days before expiry)",
      "renewByDue": "{days} days from now",
      "reuseHeading": "Validation reuse (issuance era)",
      "dcvText": "Domain validation (DCV) data can be reused for {days} days.",
      "siiText": "Organization identity (OV/EV SII) can be reused for {days} days.",
      "scheduleHeading": "The SC-081v3 schedule",
      "scheduleIntro": "Public TLS maximums key off the certificate's issuance date:",
      "colPeriod": "Issued on/after",
      "colValidity": "Max validity (days)",
      "colDcv": "DCV reuse (days)",
      "colSii": "SII reuse (days)",
      "phaseP0": "Before 15 Mar 2026",
      "phaseP1": "15 Mar 2026",
      "phaseP2": "15 Mar 2027",
      "phaseP3": "15 Mar 2029",
      "yourPhase": "← this cert",
      "projectionHeading": "Renewal load at each cap",
      "projectionIntro": "Renewals per certificate per year, as the caps tighten:",
      "perYearShort": "yr",
      "note_overCap": "This validity exceeds the {max}-day maximum for its issuance date.",
      "note_future47": "Compliant today, but longer than the eventual 47-day cap — expect more frequent renewals as the schedule advances.",
      "note_publicOnly": "These caps apply to publicly trusted TLS certificates only. Private or internal PKI is not governed by SC-081v3.",
      "note_automate": "At these cadences, automate issuance and renewal with ACME (RFC 8555) and ARI (RFC 9773); manual renewal does not scale.",
      "err_empty": "Enter both the issue and expiry dates.",
      "err_invalidDate": "Use a valid date (YYYY-MM-DD).",
      "err_order": "The expiry date must be after the issue date.",
      "err_tooLong": "That input is too long.",
      "err_invalid": "Could not read those dates."
    },
    "csr-decoder": {
      "name": "CSR decoder",
      "blurb": "Decode a PKCS#10 certificate signing request to read its subject, public key, requested SANs and extensions, and attributes — entirely in your browser.",
      "inputLabel": "Certificate signing request (PEM, base64, or hex)",
      "inputPlaceholder": "-----BEGIN CERTIFICATE REQUEST-----\n...",
      "exampleLabel": "Load an example CSR",
      "runsLocally": "Everything runs in your browser; the CSR is never uploaded.",
      "notCertNote": "A CSR is a request, not a certificate. It has no serial number, no issuer, and no validity dates — only what the requester is asking a CA to certify.",
      "subjectHeading": "Subject",
      "colAttr": "Attribute",
      "colValue": "Value",
      "noSubject": "No subject name (this CSR relies on requested SANs).",
      "keyHeading": "Public key",
      "keyAlgorithmLabel": "Algorithm",
      "keySizeLabel": "Size",
      "keySizeValue": "{bits} bits",
      "keyCurveLabel": "Curve",
      "keyExponentLabel": "Exponent",
      "keyExponentValue": "{exp}",
      "requestedHeading": "Requested extensions",
      "sanLabel": "Subject Alternative Names",
      "keyUsageLabel": "Key usage",
      "ekuLabel": "Extended key usage",
      "basicConstraintsLabel": "Basic constraints",
      "caYes": "CA: yes",
      "caNo": "CA: no",
      "pathLenValue": "path length {n}",
      "noRequested": "No extensions requested.",
      "attributesHeading": "Attributes",
      "challengePasswordLabel": "Challenge password",
      "unstructuredNameLabel": "Unstructured name",
      "signatureHeading": "Self-signature",
      "signatureAlgLabel": "Algorithm",
      "signatureBitsLabel": "Length",
      "signatureBitsValue": "{bits} bits",
      "versionValue": "Version: v1 ({v})",
      "derLengthValue": "DER: {bytes} bytes",
      "err_empty": "Paste a certificate signing request to decode.",
      "err_format": "That does not look like a PEM, base64, or hex CSR.",
      "err_der": "The DER structure could not be parsed.",
      "err_structure": "This parses as DER but is not a PKCS#10 certification request."
    }
  },
  "privacy_page": {
    "eyebrow": "Privacy",
    "title": "Your data, and what this site does with it",
    "lede": "A plain-language account of exactly what this website does and does not do with your information. It is written to be accurate rather than merely reassuring, because under regulations like the GDPR and Brazil's LGPD it is the accurate disclosure that matters.",
    "shortTitle": "The short version",
    "short1": "This site sets no cookies, runs no analytics, uses no advertising, and contains no third-party trackers or fingerprinting. Nothing follows you across the web.",
    "short2": "It does not sell, share, or build profiles of its visitors, and it asks you for nothing in order to read it.",
    "short3": "The interactive tools run entirely in your browser. What you paste or type into them stays on your device and is not transmitted anywhere.",
    "short4": "Only three things involve data at all, and each is explained below: a single theme setting saved in your own browser, the standard connection logs that every website visit creates at the hosting layer, and any message you choose to send by email.",
    "controllerTitle": "Who is responsible",
    "controllerBody": "This is the personal website of Rodolfo Nützmann (ronutz.com). For any privacy question, or to exercise any of the rights described below, write to {email}. Enquiries are handled directly by Rodolfo Nützmann, as the data controller.",
    "noTrackTitle": "No cookies, no tracking, no analytics",
    "noTrackBody": "This site sets no cookies of any kind. It uses no analytics service (such as Google Analytics or Plausible), no advertising network, no social-media tracking pixels, and no device fingerprinting. Your visit is not measured, profiled, or shared with anyone for those purposes.",
    "browserTitle": "What is stored in your browser",
    "browserBody": "One small thing: your chosen visual theme, saved in your browser's local storage so the site can remember it the next time you visit. It is a convenience setting that stays on your own device, is never sent to this site or to anyone else, and can be cleared at any time through your browser. No other data about you is stored on your device.",
    "hostingTitle": "Hosting and server logs",
    "hostingBody": "The site is delivered through Cloudflare, which provides its hosting and content delivery. As with any website, loading a page means your device connects to a server, and Cloudflare, acting as the hosting provider, processes basic connection data, including your IP address and standard request details, in order to deliver the pages to you and to protect the site against abuse and attack. This processing is necessary to operate and secure the site (a legitimate interest under GDPR Article 6(1)(f), and the corresponding bases under LGPD Articles 7 and 10). It is retained only briefly by the provider and is not used here to identify or track you.",
    "toolsTitle": "The tools run in your browser",
    "toolsBody": "The decoders and calculators on this site, for JWTs, IP addresses, certificates and the rest, compute entirely within your browser. The values you enter are processed on your own device and are never sent to a server. A separate programmatic interface (an API) is offered for automation and integrations; by design it is stateless and logs none of the queries or request bodies sent to it.",
    "contactTitle": "If you contact me",
    "contactBody": "The contact form does not submit to any server. Instead it opens a pre-filled message in your own email application, which you then send yourself from your own account, so nothing passes through a third party. If you do write, whether through the form or directly, I receive the information you include, such as your name, email address and message, and use it only to reply to you. I keep it only for as long as needed to deal with your enquiry, do not use it for marketing, and do not share it.",
    "intlTitle": "Processing outside your country",
    "intlBody": "Because Cloudflare operates a global network, the connection-level processing described above may take place on servers located outside your own country, including outside Brazil and the European Economic Area. Where personal data is handled internationally in this way, it is processed under the safeguards offered by the provider concerned.",
    "childrenTitle": "Children",
    "childrenBody": "This site is intended for a professional, general audience. It is not directed at children and does not knowingly collect personal data from them.",
    "rightsTitle": "Your rights",
    "rightsBody": "Depending on where you live, you have rights over your personal data, including to access it, to have it corrected or deleted, to object to or restrict its processing, to request a copy in a portable form, and to be told how it is handled. To exercise any of these, simply write to {email}. Because so little personal data is ever processed here, in practice there is usually very little to act on, but the channel is always open.",
    "rightsGdpr": "If you are in the European Economic Area or the United Kingdom, you also have the right to lodge a complaint with your local data protection supervisory authority.",
    "rightsLgpd": "If you are in Brazil, you hold the rights set out in Article 18 of the LGPD, and may also contact the national data protection authority (the ANPD).",
    "changesTitle": "Changes to this notice",
    "changesBody": "If this notice changes, the revised version will be published on this page and the date below will be updated. Material changes will not be applied retroactively.",
    "updated": "Last updated: 30 June 2026",
    "backHome": "Back to home"
  },
  "footer": {
    "redEducation": "Book official training with <b>Red Education</b>",
    "builtWith": "Built by Rodolfo Nützmann with CONCORD",
    "colophon": "How this was built",
    "contribute": "Improve the translations",
    "api": "API reference",
    "contributeTools": "Share an idea",
    "feedback": "Submit feedback",
    "privacy": "Privacy",
    "license": "License",
    "coffee": "Buy me a coffee"
  },
  "search": {
    "kindTool": "Tool",
    "kindArticle": "Article",
    "kindPage": "Page",
    "label": "Search",
    "placeholder": "Search the site…",
    "close": "Close",
    "searching": "Searching…",
    "noResults": "No results for “{query}”.",
    "unavailable": "Search runs on the published site. It is not available in local preview.",
    "hint": "Type to search articles, tools, and pages."
  },
  "theme": {
    "label": "Theme",
    "dark": "Dark",
    "light": "Light"
  },
  "about": {
    "eyebrow": "The instructor",
    "role": "Senior Technical Instructor",
    "lede": "Network and security training delivered by a practitioner who has spent his career on the implementation side, not just the slides. Based in São Paulo, teaching globally, in Portuguese and English.",
    "now": {
      "title": "What I do now",
      "body": "I deliver official, certified instructor-led training across four security and networking platforms. The work is hands-on and lab-driven: the goal is always that people leave able to do the thing, not just describe it. I have been an authorized instructor since 1996, and training and technical enablement have been part of my work since the late 1990s.",
      "basedLabel": "Based in",
      "basedValue": "São Paulo, Brazil",
      "teachesLabel": "Teaches",
      "teachesValue": "Virtual and on-site instructor-led training, globally",
      "languagesLabel": "Languages",
      "languagesValue": "Portuguese (native), English (fluent)"
    },
    "platforms": {
      "title": "Four platforms, taught in depth",
      "body": "Being certified across four vendors means I can teach each one properly and compare them honestly. These are the platforms I am currently authorized to deliver official training for.",
      "f5": "BIG-IP across the full instructor-led curriculum: LTM, DNS, Advanced WAF (ASM), APM, AFM, SSL Orchestrator, automation, and troubleshooting.",
      "fortinet": "Fortinet certified training, including the FCP track.",
      "extreme": "Extreme Networks switching, SD-WAN, and API and automation tracks, across installation, configuration, management, and troubleshooting.",
      "netskope": "Netskope security cloud instructor-led training."
    },
    "path": {
      "title": "The path here",
      "intro": "My career began on the vendor and implementation side in 1996, and stayed there for two decades before I focused fully on training. That implementation background is the reason the training lands: I have built, broken, and fixed these systems in production.",
      "present": "present",
      "cabletron": "Network engineer and certified instructor. Non-Ethernet and Ethernet networks, campus networks, IP routing.",
      "riverstone": "Product support engineer and knowledge-base coordinator in California. Gigabit Ethernet, metropolitan area networks, IP routing, BGP. Third-level escalation, customer scenario recreation, and regression testing.",
      "cisco": "Network consulting engineer, acting as the single point of contact for key customers including SERPRO and Correios. Escalation and customer-satisfaction management.",
      "enterasys": "Network engineer and instructor. Enterprise networks, IP routing, user access control and NAC, IDS and IPS.",
      "juniper": "Channel support engineer and instructor for enterprise switches and firewalls. Technical sales enablement and Junos-SRX operations training.",
      "f5channel": "Channel-facing sales and pre-sales engineering for F5, providing technical enablement, proof-of-concept execution, and partner training across distribution.",
      "rededucation": "Authorized training instructor delivering official certified courses across F5, Fortinet, Extreme Networks, and Netskope to organizations worldwide.",
      "fullHistory": "Read the full history",
      "vendorsLink": "Vendors I have worked with"
    },
    "origins": {
      "title": "Where it started",
      "body": "Before the formal career, there was the curiosity. Through the early 1990s I was importing and assembling computers, running and using bulletin board systems, and working across DOS, Unix, Linux, Netware, early Ethernet, X.25, and dial-up internet. By 1995 that hands-on work had become a first formal role building an electronic-data-interchange system. The thread from then to now is the same: take something genuinely complex and make it work, then make it make sense to someone else."
    },
    "approach": {
      "title": "How I teach",
      "body": "I chose to specialize in training because it combines deep technical knowledge with the part of the work I enjoy most: explaining complex concepts simply. The strongest sessions connect each concept to the job the learner actually has to do, so the content has somewhere to land. Real-world examples, real labs, and a focus on understanding over memorization."
    },
    "cta": {
      "title": "Start with the concepts",
      "body": "The Learn section explains the ideas behind the tools, and the tools let you work with them directly, all in your browser.",
      "learnButton": "Read the Learn section",
      "toolsButton": "Open the tools"
    },
    "recognition": {
      "title": "Recognition",
      "body": "Recognized as an F5 DevCentral MVP for three consecutive years, in 2022, 2023, and 2024, for contributions to the F5 technical community."
    }
  },
  "endorsements": {
    "eyebrow": "Endorsements",
    "title": "What people say, in their own words.",
    "intro": "{count} verbatim recommendations and reviews, spanning two decades of teaching and consulting. Nothing here is paraphrased or edited.",
    "provenance": "Sourced from LinkedIn recommendations, Google reviews, and verified Red Education student reviews. Original wording and spelling are preserved exactly as written."
  },
  "testimonials": {
    "filterLabel": "Filter testimonials",
    "sourceFilter": "Source",
    "languageFilter": "Language",
    "all": "All",
    "showing": "Showing {count} of {total}",
    "reply": "Reply from Red Education",
    "translateLabel": "Translation",
    "translateOff": "Translate to English",
    "translateOn": "Showing English",
    "machineDisclaimer": "Machine-generated translation. It may not accurately reflect the original wording.",
    "showOriginal": "Show original",
    "hideOriginal": "Hide original"
  },
  "history": {
    "indexTitle": "The history",
    "indexLede": "Three eras, one through-line: take something genuinely complex, make it work, then make it make sense to someone else.",
    "eraLabel": "Era",
    "backToHistory": "All eras",
    "backToAbout": "About",
    "readNext": "Read next",
    "pre1996": {
      "years": "Before 1996",
      "title": "The curiosity",
      "subtitle": "Importing parts, assembling machines, and dialing into the early internet, before any of it was a job.",
      "intro": "Every technical career has a before. Before the vendor badges and the certifications, there was a teenager taking machines apart to understand how they worked, and a young autonomous professional turning that understanding into a living. This is where the instinct that drives everything else was formed.",
      "s1Title": "Hands on hardware, 1991 to 1995",
      "s1Body": "From 1991, the work was autonomous and hands-on: importing computer parts from the United States, assembling and selling custom-built personal computers, and installing, configuring, and troubleshooting them for whoever needed help. This was the era of building a machine from components and making it run, not buying one off a shelf. The systems of the day passed through these hands directly: DOS and CP/M, BASIC, Turbo Pascal, early Windows and office applications, and the database tools that ran small businesses then, Clipper and dBase.",
      "s2Title": "The networks before the internet",
      "s2Body": "Networking did not begin with the web. Long before broadband, the connective tissue was different and harder to work with: Novell NetWare for local servers, bulletin board systems for community and file exchange, early Ethernet networks, and the wide-area technologies of the time, X.25 (known in Brazil as RENPAC) and Frame Relay. When the internet did arrive, it arrived over a modem, reached through a shell account, SLIP, or PPP. Working across all of it meant understanding networks from the wire up, an understanding that later made enterprise networking feel like familiar ground.",
      "s3Title": "BBS, phreaking, and the academic internet",
      "s3Body": "The genuine curiosity of the era went beyond paid work. The explorations of those years included running and using bulletin board systems, the phone-network tinkering of the phreaking scene, hands-on UNIX, and early access to the academic internet. This was learning by doing, in a community that shared knowledge because there was nowhere else to get it. That habit, of digging until something is genuinely understood and then passing it on, never went away.",
      "s4Title": "1995: the first formal role",
      "s4Body": "In 1995, the autonomous work converged into a first formal position. At INTELECTA, a company incubated by SEBRAE-SP, the project was an electronic-data-interchange system for the commercialization of medical and hospital supplies, built on Novell NetWare servers and the PCBoard bulletin board system. It was a real system, solving a real commercial problem, and it marked the point where the hobby and the trade became a profession.",
      "closer": "By the end of 1995, the foundation was set: a person who understood machines and networks from first principles, who learned by building, and who already had the instinct to explain. Everything that followed, the vendors, the certifications, the global classrooms, was built on this."
    },
    "era19962020": {
      "years": "1996 – 2020",
      "title": "The practitioner",
      "subtitle": "Two decades inside the networking and security industry, building, breaking, and fixing the systems that later became the curriculum.",
      "intro": "This is the long middle of the story, and the reason the teaching that came later carries weight. For roughly two decades, the work was implementation: designing networks, standing them up, troubleshooting them under pressure, and being the person called when something critical broke. The journey ran through some of the defining names in networking, on two continents.",
      "s1Title": "Cabletron and Enterasys, 1996 to 2000",
      "s1Body": "The formal career began in 1996 at Cabletron Systems, then a leading networking equipment vendor based in Rochester, New Hampshire. Over four and a half years, the role spanned field engineering and post-sales support, systems engineering and pre-sales, and, from 1997, certified instruction. The subject matter was the enterprise LAN and WAN of the era: switches, routers, Wi-Fi and WLAN, network management, NAC and UAC, and stateful-inspection firewalls. In 2000, Cabletron reorganized into four companies, and the part this career touched became Enterasys Networks.",
      "s2Title": "Riverstone Networks, Santa Clara, 2000 to 2002",
      "s2Body": "The next chapter was in California. Riverstone Networks, a Cabletron spin-off building metropolitan-area network equipment, brought a move to Santa Clara on an H1-B1 work visa. The role was Tier-III product support engineer and knowledge-management coordinator: third-level technical escalation, recreating customer scenarios in the lab, regression testing and bug verification, and building the knowledge base that the rest of support relied on. The technologies were the backbone of the early-2000s carrier and metro world: Gigabit Ethernet, MPLS, metropolitan-area switching and routing, and BGP. This period also produced a formal milestone: as part of the visa process, a United States evaluation in 2001 recognized an educational background equivalent to a bachelor's degree in computer science and a bachelor's degree in business administration.",
      "s3Title": "Cisco Systems, Brasília, 2003 to 2004",
      "s3Body": "Back in Brazil, and contracted through Cisco Professional Services, the role shifted toward the customer relationship at its most demanding. As a high-touch operations manager and single point of contact, the work was post-sales customer-satisfaction management for two of Brazil's largest federal entities, SERPRO, the government's data-processing agency, and ECT-Correios, the national postal service. The technical surface was Catalyst switches and routers, PIX firewalls, and CSS, CSM, and ACE load balancers, but the real work was escalation management and keeping critical national infrastructure running smoothly.",
      "s4Title": "Enterasys again, then Juniper, 2005 to 2010",
      "s4Body": "The second half of the decade returned to the vendor side as an enterprise LAN subject-matter expert. At Enterasys from 2005, the focus was switches and routers, Wi-Fi and WLAN, network management, NAC and UAC, and intrusion detection and prevention, across solution design, implementation, auditing, and training. From 2009, at Juniper Networks through Professional Services for LATAM, the role was new-product advocacy for the strategic partner Telefónica Empresas in Brazil, centered on EX switches and SRX firewalls, with operations training on Junos-SRX delivered at Level 3 and Impsat, now Lumen.",
      "s5Title": "The channel and consulting years, 2010 to 2020",
      "s5Body": "The final decade of this era moved fluidly between roles, all of them building toward the instructor the story arrives at. There were stints as a network and security engineer through resellers and distributors, deepening expertise in enterprise switching and routing, firewalls and next-generation firewalls, SSL-VPN, user access control, WAN acceleration, and internet load-balancing across Juniper and Cisco solutions. Crucially, this period included the pivot toward F5, beginning work with F5 BIG-IP that would define the years to come. Across all of it, technical training was a constant thread, never absent from any role.",
      "closer": "By 2020, the picture was complete: someone who had not just studied these systems but lived inside them for twenty years, on the vendor side and the customer side, in design and in crisis. That is the difference an implementer brings to a classroom. When this person explains why a configuration behaves a certain way, it is because they have seen it behave that way, at three in the morning, with a critical service waiting."
    },
    "era2020present": {
      "years": "2020 – present",
      "title": "The instructor",
      "subtitle": "Full-time technical training, delivered globally, expanding platform by platform.",
      "intro": "In 2020, a career-long thread became the whole cloth. After two decades where teaching accompanied every role, training became the work itself: full-time, official, certified instruction delivered to professionals and teams across the world. What makes this era distinct is not just the focus, but the deliberate, dated expansion across platforms, each one added on top of deep practitioner experience rather than in place of it.",
      "s1Title": "Full-time, by vocation",
      "s1Body": "Since 2020, the work has been delivering official instructor-led training, remotely and in person, in Portuguese and English, to audiences around the globe. The delivery reaches Australia, Singapore, India, Central Europe, the United States, and Brazil. Brazilian and German citizenship, together with travel clearance to the United States and the United Kingdom, make that global reach practical: unrestricted eligibility to work across the European Union and Mercosur, and the freedom to go where the classroom is.",
      "s2Title": "F5, from the start",
      "s2Body": "F5 has been the anchor since the beginning of this era, building on work with BIG-IP that reaches back over a decade. The authorized curriculum covers the full BIG-IP instructor-led catalog: Local Traffic Manager, DNS, Advanced WAF, Access Policy Manager, Advanced Firewall Manager, SSL Orchestrator, BIG-IQ, iRules development, automation, and troubleshooting, ranging from one-day to four-day courses. Alongside the teaching runs a practical complement: managed F5 BIG-IP lab environments, so that hands-on practice always has somewhere real to happen.",
      "s3Title": "The expansion, platform by platform",
      "s3Body": "What distinguishes recent years is a clear, dated progression. Extreme Networks training was added from 2021, covering EXOS switching, SD-WAN, and automation. Fortinet followed from 2024, centered on the FCP FortiGate Administrator track. Netskope joined from 2025, covering Netskope Security Cloud operation, administration, implementation, and integration. Four platforms, each added deliberately, each resting on the same two decades of network and security implementation underneath.",
      "s4Title": "Through Red Education, to the world",
      "s4Body": "The primary vehicle for this global delivery is Red Education, an authorized training center through which official certified courses reach organizations across regions. The role is global technical training instructor, delivering to the kind of international audiences that a São Paulo base, two passports, and a genuine love of travel make possible. The standing relationship turns individual expertise into something organizations worldwide can book and rely on.",
      "closer": "This is where the through-line of the whole history pays off. The curiosity of the early years became the implementation depth of the practitioner years, and that depth is now what every student receives: not a presenter reading slides, but someone who built these systems explaining how they actually work, and why."
    }
  },
  "vendors": {
    "indexTitle": "Vendors",
    "indexLede": "The networking and security companies whose technology shaped this career, from the wire up. These are past relationships; the platforms taught today are listed under Training.",
    "backToVendors": "All vendors",
    "backToAbout": "About",
    "technologies": "Technologies",
    "role": "Role",
    "years": "Years",
    "readNext": "Next vendor",
    "cabletron": {
      "name": "Cabletron and Enterasys",
      "years": "1996 – 2007",
      "tagline": "Where the career began, and the enterprise LAN was learned from the ground up.",
      "intro": "The longest single thread in this history runs through one company and its successor. Cabletron Systems, a leading networking equipment vendor based in Rochester, New Hampshire, was the first employer, starting in 1996. When Cabletron reorganized into four companies in 2000, the line carried forward as Enterasys Networks, and the relationship resumed there from 2005. Together these span the formative decade of enterprise networking expertise.",
      "s1Title": "Cabletron, 1996 to 2000",
      "s1Body": "Over four and a half years, the role moved through the full arc of vendor engineering: field engineering and post-sales support, systems engineering and pre-sales, and, from 1997, certified instruction. The subject was the enterprise LAN and WAN of the era: switches and routers, Wi-Fi and WLAN, network management, NAC and UAC, and stateful-inspection firewalls. This was where the discipline of solution design, implementation, auditing, troubleshooting, and escalation management was first practiced, and where teaching first entered the work.",
      "s2Title": "Enterasys, 2005 to 2007",
      "s2Body": "Returning to the lineage as a services and support manager, the focus was the Secure Routing product line, with Enterasys as the regional focal point for Brazil. The work combined high-level customer support, complex troubleshooting, and escalation management with localized product management. The technical surface had grown to include network management, NAC and UAC, intrusion detection and prevention, and SIEM, across enterprise switching and routing. Enterasys was later acquired by Extreme Networks in 2013, closing a circle that connects this early work to a platform still taught today.",
      "certs": "Cabletron Systems Engineer (CSE), 1999. Enterasys Systems Engineer (ESE), 2000 and 2007. Enterasys Certified Internetworking Engineer (ECIE), 2007.",
      "lineageTitle": "The corporate lineage",
      "lineageDesc": "Cabletron Systems, based in Rochester New Hampshire, split into four companies in 2000: Enterasys, Riverstone, Aprisma, and GNTS. Enterasys was acquired by Extreme Networks in 2013. Riverstone was acquired by Alcatel-Lucent in 2006."
    },
    "juniper": {
      "name": "NetScreen and Juniper",
      "years": "2009 – 2014",
      "tagline": "Enterprise switching and the security gateways that grew from NetScreen into the Juniper SRX line.",
      "intro": "Juniper Networks acquired NetScreen, the firewall company, in 2004, and NetScreen's security technology became the foundation of Juniper's secure-gateway line. Working with both reflects one continuous lineage: the NetScreen SSG firewalls and the SRX gateways that succeeded them. The relationship ran directly through Juniper from 2009, and continued through the reseller channel afterward.",
      "s1Title": "Juniper Networks, 2009 to 2010",
      "s1Body": "Contracted through Juniper Professional Services for Brazil, the role was new-product advocacy for the newly introduced enterprise lines: the SRX-series secure gateways and EX-series switches. The primary engagement was with the strategic partner Telefónica Empresas in Brazil. Beyond pre-sales advocacy, this period delivered real instruction: JUNOS networking-operating-system and SRX secure-gateway operations training for channel partners and customers, including operations training for the Level 3 Communications network operations center staff in Brazil and Argentina.",
      "s2Title": "Through the channel, 2010 to 2014",
      "s2Body": "The Juniper and NetScreen relationship continued through systems integrators and resellers. At CYLK, the work spanned configuration development, proof-of-concept and interoperability testing, and live implementation and troubleshooting across Juniper, NetScreen, and F5. At TDec, Juniper joined a multi-vendor consulting and training practice. The hands-on product range across these years was broad: EX switches, SRX and NetScreen SSG firewalls, SA SSL-VPN, J-series routers, and AX managed Wi-Fi.",
      "certs": "Juniper Networks Sales Specialist, Enterprise Networking (JNSS-EN), 2010. Juniper Networks Sales Associate, Enterprise Networking (JNSA-EN), 2010.",
      "lineageTitle": "The security lineage",
      "lineageDesc": "NetScreen, maker of the SSG firewalls, was acquired by Juniper Networks in 2004 and became the foundation of Juniper's SRX secure-gateway line."
    },
    "riverstone": {
      "name": "Riverstone Networks",
      "years": "2000 – 2002",
      "tagline": "Two years in Santa Clara, at the carrier and metropolitan-network edge.",
      "intro": "The one chapter of this career set entirely outside Brazil. Riverstone Networks, a metropolitan-area-network equipment vendor based in Santa Clara, California, brought a move to the United States on an H1-B1 work visa. Riverstone had an unusual lineage of its own: originally a company called Yago, acquired by Cabletron around 1998, and re-emerged as an independent company through a spin-off in 2001. It was later acquired by Alcatel-Lucent in 2006.",
      "s1Title": "Tier-III support and knowledge management",
      "s1Body": "The role carried two titles across two years: product support engineer and knowledge-management coordinator. As a Tier-III technical-support specialist, the work was third-level escalation, recreating customer scenarios in the lab, regression testing, and bug verification. As knowledge-management coordinator, it was building and organizing the knowledge base the rest of support relied on, alongside product-marketing support and internal training. This was the deepest technical-support work of the career, at the level where the hardest problems escalate.",
      "s2Title": "The metropolitan-network world",
      "s2Body": "The technologies were the backbone of the early-2000s carrier and metro era: Gigabit Ethernet, MPLS, metropolitan-area switching and routing, and wide-area IP routing including BGP. Working at the vendor's third-level support meant seeing how these systems behaved at the edges, under the conditions that only surface in production at scale. It also delivered formal instruction: Riverstone concepts, features, and configuration training, and customer-support issue-identification and escalation-procedure training.",
      "certs": "Riverstone Certified Networking Professional (RCNP), 2001. United States educational-equivalency evaluation recognizing a background equivalent to a bachelor's degree in computer science and a bachelor's degree in business administration, completed in 2001 as part of the H1-B1 visa process.",
      "lineageTitle": "The corporate lineage",
      "lineageDesc": "Riverstone Networks began as a company called Yago, was acquired by Cabletron Systems around 1998, re-emerged as an independent company through a spin-off in 2001, and was acquired by Alcatel-Lucent in 2006."
    },
    "cisco": {
      "name": "Cisco Systems",
      "years": "2003 – 2008",
      "tagline": "Keeping critical national infrastructure running, as the single point of contact for Brazil's federal customers.",
      "intro": "Contracted through Cisco Professional Services in Brazil, this was the career at its most operationally demanding, where the work was less about any single technology and more about keeping critical systems running for customers who could not afford downtime.",
      "s1Title": "High-touch operations, 2003 to 2004",
      "s1Body": "As a high-touch operations manager and single point of contact, the role was post-sales customer-satisfaction management for two of Brazil's largest federal entities: SERPRO, the government's data-processing agency, and ECT-Correios, the national postal service, across Brasília and São Paulo. The technical surface included Catalyst switches and routers, PIX firewalls, and CSS, CSM, and ACE content and load-balancing appliances. The real discipline, though, was escalation management and crisis handling, maintaining high satisfaction for accounts where the stakes were national.",
      "s2Title": "Cisco instruction, 2007 to 2008",
      "s2Body": "The Cisco relationship also produced formal training delivery: IOS and CatOS concepts and operations, and Layer 2 and Layer 3 networking concepts, operations, and troubleshooting, in multi-day courses. This complemented the deep operational experience with the structured instruction that would later become the whole focus of the career.",
      "ironportTitle": "A separate note: IronPort, 2004",
      "ironportBody": "Worth recording accurately, and distinct from the Cisco work: a brief three-month engagement in late 2004 with IronPort Systems, then an independent email-security-appliance startup based in San Bruno, California. The work was channel development and pre-sales technical consulting for its C-Series email-security appliances. This predates Cisco's acquisition of IronPort in 2007 entirely, so it was a separate relationship with an independent company, not Cisco technology, and is noted here only because the company later became part of Cisco.",
      "certs": "Cisco Certified Network Associate (CCNA), 2000 and 2005. Cisco Internetwork Troubleshooting (CIT), 2003."
    },
    "paloalto": {
      "name": "Palo Alto Networks",
      "years": "2013 – 2015",
      "tagline": "Next-generation firewalls, through the reseller channel and the classroom.",
      "intro": "A focused relationship centered on next-generation firewall technology, carried through the reseller and integrator channel. This is a past engagement; Palo Alto is not among the platforms taught today, but the work was real and certified.",
      "s1Title": "Channel consulting and training, 2013 to 2015",
      "s1Body": "At TDec Network Group, Palo Alto joined a multi-vendor consulting and training practice spanning systems engineering, solutions architecture, application enablement, implementation, audits, and troubleshooting. The relationship continued through Cipher Security in 2015 for pre-sales and post-sales work. The technical focus was next-generation firewalls and the Panorama management platform, the core of Palo Alto's enterprise security offering at the time.",
      "s2Title": "PAN-OS instruction",
      "s2Body": "This period included formal training delivery: a PAN-OS 6.0 bootcamp, building the same hands-on, lab-driven instruction that defines the teaching practice today. Combined with the certifications earned in 2014, this established genuine depth in the platform, even as the career's focus later concentrated on other technologies.",
      "certs": "Palo Alto Certified Network Security Engineer (CNSE 5.1), 2014. Palo Alto Networks Accredited Configuration Engineer (ACE), 2014. Palo Alto Networks Accredited Sales Expert (ASE), 2014. Note: these certifications are historical and are not maintained as current."
    }
  },
  "training": {
    "eyebrow": "Training I deliver",
    "title": "Four platforms, taught by someone who has run them.",
    "intro": "Official, certified instructor-led training across {courses} courses on the four platforms at the center of modern networking and security. Every course is delivered by an authorized instructor with decades of hands-on implementation behind the teaching.",
    "courseCount": "{count} courses",
    "since": "since",
    "representativeNote": "This catalog is representative, not exhaustive. Course names, durations, and content reflect current public information and are refined from official datasheets.",
    "allPlatforms": "All platforms",
    "authorizedSince": "Authorized instructor since {year}",
    "workingSince": "Working with {platform} since {year}",
    "tech": {
      "switchesRouters": "enterprise switches and routers",
      "firewalls": "firewalls",
      "webCloudSecurity": "web and cloud security"
    },
    "coursesHeading": "{count} courses",
    "duration": "Duration",
    "delivery": "Delivery",
    "deliveryValue": "Virtual or in person",
    "modules": "Modules",
    "aboutCourse": "About this course",
    "tableOfContents": "Table of contents",
    "agendaPending": "A detailed day-by-day agenda will be added from the official course datasheet.",
    "moreFrom": "More {platform} courses",
    "requestTraining": "Request this training",
    "requestVia": "Delivered through {destination}"
  },
  "teach": {
    "eyebrow": "How I teach",
    "title": "An instructor who built these systems before teaching them.",
    "lede": "Most technical training is delivered by people who learned the material to teach it. This is the opposite: three decades of building, breaking, and fixing real networks and security systems, distilled into training that connects every concept to how it actually behaves in production.",
    "s1Title": "Why this matters in a classroom",
    "s1Body": "There is a difference between explaining how a feature is supposed to work and explaining why it behaves the way it does at three in the morning when something critical is down. The first comes from a manual. The second comes from having been there. Since 1996, the work was implementation: designing networks, standing them up, and being the person called when they broke, for vendors and for some of the largest organizations in Brazil. That depth is what every student receives, not a presenter reading slides, but an engineer who has lived inside these systems explaining how they truly work.",
    "s2Title": "Complex made clear",
    "s2Body": "Deep technical knowledge is necessary but not sufficient. The rarer skill is translating it: taking something genuinely complex, web application firewalls, identity federation, traffic management, SD-WAN, and making it click for someone encountering it for the first time. Students consistently single out the real-world examples and the clear, structured didactics, the ability to put each concept in the context of the work they actually do. Teaching has been a thread through this entire career, present in nearly every role since 1997, and the full-time focus since 2020.",
    "s3Title": "Hands-on, not hand-wavy",
    "s3Body": "Technical skill is built by doing, not by watching. Every course is built around hands-on labs on real systems, reinforced with managed lab environments so that practice always has somewhere real to happen. The format adapts to the audience: virtual instructor-led training delivered globally, in-person when that serves better, in English or Portuguese. The goal of every session is the same, that participants leave able to do the thing, not just describe it.",
    "s4Title": "Recognized, certified, and current",
    "s4Body": "The teaching rests on a foundation of formal recognition. F5 DevCentral MVP for three consecutive years, in 2022, 2023, and 2024. F5 certifications held since 2015, and instructor authorization across four platforms: F5, Extreme Networks, Fortinet, and Netskope. Delivery reaches Australia, Singapore, India, Central Europe, the United States, and Brazil, through Red Education, an authorized training center. The credentials matter, but they are shorthand for the thing underneath: a genuine, current command of the technology.",
    "platformsTitle": "What I teach",
    "platformsBody": "Official, certified instructor-led training across four platforms at the center of modern networking and security. Each links to its full course catalog.",
    "s5Title": "Beyond the classroom",
    "s5Body": "The same depth that makes for good teaching makes for good counsel. Thirty years across application delivery, network security, identity, and infrastructure, on both the vendor and the integrator side, with a consistent record of customer advocacy, is a perspective that travels well beyond a training room, into architecture decisions, technology selection, and the hard problems that do not fit a syllabus. The teaching is the focus; the experience behind it is available to teams that need more than a course.",
    "toolsTitle": "Tools that compute, never guess",
    "toolsBody": "Alongside the training sits a growing set of free, privacy-first network and security tools, deterministic utilities that run entirely in your browser and never send your input anywhere. Subnet and CIDR math, IPv6, certificate and token inspection, and more, the kind of everyday tools a working engineer reaches for. They are built in the same spirit as the teaching: precise, practical, and genuinely useful. Try them, no sign-up, no tracking.",
    "toolsCta": "Explore the tools",
    "historyTitle": "Three decades, one through-line",
    "historyBody": "From building computers as a teenager in 1991, through two decades inside the networking and security industry, to full-time global instruction since 2020. The whole story is worth reading if you want to understand the experience behind the teaching.",
    "historyCta": "Read the full history",
    "ctaTitle": "Let's work together",
    "ctaBody": "Whether you are looking to book official training, build a custom program for your team, or bring in experienced counsel on a hard problem, the door is open.",
    "ctaButton": "Get in touch",
    "coursesButton": "Browse all courses"
  },
  "contact": {
    "title": "Get in touch",
    "lede": "Whether you are looking to book official training, build a custom program for your team, or bring in experienced counsel on a hard problem, I would be glad to hear from you.",
    "formHeading": "Send a message",
    "directHeading": "Or reach out directly",
    "formName": "Your name",
    "formEmail": "Your email",
    "formTopic": "What's this about?",
    "topicTraining": "Official training",
    "topicCustom": "Custom program for a team",
    "topicAdvisory": "Advisory & consulting",
    "topicOther": "Something else",
    "formMessage": "Your message",
    "formSend": "Send message",
    "formSending": "Sending…",
    "formRequired": "Please fill in your name, email, and a message.",
    "successTitle": "Thank you.",
    "successBody": "Your message is on its way. I'll get back to you as soon as I can.",
    "errorBody": "Something went wrong sending that. Please try again, or email directly.",
    "emailLabel": "Email",
    "channels": {
      "linkedin": {
        "label": "LinkedIn",
        "description": "Connect professionally"
      },
      "youtube": {
        "label": "YouTube",
        "description": "Videos and walkthroughs"
      },
      "instagram": {
        "label": "Instagram",
        "description": "Behind the scenes"
      },
      "training": {
        "label": "Official training",
        "description": "Book a course through Red Education"
      }
    },
    "feedbackNote": "Found a bug, a mistake, or an inaccuracy on the site?",
    "feedbackLink": "Share it on the ideas page"
  },
  "certs": {
    "title": "Certifications & credentials",
    "lede": "Three decades of formal credentials across networking and security. The instructor authorizations and certifications below are current; a full record of earned credentials, most now historical, follows for depth.",
    "jumpToHistorical": "Jump to the full record",
    "credlyVerify": "Verify on Credly",
    "current": "Current",
    "historical": "Historical",
    "instructorTitle": "Instructor authorizations",
    "instructorIntro": "Authorized to deliver official, certified training on each of these platforms today.",
    "currentCertsTitle": "Current certifications",
    "recognitionTitle": "Recognition",
    "historicalTitle": "The full record",
    "historicalIntro": "Earned credentials across a career that began in 1996. Most are historical or expired, kept here for the depth they represent.",
    "verify": "Verify",
    "credly": "Credly",
    "certificate": "Certificate",
    "verifyCode": "Code",
    "candidateId": "ID"
  },
  "colophon_page": {
    "eyebrow": "Colophon",
    "title": "How this was built",
    "lede": "Most websites do not explain themselves. This one does, because how it was made is part of what it is: a deliberate experiment in building well, with unusual collaborators, and a record worth keeping.",
    "concordTitle": "CONCORD",
    "concordBody1": "This site was designed and built through a protocol called CONCORD: a structured collaboration between one person and three different AI systems, each in a distinct role. It is not a gimmick. It is a working method, with its own governance, its own decision record, and a single human accountable for every choice that shipped.",
    "concordBody2": "The premise is simple. Different AI models have different strengths, and a hard problem benefits from more than one perspective held in tension. So the work was divided by role, and one person sat at the center, relaying between them, ratifying what was sound, and rejecting what was not.",
    "concordBody3": "CONCORD was not adopted from anywhere. It was designed by Rodolfo Nützmann for this project, out of a practical need: how to draw on several AI systems at once, each genuinely strong at something different, without surrendering the single thread of human accountability that real work requires. The answer was to give each system a defined seat, keep them from negotiating with one another, and route every exchange through one person who held the whole picture. That arrangement has an older name. The AI systems are agents: they act on direction and on someone else's behalf. PRIME is the principal: the party who actually decides, who exercises the judgment, and who carries both the consequences and the name.",
    "concordBody4": "It began informally, as a way of dividing the work, and hardened over the build into a named method: fixed seats, a single overriding rule that nothing ships without PRIME ratifying it, and a written record of why each choice was made. The name states the aim: concord, agreement reached on purpose through a process, not whatever an unsupervised tool happens to produce.",
    "concordPrincipal": "The leverage is the agents'. The accountability is the principal's, and it does not transfer.",
    "concordMechTitle": "The mechanics, in plain terms",
    "mech1Label": "Propose",
    "mech1Gloss": "Each seat puts forward options within its own remit.",
    "mech2Label": "Relay",
    "mech2Gloss": "PRIME carries proposals between seats; they never negotiate directly.",
    "mech3Label": "Ratify",
    "mech3Gloss": "PRIME accepts what is sound and rejects what is not. Nothing ships otherwise.",
    "mech4Label": "Constrain",
    "mech4Gloss": "A standing set of house rules bounds every output, in every seat.",
    "mech5Label": "Record",
    "mech5Gloss": "A written decision log keeps the reasoning behind each choice.",
    "mech6Label": "Remember",
    "mech6Gloss": "Context, the house rules, and that log persist as files, carried from one session to the next, so the method outlives any single conversation.",
    "rolesTitle": "The seats",
    "rolePrime": "PRIME",
    "rolePrimeWho": "Rodolfo Nützmann",
    "rolePrimeBody": "The principal, and the sole ratifier. Every decision, every line that shipped, passed through one human who held the full picture and bore final responsibility. The agents proposed; PRIME disposed.",
    "rolePrimeModel": "Human",
    "roleAnvil": "ANVIL",
    "roleAnvilWho": "Engineering",
    "roleAnvilBody": "The chief engineer seat. Architecture, code, content structure, and the build itself, turned from intention into a working, tested, deployable site.",
    "roleAnvilModel": "Anthropic · Claude Opus 4.8",
    "roleScout": "SCOUT",
    "roleScoutWho": "Strategy and brand",
    "roleScoutBody": "The strategy and positioning seat. The questions of what this is, who it is for, and how it should present itself to the world.",
    "roleScoutModel": "OpenAI · ChatGPT 5.5",
    "rolePrism": "PRISM",
    "rolePrismWho": "Design",
    "rolePrismBody": "The design seat. The visual language, the typography, the colour, and the feel of the thing, shaped into a coherent system.",
    "rolePrismModel": "Google · Gemini 3.1 Pro",
    "seatsModelNote": "AI model versions as of June 2026.",
    "principlesTitle": "How it was made",
    "principlesBody": "A few principles held throughout, and they are visible if you know where to look.",
    "p1Title": "Compute, never guess",
    "p1Body": "The tools on this site calculate answers locally and deterministically. They do not call a server with your input, and they do not approximate. What runs in your browser, stays in your browser.",
    "p2Title": "Open at the core",
    "p2Body": "The deterministic logic each tool runs is the whole of the tool — there is no hidden server step, no account, and no telemetry. Everything runs in your browser.",
    "p3Title": "Documented by construction",
    "p3Body": "Every part of the codebase is commented and documented, not as an afterthought but as a standing rule. The build is meant to be legible, to its maintainer and to anyone who inherits it.",
    "p4Title": "Built to last and to travel",
    "p4Body": "The site is a static export: fast, cacheable, and dependent on nothing at runtime. It is structured for many languages from the ground up, so it can speak to a global audience without being rebuilt.",
    "stackTitle": "The stack",
    "stackBody": "For those who care about such things, the technical foundation, stated plainly.",
    "stackFramework": "Framework",
    "stackFrameworkV": "Next.js 15 and React 19, exported as a fully static site",
    "stackI18n": "Internationalization",
    "stackI18nV": "next-intl, with {count} locales and right-to-left support",
    "stackDesign": "Design system",
    "stackDesignV": "A skinnable, token-based theme engine; the default theme is Obsidian",
    "stackType": "Typography",
    "stackTypeV": "Inter for prose, JetBrains Mono for data and codes",
    "stackEngine": "Tool engine",
    "stackEngineV": "A deterministic compute layer that runs entirely in the browser",
    "stackSearch": "Search",
    "stackSearchV": "Static, client-side full-text search; no search server",
    "vibeTitle": "Is this vibe coding?",
    "vibeBody1": "It is a fair question, and worth answering plainly. Vibe coding is a term the AI researcher Andrej Karpathy coined in early 2025 for a way of building software where you describe what you want to a language model, accept what it writes without reading it closely, and steer by results rather than by the code itself. He framed it as giving in to the vibes and forgetting that the code even exists, and was clear that it suited quick, throwaway projects more than systems people depend on.",
    "vibeBody2": "By that definition, part of this site was built that way, and it is worth owning rather than hiding. The application's surface, the framework wiring, the components, the styling, the plumbing that holds the pages together, was produced quickly with an AI engineer and steered by outcome and by a fixed set of house rules, not typed out by hand line by line. For that layer, where a mistake is visible and easily corrected, speed was the point.",
    "vibeBody3": "The parts that matter most are held to a different standard. Everything that computes your data is verified, not vibed: each tool's core is checked against the published standard it implements, the relevant RFCs and specifications, and its output is confirmed against independent references before it ships. As a widely cited line from the programmer Simon Willison puts it, code you have reviewed, tested, and understood is not vibe coding at all. Karpathy himself now calls the disciplined version agentic engineering: keeping the leverage of AI without conceding the quality of the result. That is the line this project draws. Fast where speed is free, rigorous where it counts, and one human accountable for all of it.",
    "closingTitle": "A note on the method",
    "closingBody": "Building software with AI collaborators is new enough that the honest thing is to be transparent about it. Nothing here was published without a human deciding it should be. The AIs were instruments, capable ones, but instruments. The judgment, the accountability, and the name on the work are human.",
    "backHome": "Back to the tools",
    "changelogLink": "Changelog",
    "standardsTitle": "Standards and frameworks",
    "standardsLede": "Every tool here implements a published specification, not a guess. The decoders and calculators are built against the documents that define their formats, and pinned to the test vectors those documents publish, so each answer is checked against the source of truth rather than against itself.",
    "specsLabel": "The specifications",
    "specsBody": "JSON Web Tokens follow RFC 7519, with signatures and algorithms in RFC 7515 and 7518; PKCE is RFC 7636; Base64 and its siblings are RFC 4648; UUIDs are RFC 9562 (which obsoleted RFC 4122 in 2024 and ships its own test vectors); HMAC is RFC 2104, over the SHA family standardized in FIPS 180-4 and FIPS 202; X.509 certificates are RFC 5280; IPv4 and CIDR notation are RFC 4632; IPv6 addressing and its canonical text form are RFC 4291 and RFC 5952; and the cipher-suite decoder is driven by the official IANA TLS Cipher Suites registry, cross-referenced with the TLS 1.3 and 1.2 specifications (RFC 8446 and 5246), the registry-update rules that set the “Recommended” column (RFC 8447), and the RC4 prohibition (RFC 7465). Where a registry is the authority, its data is vendored directly rather than retyped.",
    "vectorsLabel": "Golden vectors",
    "vectorsBody": "Each tool ships with a set of golden vectors: known inputs paired with known-correct outputs, taken from the relevant RFCs and standards bodies. They run on every build, so a refactor that quietly changes an answer fails the build instead of shipping.",
    "owaspLabel": "OWASP",
    "owaspBody": "The security tools are defined against OWASP's frameworks rather than assembled ad hoc. The cryptographic and TLS tools map onto the Cryptographic Failures and Security Misconfiguration areas of the OWASP Top 10 and the matching checks in the Application Security Verification Standard; the token tooling follows OWASP's guidance for inspecting and validating JWTs. OWASP's prevention cheat sheets also set hard rules for what gets built next: any XML or SAML handling added here is required to be hardened against XXE before it ships.",
    "redblueLabel": "Red and blue",
    "redblueBody": "The same decode-and-explain that lets a red-teamer read a captured token lets a blue-teamer understand what their own stack is emitting. The platform deliberately sits on the analysis side of that line: it identifies, decodes, converts, and explains, and it stops short of forging, injecting, or defeating controls. That boundary is a design decision, not an oversight; these tools exist to teach and to diagnose, not to weaponize.",
    "localLabel": "Local and deterministic",
    "localBody": "Everything runs in the browser. The tool calls a pure function: given the same input it returns the same output, holds no state, and sends nothing to a server. No cookies, no analytics, as the Privacy page sets out in full.",
    "thanksTitle": "Special thanks"
  },
  "support": {
    "title": "Support the project",
    "lede": "These tools are free and built to stay that way. If they save you time, you're welcome to chip in toward their upkeep. Entirely optional, always.",
    "tipHeading": "Leave a tip",
    "tipBlurb": "Every contribution goes directly to supporting the tools and the time that goes into them.",
    "zeroCommission": "0% commission. Links go straight to the provider; this site is never in the payment path.",
    "placeholder": "Support options are being set up and will appear here soon."
  },
  "machineTranslation": {
    "notice": "This page was translated by machine and may contain mistakes.",
    "cta": "Help improve it"
  },
  "contribute": {
    "eyebrow": "Translations",
    "title": "Help improve the translations",
    "lede": "Every language here other than English is a machine-made first draft. If you speak one of them and notice something wrong or clumsy, your corrections are genuinely welcome. Here is how to send them.",
    "howTitle": "How to contribute",
    "howBody": "English is the source of truth, and every other language is translated from it, so mistakes are possible. Each language pack is a single text file of labelled phrases. Download the one you want to improve, change only the text after each label, and leave the labels and anything inside curly braces exactly as they are. Then email the edited file and mention the language. Every submission is reviewed by hand.",
    "downloadHeading": "Language packs",
    "referenceTag": "reference",
    "emailHeading": "Send your contribution",
    "backHome": "Back to tools"
  },
  "admin": {
    "eyebrow": "Admin",
    "title": "Site control",
    "lede": "The control surface for this site's optional features and settings.",
    "previewBanner": "Preview scaffold. On the static site these controls preview the admin surface; live control activates with the service layer. Changes here are not saved.",
    "featuresTitle": "Features",
    "flagRequestTraining": "Request this training",
    "flagRequestTrainingDesc": "The lead-generation CTA on course and platform pages.",
    "flagTipJar": "TipJar",
    "flagTipJarDesc": "Creator-support links on the support page.",
    "flagToolFunding": "Tool funding",
    "flagToolFundingDesc": "Per-tool support interface.",
    "flagToolProvenance": "Tool provenance",
    "flagToolProvenanceDesc": "Per-tool credits and sources panel.",
    "routingTitle": "Lead routing",
    "routingDefaultLabel": "Global default",
    "routingNoOverrides": "No per-platform or per-course overrides configured.",
    "contactTitle": "Contact",
    "contactEmailLabel": "Email",
    "contactFormLabel": "Form submission",
    "formMailto": "Mailto fallback (no backend)",
    "formEndpoint": "Posting to endpoint",
    "tipJarTitle": "TipJar providers",
    "tipConfigured": "Configured",
    "tipNotConfigured": "Not configured",
    "on": "On",
    "off": "Off",
    "accessTitle": "Access control",
    "accessNote": "Only these federated identities may hold admin access. Enforced server-side by the service layer; the static site does not authenticate.",
    "accessFederatedOnly": "Federated sign-in only. No local account fallback.",
    "accessRoleLabel": "Role",
    "accessPermsLabel": "Owner permissions"
  },
  "api": {
    "title": "API",
    "lede": "The tools on this site run in your browser and keep your data on your device. For automation, such as scripts, pipelines, and integrations, the same deterministic computations are available as a small HTTP API. It is the programmatic counterpart to the browser tools, not a replacement for them.",
    "privacyTitle": "What this means for your data",
    "privacyBody": "The API receives only the input you send it, computes a result, and returns it. It is stateless and logs no query values or request bodies. If you need guaranteed zero data egress, use the browser tools, or run the open engine yourself.",
    "engineTitle": "The same engine as the browser",
    "engineBody": "Every endpoint runs the same pure function the in-browser tool runs, so the API and the browser return byte-identical results.",
    "specTitle": "The specification",
    "specBody": "The full contract is published as OpenAPI 3.1. Download it, point your own tooling at it, or read the reference below.",
    "downloadSpec": "Download openapi.yaml",
    "baseUrlLabel": "Base URL",
    "authLabel": "Authentication",
    "authValue": "None. This is a public, read-only API.",
    "referenceTitle": "Reference",
    "loading": "Loading the specification.",
    "loadError": "The specification could not be loaded.",
    "tryItTitle": "Try it",
    "tryItSend": "Send",
    "tryItRunning": "Running.",
    "tryItHint": "Runs against the live API on this origin. Your input is sent to the endpoint.",
    "paramsTitle": "Parameters",
    "responsesTitle": "Responses",
    "schemasTitle": "Schemas",
    "exampleLabel": "Example",
    "requiredLabel": "required",
    "fieldLabel": "Field",
    "typeLabel": "Type",
    "descriptionLabel": "Description",
    "viewReference": "Reference",
    "viewSwagger": "Swagger UI",
    "swaggerLoadError": "Swagger UI could not be loaded."
  },
  "contributeIdeas": {
    "eyebrow": "Ideas welcome",
    "title": "Share an idea",
    "lede": "This toolbox is built to grow, and the clearest signal for where it should go comes from the people using it. Found a bug, a mistake, or an inaccuracy? Want a tool that isn't here yet? See a better way to handle something, or a result you'd word differently? Send it, every kind of input is welcome.",
    "sendTitle": "What you can send",
    "sendBody": "Bugs, mistakes, and inaccuracies of any kind: a tool that misbehaves, a wrong result, an error in a Learn article, or anything that simply looks off. Feature requests for tools that already exist. Ideas for new tools the toolbox should have. Corrections and additions to the Learn articles, like a clearer explanation, a better source, or a topic that is missing. Or simply a different angle on a problem. Rough is fine; a sentence is enough to start a conversation.",
    "toolTitle": "If you're proposing a new tool",
    "toolBody": "Tools here are small, self-describing modules: a manifest that says what the tool is and where its correctness comes from, one pure function that does the work, and a set of golden vectors, the fixed input-and-output pairs that prove it. A good fit computes locally and deterministically (the same input always yields the same output, with no clock, network, or randomness in the result), keeps anything sensitive on the device, and pins its correctness to a cited source such as an RFC rather than to opinion. You don't need to build any of that to propose one: just describe what it should compute, an example, and the source it rests on.",
    "fitRule": "One simple test decides it. Every tool here runs entirely in your browser and sends nothing anywhere, so a new tool has to be something a computer can work out just from what you type, by following a fixed, published rule. If it needs to go online, look something up live, sign you in, or remember you, it does not belong here.",
    "fitYes": "Fits:",
    "fitYesBody": "decoding or explaining something you paste in (a token, a certificate, a config, command output), converting between formats, calculating from a standard or formula, or generating from a rule, like a UUID, a hash, or a command line.",
    "fitNo": "Does not fit:",
    "fitNoBody": "anything that has to go online or check something live (testing a real website, querying a live DNS server, scanning an address), anything that needs an account, a login, or saved data, or anything whose answer is not fixed by a published standard.",
    "fitUnsure": "Not sure which side your idea falls on? Send it anyway and say what it should do. I will tell you honestly whether it fits, and why.",
    "emailTitle": "How to reach me",
    "emailBody": "Email is the channel. Tell me what you found or what you'd like, with enough detail to act on: an example, a link, the exact wording, whatever fits. If it makes the toolbox better, it gets built.",
    "emailLabel": "Email",
    "backToTools": "Back to the toolbox"
  },
  "license_page": {
    "eyebrow": "Terms",
    "title": "License",
    "lede": "ronutz.com is a proprietary work, all rights reserved. These terms cover the website and its content. The site is built on open-source software, which is used and redistributed under its own license terms — credited below.",
    "closedHeading": "Closed source: this website",
    "closedBody": "The website itself is closed source. Its design, interface, written content (including every Learn article), branding, and the particular way these tools are assembled and presented here are proprietary, all rights reserved. No permission is granted to copy, reproduce, modify, redistribute, or create derivative works from the site or its content without prior written consent.",
    "contact": "Questions about licensing? <a>Get in touch.</a>",
    "backHome": "Back to the tools",
    "thirdHeading": "Open-source components",
    "thirdBody": "This site stands on open-source work. The site itself is built with Next.js and React and shipped as a static export; internationalization uses next-intl; the Learn content is rendered with next-mdx-remote, gray-matter, remark-gfm, and js-yaml; and search is powered by Pagefind. These are provided under the MIT License, except next-mdx-remote (Mozilla Public License 2.0). The API reference embeds Swagger UI, under the Apache License 2.0. Each component stays under its own license, and the full notices ship alongside the source."
  },
  "languageStatus": {
    "title": "Translation status",
    "reviewed": "Human-reviewed",
    "complete": "Machine, complete",
    "partial": "Machine, in progress",
    "explainTitle": "How translations are marked",
    "explainBody": "English and Brazilian Portuguese are written and reviewed by a person. Most other languages are machine-translated and flagged by how far along they are: amber once a language covers the whole site, yellow while newer content is still in English and catching up. Languages marked red have no translation yet and are shown in English for now. Machine-translated pages also carry a short notice, and you are welcome to help improve any of them.",
    "stub": "Not translated yet"
  },
  "changelog": {
    "eyebrow": "Changelog",
    "title": "What is new",
    "lede": "A running record of new tools, new Learn articles, and significant changes to this site. There are {count} tools live today.",
    "kindLaunch": "Launch",
    "kindTool": "New tool",
    "kindFeature": "Feature",
    "kindI18n": "Localization",
    "kindContent": "Content",
    "kindInfra": "Infrastructure"
  }
}
