@redaktyn/cli 1.5.6 → 1.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,7 +45,7 @@ node redaktyn-fingerprint.mjs
45
45
  The wizard will guide you through:
46
46
  1. Entering your Org ID (from Dashboard → Settings)
47
47
  2. Entering your org passphrase (masked input)
48
- On a brand-new workspace that has no passphrase yet, what you type becomes it: it must meet the extension's rules (12+ characters, mixed case, a digit and a symbol, not built on a common word), is asked twice, and is recorded with the server once (an `import` dry run does not record it).
48
+ On a brand-new workspace that has no passphrase yet, one is generated for you, shown once, and recorded with the server once after you type `saved`. A passphrase you type yourself is refused for a new workspace, `REDAKTYN_PASSPHRASE` included (set it to the generated one for later runs). An `import` dry run records nothing and uses a throwaway passphrase. A workspace that already has a passphrase is unchanged: you type it.
49
49
  3. Adding one or more secrets (label + value, both masked)
50
50
  4. Showing you the exact crypto steps for transparency
51
51
  5. Printing copy-ready JSON to paste into the dashboard
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redaktyn/cli",
3
- "version": "1.5.6",
3
+ "version": "1.5.8",
4
4
  "description": "Redaktyn CLI: bulk-enrol secrets from a .env or any vault (--project aware), local fingerprints, git/directory digest scans. Digests are computed on your machine; secret values never leave it.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
- import{readFileSync as me,realpathSync as ye}from"node:fs";import{basename as W}from"node:path";import*as $e from"node:readline";import{pathToFileURL as we}from"node:url";import{canonicalize as ke,computeHmac as ve,deriveKey as be,deriveProjectKey as Se,enrollPayload as Re}from"./redaktyn-fingerprint.mjs";import{freshAdminSession as Ne,freshSession as je,loadAdminSession as U,loadSession as Ae,resolveServerUrl as Ee}from"./redaktyn-session.mjs";import{askWorkspacePassphrase as xe}from"./redaktyn-passphrase.mjs";import{banner as Te,bar as Oe,box as B,g as C,humanBytes as z,k as g,rich as R,reveal as Le,rows as K,say as w,step as G}from"./redaktyn-ui.mjs";import{createRequire as Ie}from"node:module";const _e=Ie(import.meta.url)("./package.json").version,x=process.argv.includes("--no-color")||!!process.env.NO_COLOR,s={reset:x?"":"\x1B[0m",bold:x?"":"\x1B[1m",dim:x?"":"\x1B[2m",red:x?"":"\x1B[31m",green:x?"":"\x1B[32m",yellow:x?"":"\x1B[33m",blue:x?"":"\x1B[34m",cyan:x?"":"\x1B[36m",gray:x?"":"\x1B[90m"};class m extends Error{}const V=15e5,Z=5e4,Pe=1e4,D=5*1024*1024,Ce=256,De=65536,He=/^v1\.[0-9a-f]{12}$/,X=e=>typeof e.scanPrefilter=="string"&&He.test(e.scanPrefilter);function Q(e,t=!1){const o=[new Map,new Map,new Map],r=(n,i,h)=>{if(!(i>0))return;const d=o[n].get(i);o[n].set(i,d?{windowLen:i,prefiltered:d.prefiltered&&h,entries:d.entries+1}:{windowLen:i,prefiltered:h,entries:1})};for(const n of e){const i=t||X(n);n.hmacHex&&r(0,n.length,i),typeof n.hmacHexStripped=="string"&&r(1,n.lengthStripped,i),typeof n.hmacHexLower=="string"&&r(2,n.lengthLower,i)}return o.flatMap(n=>[...n.values()])}function ee(e,t){let o=0;for(const r of t){const n=Math.max(0,e-r.windowLen+1);o+=r.prefiltered?Math.ceil(n/Ce)+Math.ceil(n*r.entries/De):n}return o}function te(e){if(e.length===0)return 1/0;if(ee(D,e)<=V)return D;let t=0,o=D;for(;t<o;){const r=Math.ceil((t+o)/2);ee(r,e)<=V?t=r:o=r-1}return t}function Me(e){const t=Q(e),o=te(t);return{windowLengths:t.length,ceiling:o,legacySecrets:e.filter(r=>r.hmacHex&&!X(r)).length,ceilingIfReenrolled:te(Q(e,!0)),atCharacterCap:o===D}}function We(e){return e.length===0||e.some(t=>t&&Object.prototype.hasOwnProperty.call(t,"scanPrefilter"))}function Ke(e){const t=e.data&&Array.isArray(e.data.unknownFields)?e.data.unknownFields:null;return e.status===400&&e.data?.code==="UNKNOWN_FIELD"&&t!==null&&t.length===1&&t[0]==="scanPrefilter"}function Ye(e){const t={help:!1,env:null,jsonFile:null,yaml:null,stdin:!1,source:null,apply:!1,yes:!1,minLength:null,allowWeak:!1,only:[],exclude:[],server:null,orgId:null,project:null,reportJson:!1,showRequest:!1,noColor:!1},o=(r,n)=>{const i=e[r];if(i===void 0||i.startsWith("--"))throw new m(`${n} needs a value`);return i};for(let r=2;r<e.length;r++){const n=e[r];if(n==="--help"||n==="-h")t.help=!0;else if(n==="--env")t.env=o(++r,"--env");else if(n==="--json")t.jsonFile=o(++r,"--json");else if(n==="--yaml")t.yaml=o(++r,"--yaml");else if(n==="--stdin")t.stdin=!0;else if(n==="--source")t.source=o(++r,"--source");else if(n==="--apply")t.apply=!0;else if(n==="--yes"||n==="-y")t.yes=!0;else if(n==="--min-length")t.minLength=Number(o(++r,"--min-length"));else if(n==="--allow-weak")t.allowWeak=!0;else if(n==="--only")t.only.push(o(++r,"--only"));else if(n==="--exclude")t.exclude.push(o(++r,"--exclude"));else if(n==="--server")t.server=o(++r,"--server");else if(n==="--org-id")t.orgId=o(++r,"--org-id");else if(n==="--project")t.project=o(++r,"--project");else if(n==="--report-json")t.reportJson=!0;else if(n==="--show-request")t.showRequest=!0;else if(n==="--no-color")t.noColor=!0;else throw new m(`Unknown flag: ${n}`)}if(t.minLength!==null&&(!Number.isInteger(t.minLength)||t.minLength<1))throw new m("--min-length must be a positive integer");return t}const Je=/^[A-Za-z_][A-Za-z0-9_.-]*$/;function Fe(e){const t=e.replace(/\r\n/g,`
2
+ import{readFileSync as me,realpathSync as ye}from"node:fs";import{basename as K}from"node:path";import*as $e from"node:readline";import{pathToFileURL as we}from"node:url";import{canonicalize as ke,computeHmac as ve,deriveKey as be,deriveProjectKey as Se,enrollPayload as je}from"./redaktyn-fingerprint.mjs";import{freshAdminSession as Re,freshSession as Ae,loadAdminSession as U,loadSession as Ee,resolveServerUrl as Ne}from"./redaktyn-session.mjs";import{askWorkspacePassphrase as xe}from"./redaktyn-passphrase.mjs";import{banner as Te,bar as Oe,box as B,g as C,humanBytes as z,k as g,rich as j,reveal as Ie,rows as J,say as w,step as G}from"./redaktyn-ui.mjs";import{createRequire as Le}from"node:module";const _e=Le(import.meta.url)("./package.json").version,x=process.argv.includes("--no-color")||!!process.env.NO_COLOR,s={reset:x?"":"\x1B[0m",bold:x?"":"\x1B[1m",dim:x?"":"\x1B[2m",red:x?"":"\x1B[31m",green:x?"":"\x1B[32m",yellow:x?"":"\x1B[33m",blue:x?"":"\x1B[34m",cyan:x?"":"\x1B[36m",gray:x?"":"\x1B[90m"};class m extends Error{}const V=15e5,Z=5e4,Pe=1e4,D=5*1024*1024,Ce=256,De=65536,He=/^v1\.[0-9a-f]{12}$/,X=e=>typeof e.scanPrefilter=="string"&&He.test(e.scanPrefilter);function Q(e,t=!1){const o=[new Map,new Map,new Map],r=(n,i,h)=>{if(!(i>0))return;const a=o[n].get(i);o[n].set(i,a?{windowLen:i,prefiltered:a.prefiltered&&h,entries:a.entries+1}:{windowLen:i,prefiltered:h,entries:1})};for(const n of e){const i=t||X(n);n.hmacHex&&r(0,n.length,i),typeof n.hmacHexStripped=="string"&&r(1,n.lengthStripped,i),typeof n.hmacHexLower=="string"&&r(2,n.lengthLower,i)}return o.flatMap(n=>[...n.values()])}function ee(e,t){let o=0;for(const r of t){const n=Math.max(0,e-r.windowLen+1);o+=r.prefiltered?Math.ceil(n/Ce)+Math.ceil(n*r.entries/De):n}return o}function te(e){if(e.length===0)return 1/0;if(ee(D,e)<=V)return D;let t=0,o=D;for(;t<o;){const r=Math.ceil((t+o)/2);ee(r,e)<=V?t=r:o=r-1}return t}function Me(e){const t=Q(e),o=te(t);return{windowLengths:t.length,ceiling:o,legacySecrets:e.filter(r=>r.hmacHex&&!X(r)).length,ceilingIfReenrolled:te(Q(e,!0)),atCharacterCap:o===D}}function We(e){return e.length===0||e.some(t=>t&&Object.prototype.hasOwnProperty.call(t,"scanPrefilter"))}function Ke(e){const t=e.data&&Array.isArray(e.data.unknownFields)?e.data.unknownFields:null;return e.status===400&&e.data?.code==="UNKNOWN_FIELD"&&t!==null&&t.length===1&&t[0]==="scanPrefilter"}function Je(e){const t={help:!1,env:null,jsonFile:null,yaml:null,stdin:!1,source:null,apply:!1,yes:!1,minLength:null,allowWeak:!1,only:[],exclude:[],server:null,orgId:null,project:null,reportJson:!1,showRequest:!1,noColor:!1},o=(r,n)=>{const i=e[r];if(i===void 0||i.startsWith("--"))throw new m(`${n} needs a value`);return i};for(let r=2;r<e.length;r++){const n=e[r];if(n==="--help"||n==="-h")t.help=!0;else if(n==="--env")t.env=o(++r,"--env");else if(n==="--json")t.jsonFile=o(++r,"--json");else if(n==="--yaml")t.yaml=o(++r,"--yaml");else if(n==="--stdin")t.stdin=!0;else if(n==="--source")t.source=o(++r,"--source");else if(n==="--apply")t.apply=!0;else if(n==="--yes"||n==="-y")t.yes=!0;else if(n==="--min-length")t.minLength=Number(o(++r,"--min-length"));else if(n==="--allow-weak")t.allowWeak=!0;else if(n==="--only")t.only.push(o(++r,"--only"));else if(n==="--exclude")t.exclude.push(o(++r,"--exclude"));else if(n==="--server")t.server=o(++r,"--server");else if(n==="--org-id")t.orgId=o(++r,"--org-id");else if(n==="--project")t.project=o(++r,"--project");else if(n==="--report-json")t.reportJson=!0;else if(n==="--show-request")t.showRequest=!0;else if(n==="--no-color")t.noColor=!0;else throw new m(`Unknown flag: ${n}`)}if(t.minLength!==null&&(!Number.isInteger(t.minLength)||t.minLength<1))throw new m("--min-length must be a positive integer");return t}const Ye=/^[A-Za-z_][A-Za-z0-9_.-]*$/;function Fe(e){const t=e.replace(/\r\n/g,`
3
3
  `).replace(/\r/g,`
4
4
  `),o=[],r=[];let n=0,i=1;const h=()=>{const c=t.indexOf(`
5
- `,n);n=c===-1?t.length:c+1},d=(c,p)=>{let a=0;for(let l=c;l<p;l++)t[l]===`
6
- `&&a++;return a};for(;n<t.length;){const c=t[n];if(c===`
7
- `){i++,n++;continue}if(c===" "||c===" "){n++;continue}if(c==="#"){h(),i++;continue}const p=i;let a=n;for(;a<t.length&&t[a]!=="="&&t[a]!==`
8
- `;)a++;if(a>=t.length||t[a]===`
9
- `){r.push({line:p,message:"no '=' on this line \u2014 skipped"}),n=a+1,i++;continue}let l=t.slice(n,a).trim();for(/^export\s/.test(l)&&(l=l.replace(/^export\s+/,"").trim()),n=a+1;n<t.length&&(t[n]===" "||t[n]===" ");)n++;let y="",u=!0;const $=t[n];if($==='"'||$==="'"){const S=++n,k=t.indexOf(`
10
- `,n);let v=!1;for(;n<t.length;){const b=t[n];if(b==="\\"&&$==='"'&&n+1<t.length){const A=t[n+1];y+=A==="n"?`
11
- `:A==="t"?" ":A==="r"?"\r":A,n+=2;continue}if(b===$){n++,v=!0;break}y+=b,n++}v?(i+=d(S,n),h(),i++):(r.push({line:p,message:"unterminated quote \u2014 skipped this entry"}),u=!1,n=k===-1?t.length:k+1,i++)}else{const S=t.indexOf(`
12
- `,n),k=S===-1?t.length:S;let v=t.slice(n,k);const b=v.search(/\s#/);b!==-1&&(v=v.slice(0,b)),y=v.trim(),n=k===t.length?k:k+1,i++}if(u){if(!Je.test(l)){r.push({line:p,message:`unusable key name ${JSON.stringify(l)} \u2014 skipped`});continue}o.push({key:l,value:y,line:p})}}return{entries:o,problems:r}}const qe=new Set(["data","metadata","lease_id","lease_duration","lease_renewable","renewable","request_id","warnings","auth","wrap_info","mount_type"]),I=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function ne(e){if(!I(e))throw new m("Expected a JSON object of secrets, got "+re(e));if(typeof e.SecretString=="string"){let r;try{r=JSON.parse(e.SecretString)}catch{throw new m("SecretString is not JSON. For a single-value secret pass it to redaktyn-fingerprint instead.")}return ne(r)}if(Array.isArray(e.fields)){const r={};for(const n of e.fields){if(!I(n))continue;const i=n.label??n.id;typeof i!="string"||typeof n.value!="string"||(r[i]=n.value)}return{shape:"1password-item",doc:r}}const t=Object.keys(e);if(t.length>0&&t.every(r=>qe.has(r))&&I(e.data)){const r=e.data;return I(r.data)&&"metadata"in r?{shape:"vault-kv2",doc:r.data}:{shape:"vault-kv1",doc:r}}return{shape:"flat",doc:e}}function re(e){return e===null?"null":Array.isArray(e)?"an array":typeof e}function Ue(e){const t=[],o=[];for(const[r,n]of Object.entries(e)){if(typeof n=="string"){t.push({key:r,value:n});continue}if(typeof n=="number"||typeof n=="boolean"){t.push({key:r,value:String(n)});continue}if(I(n)){const i=["value","raw","computed","computedValue"].find(h=>typeof n[h]=="string");if(i){t.push({key:r,value:n[i]});continue}o.push({key:r,message:"nested object with no value/raw/computed field \u2014 skipped"});continue}o.push({key:r,message:`${re(n)} is not a secret value \u2014 skipped`})}return{entries:t,problems:o}}function oe(e){let t;try{t=JSON.parse(e)}catch(h){throw new m(`Input is not valid JSON: ${h.message}`)}const{shape:o,doc:r}=ne(t),{entries:n,problems:i}=Ue(r);return{entries:n,problems:i,shape:o}}function Be(e){const t=[],o=[];return e.replace(/\r\n/g,`
5
+ `,n);n=c===-1?t.length:c+1},a=(c,p)=>{let l=0;for(let d=c;d<p;d++)t[d]===`
6
+ `&&l++;return l};for(;n<t.length;){const c=t[n];if(c===`
7
+ `){i++,n++;continue}if(c===" "||c===" "){n++;continue}if(c==="#"){h(),i++;continue}const p=i;let l=n;for(;l<t.length&&t[l]!=="="&&t[l]!==`
8
+ `;)l++;if(l>=t.length||t[l]===`
9
+ `){r.push({line:p,message:"no '=' on this line \u2014 skipped"}),n=l+1,i++;continue}let d=t.slice(n,l).trim();for(/^export\s/.test(d)&&(d=d.replace(/^export\s+/,"").trim()),n=l+1;n<t.length&&(t[n]===" "||t[n]===" ");)n++;let y="",u=!0;const $=t[n];if($==='"'||$==="'"){const S=++n,k=t.indexOf(`
10
+ `,n);let b=!1;for(;n<t.length;){const v=t[n];if(v==="\\"&&$==='"'&&n+1<t.length){const E=t[n+1];y+=E==="n"?`
11
+ `:E==="t"?" ":E==="r"?"\r":E,n+=2;continue}if(v===$){n++,b=!0;break}y+=v,n++}b?(i+=a(S,n),h(),i++):(r.push({line:p,message:"unterminated quote \u2014 skipped this entry"}),u=!1,n=k===-1?t.length:k+1,i++)}else{const S=t.indexOf(`
12
+ `,n),k=S===-1?t.length:S;let b=t.slice(n,k);const v=b.search(/\s#/);v!==-1&&(b=b.slice(0,v)),y=b.trim(),n=k===t.length?k:k+1,i++}if(u){if(!Ye.test(d)){r.push({line:p,message:`unusable key name ${JSON.stringify(d)} \u2014 skipped`});continue}o.push({key:d,value:y,line:p})}}return{entries:o,problems:r}}const qe=new Set(["data","metadata","lease_id","lease_duration","lease_renewable","renewable","request_id","warnings","auth","wrap_info","mount_type"]),L=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function ne(e){if(!L(e))throw new m("Expected a JSON object of secrets, got "+re(e));if(typeof e.SecretString=="string"){let r;try{r=JSON.parse(e.SecretString)}catch{throw new m("SecretString is not JSON. For a single-value secret pass it to redaktyn-fingerprint instead.")}return ne(r)}if(Array.isArray(e.fields)){const r={};for(const n of e.fields){if(!L(n))continue;const i=n.label??n.id;typeof i!="string"||typeof n.value!="string"||(r[i]=n.value)}return{shape:"1password-item",doc:r}}const t=Object.keys(e);if(t.length>0&&t.every(r=>qe.has(r))&&L(e.data)){const r=e.data;return L(r.data)&&"metadata"in r?{shape:"vault-kv2",doc:r.data}:{shape:"vault-kv1",doc:r}}return{shape:"flat",doc:e}}function re(e){return e===null?"null":Array.isArray(e)?"an array":typeof e}function Ue(e){const t=[],o=[];for(const[r,n]of Object.entries(e)){if(typeof n=="string"){t.push({key:r,value:n});continue}if(typeof n=="number"||typeof n=="boolean"){t.push({key:r,value:String(n)});continue}if(L(n)){const i=["value","raw","computed","computedValue"].find(h=>typeof n[h]=="string");if(i){t.push({key:r,value:n[i]});continue}o.push({key:r,message:"nested object with no value/raw/computed field \u2014 skipped"});continue}o.push({key:r,message:`${re(n)} is not a secret value \u2014 skipped`})}return{entries:t,problems:o}}function oe(e){let t;try{t=JSON.parse(e)}catch(h){throw new m(`Input is not valid JSON: ${h.message}`)}const{shape:o,doc:r}=ne(t),{entries:n,problems:i}=Ue(r);return{entries:n,problems:i,shape:o}}function Be(e){const t=[],o=[];return e.replace(/\r\n/g,`
13
13
  `).replace(/\r/g,`
14
14
  `).split(`
15
- `).forEach((n,i)=>{const h=i+1;if(n.trim()===""||n.trim().startsWith("#")||n.trim()==="---"||n.trim()==="...")return;if(/^\s/.test(n))throw new m(`${h}: this YAML is indented, so it is not flat key/value. Refusing rather than guessing \u2014 convert it to JSON and use --json.`);if(/^-\s/.test(n.trim())||n.trim()==="-")throw new m(`${h}: YAML lists are not supported. Use --json.`);if(/^[|>]/.test(n.trim()))throw new m(`${h}: YAML block scalars are not supported. Use --json.`);const d=/^([A-Za-z_][A-Za-z0-9_.-]*)\s*:\s?(.*)$/.exec(n);if(!d){o.push({line:h,message:"not a `key: value` line \u2014 skipped"});return}const c=d[1];let p=d[2]??"";if(p.trim()===""||p.trim()==="|"||p.trim()===">")throw new m(`${h}: "${c}" has no inline value, which in YAML means a nested block or null. Refusing rather than registering an empty fingerprint.`);const a=p.trim();if(a.startsWith('"')&&a.endsWith('"')&&a.length>1||a.startsWith("'")&&a.endsWith("'")&&a.length>1)p=a.slice(1,-1),a[0]==='"'&&(p=p.replace(/\\n/g,`
16
- `).replace(/\\t/g," ").replace(/\\(.)/g,"$1"));else{const l=a.search(/\s#/);p=(l===-1?a:a.slice(0,l)).trim()}t.push({key:c,value:p,line:h})}),{entries:t,problems:o}}const Y=12,ze=new Set(["changeme","change-me","change_me","replaceme","replace-me","your-secret-here","your_secret_here","yoursecrethere","development","production","staging","localhost","password","passw0rd","secret","topsecret","undefined","none","null","n/a","todo","tbd","example","test","dummy","placeholder"]);function se(e){if(e.length===0)return 0;const t=new Map;for(const r of e)t.set(r,(t.get(r)??0)+1);let o=0;for(const r of t.values()){const n=r/e.length;o-=n*Math.log2(n)}return o}function Ge(e){if(!/:\/\//.test(e))return null;let t;try{t=new URL(e)}catch{return null}return t.password?{ok:!0}:[...t.pathname.split("/"),...t.searchParams.values(),t.hash.replace(/^#/,"")].filter(Boolean).some(r=>r.length>=16&&se(r)>=2.5)?{ok:!0}:{ok:!1,reason:"URL with no embedded credential or token"}}function Ve(e,{minLength:t=Y}={}){if(e.length===0)return{ok:!1,reason:"empty value"};if(e.length<t)return{ok:!1,reason:`only ${e.length} chars (minimum ${t})`};if(/^\d+$/.test(e))return{ok:!1,reason:"all digits \u2014 port, id or timestamp"};if(/^(true|false|yes|no|on|off|null|nil|none|undefined|enabled|disabled)$/i.test(e))return{ok:!1,reason:"boolean or empty-ish flag"};if(/^v?\d+(\.\d+){1,3}([-+][0-9A-Za-z.-]+)?$/.test(e))return{ok:!1,reason:"version number"};if(ze.has(e.toLowerCase()))return{ok:!1,reason:"placeholder or environment name"};if(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(e))return{ok:!1,reason:"email address"};if(/^(\/[^\s]*|\.{1,2}\/[^\s]*|~\/[^\s]*|[A-Za-z]:[\\/][^\s]*)$/.test(e))return{ok:!1,reason:"filesystem path"};const o=Ge(e);if(o&&!o.ok)return{ok:!1,reason:o.reason};if(!o){const r=new Set(e).size;if(r<5)return{ok:!1,reason:`only ${r} distinct characters`};if(se(e)<2)return{ok:!1,reason:"very low character diversity"}}return{ok:!0}}async function Ze(){if(process.stdin.isTTY)throw new m("--stdin was passed but nothing is piped in.");const e=[];for await(const t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf8")}function J(e,t){try{return me(e,"utf8")}catch(o){throw new m(`${t} ${e}: ${o.code==="ENOENT"?"no such file":o.message}`)}}function O(e){return`import:${e}`}function Xe(e){return String(e).replace(/^[./]+/,"").replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60)||"import"}function ie(e,t){return t.some(o=>o.includes("*")?new RegExp("^"+o.split("*").map(Qe).join(".*")+"$","i").test(e):e.toLowerCase()===o.toLowerCase())}const Qe=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function et({candidates:e,existing:t,source:o}){const r=O(o),n=new Map;for(const l of t)l.hmacHex&&n.set(l.hmacHex,l);const i=t.filter(l=>Array.isArray(l.tags)&&l.tags.includes(r)),h=new Map(i.map(l=>[l.label,l])),d=new Map;for(const l of t)i.includes(l)||d.has(l.label)||d.set(l.label,l);const c=[],p=new Set;for(const l of e){const{key:y,digests:u}=l;p.add(y);const $=h.get(y);if($){if($.hmacHex===u.digest&&tt($,u))c.push({key:y,action:"skip",reason:"already registered and unchanged",id:$.id,length:u.length});else{const v=n.get(u.digest);if(v&&v.id!==$.id)c.push({key:y,action:"conflict",reason:`new value is already registered as "${v.label}"`,id:$.id,length:u.length});else{const b=$.hmacHex===u.digest?"value unchanged; adding missing variants":"value changed";c.push({key:y,action:"rotate",reason:b,id:$.id,length:u.length})}}continue}const S=n.get(u.digest);if(S){c.push({key:y,action:"skip",reason:`already registered as "${S.label}"`,id:S.id,length:u.length});continue}const k=d.get(y);if(k){c.push({key:y,action:"conflict",reason:"a secret with this label exists outside this import source",id:k.id,length:u.length});continue}c.push({key:y,action:"create",reason:"new",length:u.length})}const a=i.filter(l=>!p.has(l.label)).map(l=>({label:l.label,id:l.id,status:l.status}));return{plan:c,missing:a}}function tt(e,t){return e.hmacHexStripped===t.hmacHexStripped&&e.hmacHexLower===t.hmacHexLower&&e.scanPrefilter===t.scanPrefilter}const ae=e=>e.replace(/\/+$/,"");async function F(e,t,o,r,n){let i;try{i=await fetch(`${ae(e)}${r}`,{method:o,headers:{Authorization:`Bearer ${t}`,...n?{"Content-Type":"application/json"}:{}},...n?{body:JSON.stringify(n)}:{}})}catch(c){throw new m(`Cannot reach ${ae(e)}: ${c.message}`)}const h=await i.text();let d=null;if(h)try{d=JSON.parse(h)}catch{d=null}return{status:i.status,ok:i.ok,data:d,text:h}}async function nt(e,t,o){const r=await F(e,t,"GET","/api/projects");if(!r.ok||!Array.isArray(r.data))throw new m(`GET /api/projects failed: ${r.status} ${String(r.text).slice(0,200)}`);const n=o.trim().toLowerCase(),i=r.data.filter(d=>d.id===o.trim()),h=i.length?i:r.data.filter(d=>String(d.name).toLowerCase()===n);if(h.length===0)throw new m(`No project named or numbered "${o}". Known: ${r.data.map(d=>d.name).join(", ")||"none"}.`);if(h.length>1)throw new m(`"${o}" matches ${h.length} projects. Pass the project id instead.`);if(h[0].status==="CLOSED")throw new m(`Project "${h[0].name}" is closed. Reopen it before enrolling into it.`);return h[0]}async function rt(e,t,o=!1){const r=await F(e,t,"GET","/api/secrets");if(o&&(r.status===401||r.status===403))throw new m("This machine's Redaktyn session is no longer valid: the device was removed or its session ended. Ask your admin for a new invite link and run `redaktyn-connect` again.");if(r.status===401)throw new m("Server rejected the token (401). REDAKTYN_TOKEN must be a current OWNER or ADMIN login token.");if(r.status===403)throw new m("This token is not allowed to manage secrets (403). Importing needs an OWNER or ADMIN token.");if(!r.ok)throw new m(`GET /api/secrets failed: ${r.status} ${r.text.slice(0,200)}`);if(!Array.isArray(r.data))throw new m("GET /api/secrets did not return a list.");return r.data}function ot(e){try{const t=e.split(".")[1];if(!t)return null;const o=t+"=".repeat((4-t.length%4)%4),r=Buffer.from(o.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8");return JSON.parse(r)}catch{return null}}function st(e){if(!e)return null;if(e.type==="extension")return`REDAKTYN_TOKEN is an extension device token. Those can sync fingerprints but not register them.
15
+ `).forEach((n,i)=>{const h=i+1;if(n.trim()===""||n.trim().startsWith("#")||n.trim()==="---"||n.trim()==="...")return;if(/^\s/.test(n))throw new m(`${h}: this YAML is indented, so it is not flat key/value. Refusing rather than guessing \u2014 convert it to JSON and use --json.`);if(/^-\s/.test(n.trim())||n.trim()==="-")throw new m(`${h}: YAML lists are not supported. Use --json.`);if(/^[|>]/.test(n.trim()))throw new m(`${h}: YAML block scalars are not supported. Use --json.`);const a=/^([A-Za-z_][A-Za-z0-9_.-]*)\s*:\s?(.*)$/.exec(n);if(!a){o.push({line:h,message:"not a `key: value` line \u2014 skipped"});return}const c=a[1];let p=a[2]??"";if(p.trim()===""||p.trim()==="|"||p.trim()===">")throw new m(`${h}: "${c}" has no inline value, which in YAML means a nested block or null. Refusing rather than registering an empty fingerprint.`);const l=p.trim();if(l.startsWith('"')&&l.endsWith('"')&&l.length>1||l.startsWith("'")&&l.endsWith("'")&&l.length>1)p=l.slice(1,-1),l[0]==='"'&&(p=p.replace(/\\n/g,`
16
+ `).replace(/\\t/g," ").replace(/\\(.)/g,"$1"));else{const d=l.search(/\s#/);p=(d===-1?l:l.slice(0,d)).trim()}t.push({key:c,value:p,line:h})}),{entries:t,problems:o}}const Y=12,ze=new Set(["changeme","change-me","change_me","replaceme","replace-me","your-secret-here","your_secret_here","yoursecrethere","development","production","staging","localhost","password","passw0rd","secret","topsecret","undefined","none","null","n/a","todo","tbd","example","test","dummy","placeholder"]);function se(e){if(e.length===0)return 0;const t=new Map;for(const r of e)t.set(r,(t.get(r)??0)+1);let o=0;for(const r of t.values()){const n=r/e.length;o-=n*Math.log2(n)}return o}function Ge(e){if(!/:\/\//.test(e))return null;let t;try{t=new URL(e)}catch{return null}return t.password?{ok:!0}:[...t.pathname.split("/"),...t.searchParams.values(),t.hash.replace(/^#/,"")].filter(Boolean).some(r=>r.length>=16&&se(r)>=2.5)?{ok:!0}:{ok:!1,reason:"URL with no embedded credential or token"}}function Ve(e,{minLength:t=Y}={}){if(e.length===0)return{ok:!1,reason:"empty value"};if(e.length<t)return{ok:!1,reason:`only ${e.length} chars (minimum ${t})`};if(/^\d+$/.test(e))return{ok:!1,reason:"all digits \u2014 port, id or timestamp"};if(/^(true|false|yes|no|on|off|null|nil|none|undefined|enabled|disabled)$/i.test(e))return{ok:!1,reason:"boolean or empty-ish flag"};if(/^v?\d+(\.\d+){1,3}([-+][0-9A-Za-z.-]+)?$/.test(e))return{ok:!1,reason:"version number"};if(ze.has(e.toLowerCase()))return{ok:!1,reason:"placeholder or environment name"};if(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(e))return{ok:!1,reason:"email address"};if(/^(\/[^\s]*|\.{1,2}\/[^\s]*|~\/[^\s]*|[A-Za-z]:[\\/][^\s]*)$/.test(e))return{ok:!1,reason:"filesystem path"};const o=Ge(e);if(o&&!o.ok)return{ok:!1,reason:o.reason};if(!o){const r=new Set(e).size;if(r<5)return{ok:!1,reason:`only ${r} distinct characters`};if(se(e)<2)return{ok:!1,reason:"very low character diversity"}}return{ok:!0}}async function Ze(){if(process.stdin.isTTY)throw new m("--stdin was passed but nothing is piped in.");const e=[];for await(const t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf8")}function F(e,t){try{return me(e,"utf8")}catch(o){throw new m(`${t} ${e}: ${o.code==="ENOENT"?"no such file":o.message}`)}}function O(e){return`import:${e}`}function Xe(e){return String(e).replace(/^[./]+/,"").replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60)||"import"}function ie(e,t){return t.some(o=>o.includes("*")?new RegExp("^"+o.split("*").map(Qe).join(".*")+"$","i").test(e):e.toLowerCase()===o.toLowerCase())}const Qe=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function et({candidates:e,existing:t,source:o}){const r=O(o),n=new Map;for(const d of t)d.hmacHex&&n.set(d.hmacHex,d);const i=t.filter(d=>Array.isArray(d.tags)&&d.tags.includes(r)),h=new Map(i.map(d=>[d.label,d])),a=new Map;for(const d of t)i.includes(d)||a.has(d.label)||a.set(d.label,d);const c=[],p=new Set;for(const d of e){const{key:y,digests:u}=d;p.add(y);const $=h.get(y);if($){if($.hmacHex===u.digest&&tt($,u))c.push({key:y,action:"skip",reason:"already registered and unchanged",id:$.id,length:u.length});else{const b=n.get(u.digest);if(b&&b.id!==$.id)c.push({key:y,action:"conflict",reason:`new value is already registered as "${b.label}"`,id:$.id,length:u.length});else{const v=$.hmacHex===u.digest?"value unchanged; adding missing variants":"value changed";c.push({key:y,action:"rotate",reason:v,id:$.id,length:u.length})}}continue}const S=n.get(u.digest);if(S){c.push({key:y,action:"skip",reason:`already registered as "${S.label}"`,id:S.id,length:u.length});continue}const k=a.get(y);if(k){c.push({key:y,action:"conflict",reason:"a secret with this label exists outside this import source",id:k.id,length:u.length});continue}c.push({key:y,action:"create",reason:"new",length:u.length})}const l=i.filter(d=>!p.has(d.label)).map(d=>({label:d.label,id:d.id,status:d.status}));return{plan:c,missing:l}}function tt(e,t){return e.hmacHexStripped===t.hmacHexStripped&&e.hmacHexLower===t.hmacHexLower&&e.scanPrefilter===t.scanPrefilter}const ae=e=>e.replace(/\/+$/,"");async function H(e,t,o,r,n){let i;try{i=await fetch(`${ae(e)}${r}`,{method:o,headers:{Authorization:`Bearer ${t}`,...n?{"Content-Type":"application/json"}:{}},...n?{body:JSON.stringify(n)}:{}})}catch(c){throw new m(`Cannot reach ${ae(e)}: ${c.message}`)}const h=await i.text();let a=null;if(h)try{a=JSON.parse(h)}catch{a=null}return{status:i.status,ok:i.ok,data:a,text:h}}async function nt(e,t,o){const r=await H(e,t,"GET","/api/projects");if(!r.ok||!Array.isArray(r.data))throw new m(`GET /api/projects failed: ${r.status} ${String(r.text).slice(0,200)}`);const n=o.trim().toLowerCase(),i=r.data.filter(a=>a.id===o.trim()),h=i.length?i:r.data.filter(a=>String(a.name).toLowerCase()===n);if(h.length===0)throw new m(`No project named or numbered "${o}". Known: ${r.data.map(a=>a.name).join(", ")||"none"}.`);if(h.length>1)throw new m(`"${o}" matches ${h.length} projects. Pass the project id instead.`);if(h[0].status==="CLOSED")throw new m(`Project "${h[0].name}" is closed. Reopen it before enrolling into it.`);return h[0]}async function rt({plan:e,existing:t,serverUrl:o,token:r}){const n=e.filter(a=>a.action==="rotate"),i=a=>t.find(c=>c.id===a.id)?.projectId??null;if(!n.some(i))return;const h=await H(o,r,"GET","/api/projects");if(!(!h.ok||!Array.isArray(h.data)))for(const a of n){const c=i(a);if(!c)continue;const p=h.data.find(l=>l.id===c);p&&(p.usesOrgKey?a.sendProjectId=c:(a.action="conflict",a.reason=`lives in project "${p.name}", which has its own key; re-run with --project "${p.name}"`))}}async function ot(e,t,o=!1){const r=await H(e,t,"GET","/api/secrets");if(o&&(r.status===401||r.status===403))throw new m("This machine's Redaktyn session is no longer valid: the device was removed or its session ended. Ask your admin for a new invite link and run `redaktyn-connect` again.");if(r.status===401)throw new m("Server rejected the token (401). REDAKTYN_TOKEN must be a current OWNER or ADMIN login token.");if(r.status===403)throw new m("This token is not allowed to manage secrets (403). Importing needs an OWNER or ADMIN token.");if(!r.ok)throw new m(`GET /api/secrets failed: ${r.status} ${r.text.slice(0,200)}`);if(!Array.isArray(r.data))throw new m("GET /api/secrets did not return a list.");return r.data}function st(e){try{const t=e.split(".")[1];if(!t)return null;const o=t+"=".repeat((4-t.length%4)%4),r=Buffer.from(o.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8");return JSON.parse(r)}catch{return null}}function it(e){if(!e)return null;if(e.type==="extension")return`REDAKTYN_TOKEN is an extension device token. Those can sync fingerprints but not register them.
17
17
  Get an OWNER or ADMIN login token instead:
18
18
  curl -s -X POST "$REDAKTYN_SERVER_URL/api/auth/login" \\
19
19
  -H 'Content-Type: application/json' \\
20
- -d '{"email":"you@example.com","password":"\u2026"}' | jq -r .token`;const t=e.role;return typeof t=="string"&&!["OWNER","ADMIN"].includes(t.toUpperCase())?`This token has role ${t}. Importing needs OWNER or ADMIN.`:null}const it={create:{label:"CREATE",color:s.green},rotate:{label:"ROTATE",color:s.yellow},skip:{label:"skip",color:s.gray},conflict:{label:"CONFLICT",color:s.red},rejected:{label:"rejected",color:s.gray}};function le(e,t){return e.length<=t?e.padEnd(t):e.slice(0,t-1)+"\u2026"}function at({rows:e,missing:t,source:o,dryRun:r,budget:n,projectName:i=null}){const h=Math.min(process.stdout.columns||80,100),d=34;console.log(""),console.log(`${s.bold}Redaktyn import${s.reset} ${s.dim}\xB7 source tag ${O(o)}${i?` \xB7 project ${i}`:""}${s.reset}`),console.log(s.dim+"\u2500".repeat(h)+s.reset),console.log(`${s.dim}${"KEY".padEnd(d)} ${"LEN".padStart(5)} ${"ACTION".padEnd(9)} WHY${s.reset}`);for(const a of e){const l=it[a.action]??{label:a.action,color:""};console.log(`${le(a.key,d)} ${String(a.length??"-").padStart(5)} ${l.color}${l.label.padEnd(9)}${s.reset} ${s.dim}${a.reason??""}${s.reset}`)}console.log(s.dim+"\u2500".repeat(h)+s.reset);const c=H(e),p=[c.create?`${s.green}${c.create} to create${s.reset}`:null,c.rotate?`${s.yellow}${c.rotate} to rotate${s.reset}`:null,c.skip?`${c.skip} unchanged`:null,c.rejected?`${c.rejected} filtered out`:null,c.conflict?`${s.red}${c.conflict} conflicting${s.reset}`:null].filter(Boolean);if(console.log(" "+(p.length?p.join(s.dim+" \xB7 "+s.reset):"nothing to do")),t.length>0){console.log(""),console.log(`${s.yellow}${t.length} secret(s) tagged ${O(o)} are not in this input.${s.reset}`),console.log(`${s.dim} Reported only \u2014 import never removes anything. Retire them in the dashboard if they are gone.${s.reset}`);for(const a of t.slice(0,20))console.log(`${s.dim} \xB7 ${a.label}${s.reset}`);t.length>20&&console.log(`${s.dim} \xB7 \u2026 ${t.length-20} more${s.reset}`)}q(n),r&&(console.log(""),console.log(`${s.bold}Dry run \u2014 nothing was sent.${s.reset} ${s.dim}Re-run with --apply to register.${s.reset}`)),console.log("")}const lt={create:{label:"CREATE",paint:g.green},rotate:{label:"ROTATE",paint:g.amber},skip:{label:"skip",paint:g.gray},conflict:{label:"CONFLICT",paint:g.red},rejected:{label:"rejected",paint:g.gray}};function ct({rows:e,missing:t,source:o,dryRun:r,budget:n,projectName:i=null,byKey:h}){const d=Math.min(process.stderr.columns||90,100),c=30;w(""),w(` ${g.bold("Plan")} ${g.dim(`source tag ${O(o)}${i?` \xB7 project ${i}`:""}`)}`),w(` ${g.gray("\u2500".repeat(d-4))}`),w(` ${g.gray(`${"KEY".padEnd(c)} ${"LEN".padStart(4)} ${"ACTION".padEnd(8)} ${"FINGERPRINT".padEnd(11)} WHY`)}`);for(const l of e){const y=lt[l.action]??{label:l.action,paint:S=>S},u=h.get(l.key),$=u&&(l.action==="create"||l.action==="rotate")?de(u.digests.digest):"";w(` ${le(l.key,c)} ${String(l.length??"-").padStart(4)} ${y.paint(y.label.padEnd(8))} ${g.amber($.padEnd(11))} ${g.dim(l.reason??"")}`)}w(` ${g.gray("\u2500".repeat(d-4))}`);const p=H(e),a=[p.create?g.green(`${p.create} to create`):null,p.rotate?g.amber(`${p.rotate} to rotate`):null,p.skip?`${p.skip} unchanged`:null,p.rejected?`${p.rejected} filtered out`:null,p.conflict?g.red(`${p.conflict} conflicting`):null].filter(Boolean);if(w(` ${a.length?a.join(g.dim(" \xB7 ")):"nothing to do"}`),t.length>0){w(""),w(` ${g.amber("\u25B2")} ${t.length} secret(s) tagged ${O(o)} are not in this input. ${g.dim("Reported only: import never removes anything.")}`);for(const l of t.slice(0,10))w(` ${g.dim(`\xB7 ${l.label}`)}`);t.length>10&&w(` ${g.dim(`\xB7 \u2026 ${t.length-10} more`)}`)}q(n)}function q(e){if(!e||e.ceiling===1/0)return;const t=e.ceiling.toLocaleString("en-US"),o=r=>{if(!(e.legacySecrets>0)||!(e.ceilingIfReenrolled>e.ceiling))return;const n=e.legacySecrets;console.log(`${r} ${n} enrolled secret${n===1?" has":"s have"} no scan prefilter (enrolled before 2026-10-07 or by an older client),${s.reset}`),console.log(`${r} so every paste is checked against ${n===1?"it":"them"} the slow way. They are outside this import; re-enrolling ${n===1?"it":"them"}${s.reset}`),console.log(`${r} from the dashboard, or importing ${n===1?"it":"them"}, raises this to ~${e.ceilingIfReenrolled.toLocaleString("en-US")} chars.${s.reset}`)};if(e.ceiling<Pe){console.log(""),console.log(`${s.red}${s.bold}Scan budget: pastes over ~${t} characters will be refused${s.reset}`),console.log(` ${e.windowLengths} distinct window lengths after this import. Detection slides one pass per`),console.log(` length, so past that size the extension ${s.bold}refuses to scan${s.reset} rather than hang \u2014`),console.log(" which is a hard block in sensitive contexts. A paste at the ceiling takes up to ~8s."),o(""),console.log(`${s.dim} Register the high-value secrets only, or split them across workspaces.${s.reset}`);return}if(e.ceiling<Z){console.log(""),console.log(`${s.yellow}Scan budget:${s.reset} ${e.windowLengths} window lengths after this import; pastes above ~${t} chars are refused.`),o("");return}console.log(e.atCharacterCap?`${s.dim} Scan budget: every paste up to the extension's ${t}-char hard limit is scanned.${s.reset}`:`${s.dim} Scan budget: ${e.windowLengths} window lengths, pastes up to ~${t} chars.${s.reset}`),o(s.dim)}function H(e){const t={create:0,rotate:0,skip:0,conflict:0,rejected:0};for(const o of e)t[o.action]=(t[o.action]??0)+1;return t}async function dt(e){if(!process.stdin.isTTY)throw new m("--apply needs a terminal to confirm on, or --yes to skip the prompt.");const t=$e.createInterface({input:process.stdin,output:process.stdout});try{const o=await new Promise(r=>t.question(`${e} `,r));return/^y(es)?$/i.test(o.trim())}finally{t.close()}}function pt(e,t){return Re({label:e,hmacHex:t.digest,length:t.length,hmacHexStripped:t.hmacHexStripped,lengthStripped:t.lengthStripped,hmacHexLower:t.hmacHexLower,lengthLower:t.lengthLower,scanPrefilter:t.scanPrefilter})}function ce(e,t,{withPrefilter:o,projectId:r,tag:n}){const{scanPrefilter:i,...h}=t.digests,d=pt(e.key,o?{...h,scanPrefilter:i}:h),{label:c,...p}=d,a=r?{projectId:r}:{};return e.action==="create"?{method:"POST",path:"/api/secrets",body:{...d,...a,tags:[n]}}:{method:"PUT",path:`/api/secrets/${e.id}/digest`,body:{...p,...a}}}const de=e=>`${e.slice(0,8)}\u2026`;function ht(e,t){const o=[];let r="";for(const n of e.split(" "))r&&(r+" "+n).length>t?(o.push(r),r=n):r=r?`${r} ${n}`:n;return r&&o.push(r),o}async function ut({rows:e,byKey:t,serverUrl:o,token:r,source:n,projectId:i=null}){const h=[],d=O(n);let c=!0,p=0,a=0;const l=e.filter(u=>u.action==="create"||u.action==="rotate").length;let y=0;for(const u of e){if(u.action!=="create"&&u.action!=="rotate")continue;const $=t.get(u.key),S=A=>{const E=ce(u,$,{withPrefilter:A,projectId:i,tag:d});return p+=Buffer.byteLength(JSON.stringify(E.body)),a+=1,F(o,r,E.method,E.path,E.body)};let k=await S(c);c&&$.digests.scanPrefilter&&Ke(k)&&(c=!1,pe(),k=await S(!1)),y+=1;const v=R?` ${g.dim(de($.digests.digest))}`:"";if(k.ok){h.push({key:u.key,action:u.action,ok:!0}),console.log(` ${s.green}\u2713${s.reset} ${u.action==="create"?"created":"rotated"} ${u.key}${v}`),R&&w(` ${Oe(y,l)}`);continue}const b=yt(k);h.push({key:u.key,action:u.action,ok:!1,status:k.status,reason:b}),console.log(` ${s.red}\u2717${s.reset} ${u.key}: ${b}`)}return h.sentBytes=p,h.requests=a,h}const ft=e=>e.replace(/[0-9a-f]{40,}/g,t=>`${t.slice(0,12)}\u2026(${t.length} hex)`);function gt({writes:e,byKey:t,serverUrl:o,projectId:r,source:n,dryRun:i,showRequest:h,viaSession:d=!1}){if(e.length===0)return;const c=O(n),p=e.map(u=>{const $=t.get(u.key);return ce(u,$,{withPrefilter:!!$.digests.scanPrefilter,projectId:r,tag:c})}),a=p.reduce((u,$)=>u+Buffer.byteLength(JSON.stringify($.body)),0),l=[...new Set(p.flatMap(u=>Object.keys(u.body)))];let y=o;try{y=new URL(o).host}catch{}if(R&&(w(""),B(i?"What WOULD leave this machine":"What leaves this machine",["",...K([["Sent to",`${y}: ${p.length} request${p.length===1?"":"s"}, ${z(a)} in total`],["Each request","label, 3 fingerprints, 3 lengths"],...ht(l.join(", "),44).map(u=>["",g.dim(u)]),["Secret values",g.green("0 B")]],{indent:0,labelWidth:18}),"",g.dim("Never leaves this machine:"),...K([["The values",`${e.length} read into memory, fingerprinted, then dropped`],...d?[["Your passphrase","not used here. This machine holds the project's key from its invite"],["The project key","in the session file only you can read; never sent to the server"]]:[["Your passphrase","asked for, used to derive the key, then forgotten"],["The workspace key","derived here, held in memory, never written or sent"]]],{indent:0,labelWidth:18}),""],{tone:"green",width:100})),h){const u=p[0];w(""),w(` ${g.dim(`The first request, exactly as it is built (${u.method} ${u.path}), digests shortened:`)}`),w(ft(JSON.stringify(u.body,null,2)).split(`
20
+ -d '{"email":"you@example.com","password":"\u2026"}' | jq -r .token`;const t=e.role;return typeof t=="string"&&!["OWNER","ADMIN"].includes(t.toUpperCase())?`This token has role ${t}. Importing needs OWNER or ADMIN.`:null}const at={create:{label:"CREATE",color:s.green},rotate:{label:"ROTATE",color:s.yellow},skip:{label:"skip",color:s.gray},conflict:{label:"CONFLICT",color:s.red},rejected:{label:"rejected",color:s.gray}};function le(e,t){return e.length<=t?e.padEnd(t):e.slice(0,t-1)+"\u2026"}function lt({rows:e,missing:t,source:o,dryRun:r,budget:n,projectName:i=null}){const h=Math.min(process.stdout.columns||80,100),a=34;console.log(""),console.log(`${s.bold}Redaktyn import${s.reset} ${s.dim}\xB7 source tag ${O(o)}${i?` \xB7 project ${i}`:""}${s.reset}`),console.log(s.dim+"\u2500".repeat(h)+s.reset),console.log(`${s.dim}${"KEY".padEnd(a)} ${"LEN".padStart(5)} ${"ACTION".padEnd(9)} WHY${s.reset}`);for(const l of e){const d=at[l.action]??{label:l.action,color:""};console.log(`${le(l.key,a)} ${String(l.length??"-").padStart(5)} ${d.color}${d.label.padEnd(9)}${s.reset} ${s.dim}${l.reason??""}${s.reset}`)}console.log(s.dim+"\u2500".repeat(h)+s.reset);const c=M(e),p=[c.create?`${s.green}${c.create} to create${s.reset}`:null,c.rotate?`${s.yellow}${c.rotate} to rotate${s.reset}`:null,c.skip?`${c.skip} unchanged`:null,c.rejected?`${c.rejected} filtered out`:null,c.conflict?`${s.red}${c.conflict} conflicting${s.reset}`:null].filter(Boolean);if(console.log(" "+(p.length?p.join(s.dim+" \xB7 "+s.reset):"nothing to do")),t.length>0){console.log(""),console.log(`${s.yellow}${t.length} secret(s) tagged ${O(o)} are not in this input.${s.reset}`),console.log(`${s.dim} Reported only \u2014 import never removes anything. Retire them in the dashboard if they are gone.${s.reset}`);for(const l of t.slice(0,20))console.log(`${s.dim} \xB7 ${l.label}${s.reset}`);t.length>20&&console.log(`${s.dim} \xB7 \u2026 ${t.length-20} more${s.reset}`)}q(n),r&&(console.log(""),console.log(`${s.bold}Dry run \u2014 nothing was sent.${s.reset} ${s.dim}Re-run with --apply to register.${s.reset}`)),console.log("")}const ct={create:{label:"CREATE",paint:g.green},rotate:{label:"ROTATE",paint:g.amber},skip:{label:"skip",paint:g.gray},conflict:{label:"CONFLICT",paint:g.red},rejected:{label:"rejected",paint:g.gray}};function dt({rows:e,missing:t,source:o,dryRun:r,budget:n,projectName:i=null,byKey:h}){const a=Math.min(process.stderr.columns||90,100),c=30;w(""),w(` ${g.bold("Plan")} ${g.dim(`source tag ${O(o)}${i?` \xB7 project ${i}`:""}`)}`),w(` ${g.gray("\u2500".repeat(a-4))}`),w(` ${g.gray(`${"KEY".padEnd(c)} ${"LEN".padStart(4)} ${"ACTION".padEnd(8)} ${"FINGERPRINT".padEnd(11)} WHY`)}`);for(const d of e){const y=ct[d.action]??{label:d.action,paint:S=>S},u=h.get(d.key),$=u&&(d.action==="create"||d.action==="rotate")?de(u.digests.digest):"";w(` ${le(d.key,c)} ${String(d.length??"-").padStart(4)} ${y.paint(y.label.padEnd(8))} ${g.amber($.padEnd(11))} ${g.dim(d.reason??"")}`)}w(` ${g.gray("\u2500".repeat(a-4))}`);const p=M(e),l=[p.create?g.green(`${p.create} to create`):null,p.rotate?g.amber(`${p.rotate} to rotate`):null,p.skip?`${p.skip} unchanged`:null,p.rejected?`${p.rejected} filtered out`:null,p.conflict?g.red(`${p.conflict} conflicting`):null].filter(Boolean);if(w(` ${l.length?l.join(g.dim(" \xB7 ")):"nothing to do"}`),t.length>0){w(""),w(` ${g.amber("\u25B2")} ${t.length} secret(s) tagged ${O(o)} are not in this input. ${g.dim("Reported only: import never removes anything.")}`);for(const d of t.slice(0,10))w(` ${g.dim(`\xB7 ${d.label}`)}`);t.length>10&&w(` ${g.dim(`\xB7 \u2026 ${t.length-10} more`)}`)}q(n)}function q(e){if(!e||e.ceiling===1/0)return;const t=e.ceiling.toLocaleString("en-US"),o=r=>{if(!(e.legacySecrets>0)||!(e.ceilingIfReenrolled>e.ceiling))return;const n=e.legacySecrets;console.log(`${r} ${n} enrolled secret${n===1?" has":"s have"} no scan prefilter (enrolled before 2026-10-07 or by an older client),${s.reset}`),console.log(`${r} so every paste is checked against ${n===1?"it":"them"} the slow way. They are outside this import; re-enrolling ${n===1?"it":"them"}${s.reset}`),console.log(`${r} from the dashboard, or importing ${n===1?"it":"them"}, raises this to ~${e.ceilingIfReenrolled.toLocaleString("en-US")} chars.${s.reset}`)};if(e.ceiling<Pe){console.log(""),console.log(`${s.red}${s.bold}Scan budget: pastes over ~${t} characters will be refused${s.reset}`),console.log(` ${e.windowLengths} distinct window lengths after this import. Detection slides one pass per`),console.log(` length, so past that size the extension ${s.bold}refuses to scan${s.reset} rather than hang \u2014`),console.log(" which is a hard block in sensitive contexts. A paste at the ceiling takes up to ~8s."),o(""),console.log(`${s.dim} Register the high-value secrets only, or split them across workspaces.${s.reset}`);return}if(e.ceiling<Z){console.log(""),console.log(`${s.yellow}Scan budget:${s.reset} ${e.windowLengths} window lengths after this import; pastes above ~${t} chars are refused.`),o("");return}console.log(e.atCharacterCap?`${s.dim} Scan budget: every paste up to the extension's ${t}-char hard limit is scanned.${s.reset}`:`${s.dim} Scan budget: ${e.windowLengths} window lengths, pastes up to ~${t} chars.${s.reset}`),o(s.dim)}function M(e){const t={create:0,rotate:0,skip:0,conflict:0,rejected:0};for(const o of e)t[o.action]=(t[o.action]??0)+1;return t}async function pt(e){if(!process.stdin.isTTY)throw new m("--apply needs a terminal to confirm on, or --yes to skip the prompt.");const t=$e.createInterface({input:process.stdin,output:process.stdout});try{const o=await new Promise(r=>t.question(`${e} `,r));return/^y(es)?$/i.test(o.trim())}finally{t.close()}}function ht(e,t){return je({label:e,hmacHex:t.digest,length:t.length,hmacHexStripped:t.hmacHexStripped,lengthStripped:t.lengthStripped,hmacHexLower:t.hmacHexLower,lengthLower:t.lengthLower,scanPrefilter:t.scanPrefilter})}function ce(e,t,{withPrefilter:o,projectId:r,tag:n}){const{scanPrefilter:i,...h}=t.digests,a=ht(e.key,o?{...h,scanPrefilter:i}:h),{label:c,...p}=a,l=e.sendProjectId??r,d=l?{projectId:l}:{};return e.action==="create"?{method:"POST",path:"/api/secrets",body:{...a,...d,tags:[n]}}:{method:"PUT",path:`/api/secrets/${e.id}/digest`,body:{...p,...d}}}const de=e=>`${e.slice(0,8)}\u2026`;function ut(e,t){const o=[];let r="";for(const n of e.split(" "))r&&(r+" "+n).length>t?(o.push(r),r=n):r=r?`${r} ${n}`:n;return r&&o.push(r),o}async function ft({rows:e,byKey:t,serverUrl:o,token:r,source:n,projectId:i=null}){const h=[],a=O(n);let c=!0,p=0,l=0;const d=e.filter(u=>u.action==="create"||u.action==="rotate").length;let y=0;for(const u of e){if(u.action!=="create"&&u.action!=="rotate")continue;const $=t.get(u.key),S=E=>{const N=ce(u,$,{withPrefilter:E,projectId:i,tag:a});return p+=Buffer.byteLength(JSON.stringify(N.body)),l+=1,H(o,r,N.method,N.path,N.body)};let k=await S(c);c&&$.digests.scanPrefilter&&Ke(k)&&(c=!1,pe(),k=await S(!1)),y+=1;const b=j?` ${g.dim(de($.digests.digest))}`:"";if(k.ok){h.push({key:u.key,action:u.action,ok:!0}),console.log(` ${s.green}\u2713${s.reset} ${u.action==="create"?"created":"rotated"} ${u.key}${b}`),j&&w(` ${Oe(y,d)}`);continue}const v=$t(k);h.push({key:u.key,action:u.action,ok:!1,status:k.status,reason:v}),console.log(` ${s.red}\u2717${s.reset} ${u.key}: ${v}`)}return h.sentBytes=p,h.requests=l,h}const gt=e=>e.replace(/[0-9a-f]{40,}/g,t=>`${t.slice(0,12)}\u2026(${t.length} hex)`);function mt({writes:e,byKey:t,serverUrl:o,projectId:r,source:n,dryRun:i,showRequest:h,viaSession:a=!1}){if(e.length===0)return;const c=O(n),p=e.map(u=>{const $=t.get(u.key);return ce(u,$,{withPrefilter:!!$.digests.scanPrefilter,projectId:r,tag:c})}),l=p.reduce((u,$)=>u+Buffer.byteLength(JSON.stringify($.body)),0),d=[...new Set(p.flatMap(u=>Object.keys(u.body)))];let y=o;try{y=new URL(o).host}catch{}if(j&&(w(""),B(i?"What WOULD leave this machine":"What leaves this machine",["",...J([["Sent to",`${y}: ${p.length} request${p.length===1?"":"s"}, ${z(l)} in total`],["Each request","label, 3 fingerprints, 3 lengths"],...ut(d.join(", "),44).map(u=>["",g.dim(u)]),["Secret values",g.green("0 B")]],{indent:0,labelWidth:18}),"",g.dim("Never leaves this machine:"),...J([["The values",`${e.length} read into memory, fingerprinted, then dropped`],...a?[["Your passphrase","not used here. This machine holds the project's key from its invite"],["The project key","in the session file only you can read; never sent to the server"]]:[["Your passphrase","asked for, used to derive the key, then forgotten"],["The workspace key","derived here, held in memory, never written or sent"]]],{indent:0,labelWidth:18}),""],{tone:"green",width:100})),h){const u=p[0];w(""),w(` ${g.dim(`The first request, exactly as it is built (${u.method} ${u.path}), digests shortened:`)}`),w(gt(JSON.stringify(u.body,null,2)).split(`
21
21
  `).map($=>` ${$}`).join(`
22
- `))}else R&&w(` ${g.dim("See the exact request body: --show-request")}`)}async function mt({label:e,cand:t,viaSession:o=!1}){const r=t.digests.length;w(""),w(` ${g.bold(e)} ${g.gray("\u2022".repeat(Math.min(r,22)))} ${g.dim(`${r} characters, read here and never sent`)}`),w(` ${g.gray(C.bar)} ${g.dim("normalise ")} trim, unicode NFC, strip invisible characters`),w(o?` ${g.gray(C.bar)} ${g.dim("project key ")} the key from your invite, already on this machine (no passphrase needed)`:` ${g.gray(C.bar)} ${g.dim("derive key ")} PBKDF2-SHA256, 600,000 rounds, from your passphrase, on this machine`),await Le(` ${g.gray(C.down)} ${g.dim("fingerprint ")} `,t.digests.digest,{show:16}),w(` ${g.dim("HMAC-SHA256, plus whitespace-stripped and lower-case variants, so a disguised paste still matches")}`),w("")}function pe(){console.log(`${s.yellow}!${s.reset} This server does not store scan prefilters yet, so secrets are registered without one.`),console.log(`${s.dim} They are protected exactly the same, but every paste checks them the slow way. Re-run this${s.reset}`),console.log(`${s.dim} import once the server is updated; it adds the prefilter to each of them.${s.reset}`)}function yt(e){if(e.status===409)return"another secret in this workspace already has this fingerprint";if(e.status===403)return"token is not OWNER or ADMIN";if(e.status===401)return"token expired or invalid";if(e.status===404)return"secret no longer exists \u2014 re-run to re-plan";const t=e.data&&typeof e.data.error=="string"?e.data.error:e.text.slice(0,160);return`${e.status} ${t}`}function $t(){console.log(`
22
+ `))}else j&&w(` ${g.dim("See the exact request body: --show-request")}`)}async function yt({label:e,cand:t,viaSession:o=!1}){const r=t.digests.length;w(""),w(` ${g.bold(e)} ${g.gray("\u2022".repeat(Math.min(r,22)))} ${g.dim(`${r} characters, read here and never sent`)}`),w(` ${g.gray(C.bar)} ${g.dim("normalise ")} trim, unicode NFC, strip invisible characters`),w(o?` ${g.gray(C.bar)} ${g.dim("project key ")} the key from your invite, already on this machine (no passphrase needed)`:` ${g.gray(C.bar)} ${g.dim("derive key ")} PBKDF2-SHA256, 600,000 rounds, from your passphrase, on this machine`),await Ie(` ${g.gray(C.down)} ${g.dim("fingerprint ")} `,t.digests.digest,{show:16}),w(` ${g.dim("HMAC-SHA256, plus whitespace-stripped and lower-case variants, so a disguised paste still matches")}`),w("")}function pe(){console.log(`${s.yellow}!${s.reset} This server does not store scan prefilters yet, so secrets are registered without one.`),console.log(`${s.dim} They are protected exactly the same, but every paste checks them the slow way. Re-run this${s.reset}`),console.log(`${s.dim} import once the server is updated; it adds the prefilter to each of them.${s.reset}`)}function $t(e){if(e.status===409&&e.data?.code==="PROJECT_MISMATCH"&&typeof e.data.error=="string")return e.data.error;if(e.status===409)return"another secret in this workspace already has this fingerprint";if(e.status===403)return"token is not OWNER or ADMIN";if(e.status===401)return"token expired or invalid";if(e.status===404)return"secret no longer exists \u2014 re-run to re-plan";const t=e.data&&typeof e.data.error=="string"?e.data.error:e.text.slice(0,160);return`${e.status} ${t}`}function wt(){console.log(`
23
23
  ${s.bold}redaktyn-import${s.reset} \u2014 register fingerprints in bulk from files or any vault CLI
24
24
 
25
25
  ${s.bold}Digests are computed on this machine.${s.reset} Values are never sent, never
@@ -66,4 +66,4 @@ ${s.bold}Exit codes${s.reset}
66
66
  0 plan printed, or every write succeeded
67
67
  1 one or more writes failed
68
68
  2 usage, auth or parse error
69
- `)}async function wt(e){const t=[e.env&&"env",e.jsonFile&&"json",e.yaml&&"yaml",e.stdin&&"stdin"].filter(Boolean);if(t.length===0)throw new m("Nothing to import. Pass one of --env, --json, --yaml or --stdin (see --help).");if(t.length>1)throw new m(`Pick one input mode, got: ${t.map(i=>"--"+i).join(", ")}`);const o=t[0];if(o==="env")return{...Fe(J(e.env,"--env")),mode:o,defaultSource:W(e.env)};if(o==="json")return{...oe(J(e.jsonFile,"--json")),mode:o,defaultSource:W(e.jsonFile)};if(o==="yaml")return{...Be(J(e.yaml,"--yaml")),mode:o,defaultSource:W(e.yaml)};const r=await Ze();if(r.trim()==="")throw new m("Nothing arrived on stdin.");return{...oe(r),mode:o,defaultSource:"stdin"}}async function kt(e){const t=process.env.REDAKTYN_TOKEN||process.env.REDAKTYN_JWT;let o=null;if(!t){const a=U();if(a)try{o=await Ne(a)}catch(l){throw new m(l.message)}}const r=e.server||!t&&o?.serverUrl||Ee(),n=t||o?.token;if(!n)throw new m("Run `redaktyn-login` to sign in as an OWNER or ADMIN (or set REDAKTYN_TOKEN for a script).");const i=ot(n),h=st(i);if(h)throw new m(h);const d=e.orgId||i?.orgId||i?.org_id||process.env.REDAKTYN_ORG_ID;if(!d)throw new m("Could not determine the org id from the token. Pass --org-id.");const c=e.orgId||process.env.REDAKTYN_ORG_ID;if(c&&i?.orgId&&c!==i.orgId)throw new m("The org id given does not match the token's org id.");let p;try{p=await xe({server:r,token:n,orgId:d,who:o?`Signed in as ${o.email}${o.orgName?` (${o.orgName})`:""}.`:null,label:"Org passphrase",record:!!e.apply})}catch(a){throw new m(a.message)}return{serverUrl:r,token:n,orgId:d,passphrase:p}}async function vt(e){const o=process.env.REDAKTYN_TOKEN||process.env.REDAKTYN_JWT||U()?null:Ae();if(o){let a;try{a=await je(o)}catch(l){throw new m(l.message)}if(e.project){const l=e.project.trim().toLowerCase();if(l!==String(a.projectId).toLowerCase()&&l!==String(a.projectName||"").toLowerCase())throw new m(`This machine is connected to project "${a.projectName??a.projectId}" only, not "${e.project}". Drop --project, or ask for an invite to the other project.`)}if(!a.projectId)throw new m("This session is not tied to a project. Ask for a new invite link.");if(e.apply&&!a.canEnrol)throw new m("This invite lets you scan but not enrol secrets. Ask your admin for a link made with: redaktyn-invite --can-enrol");return{serverUrl:e.server||a.serverUrl,token:a.token,key:Buffer.from(a.key,"hex"),project:{id:a.projectId,name:a.projectName??a.projectId,usesOrgKey:a.projectUsesOrgKey===!0},viaSession:!0}}const{serverUrl:r,token:n,orgId:i,passphrase:h}=await kt(e),d=await be(h,i),c=e.project?await nt(r,n,e.project):null,p=c&&!c.usesOrgKey?Se(d,c.id):d;return{serverUrl:r,token:n,key:p,project:c,viaSession:!1}}async function bt(){const e=Ye(process.argv);if(e.help)return $t(),0;e.reportJson||Te("import secrets",_e);const t=await wt(e),o=Xe(e.source??t.defaultSource);R&&!e.reportJson&&w(` ${g.green("\u2714")} Read ${t.entries.length} key${t.entries.length===1?"":"s"} ${g.dim(`(${t.mode}); the values stay in memory`)}`);const r=new Map;for(const f of t.entries)r.set(f.key,f);const n=t.entries.length-r.size;let i=[...r.values()];if(e.only.length>0&&(i=i.filter(f=>ie(f.key,e.only))),e.exclude.length>0&&(i=i.filter(f=>!ie(f.key,e.exclude))),i.length===0)throw new m(`No usable keys found in the input (${t.mode}). `+(t.problems?.length?`${t.problems.length} line(s) were skipped \u2014 see above.`:""));const{serverUrl:h,token:d,key:c,project:p,viaSession:a}=await vt(e),l=e.minLength??Y,y=[],u=[],$=R&&!e.reportJson?G("Fingerprinting on this machine"):null;for(const f of i){if(f.key.length>200){u.push({key:f.key,action:"rejected",reason:"key longer than 200 characters"});continue}const j=ke(f.value),P=Ve(j,{minLength:l});if(!P.ok&&!e.allowWeak){u.push({key:f.key,action:"rejected",reason:P.reason,length:j.length});continue}const ge=ve(f.value,c);y.push({key:f.key,digests:ge,weak:!P.ok,weakReason:P.reason})}$?.succeed(`${y.length} fingerprint${y.length===1?"":"s"} computed here ${g.dim("(three variants each)")}`),R&&!e.reportJson&&y.length>0&&await mt({label:y[0].key,cand:y[0],viaSession:a});const S=R&&!e.reportJson?G("Comparing with what your workspace already holds"):null;let k=await rt(h,d,a);p&&(k=k.filter(f=>f&&f.projectId===p.id)),S?.succeed(`${k.length} existing secret${k.length===1?"":"s"} compared`);const v=We(k);if(!v)for(const f of y)delete f.digests.scanPrefilter;const{plan:b,missing:A}=et({candidates:y,existing:k,source:o}),E=new Map(y.map(f=>[f.key,f]));for(const f of b){const j=E.get(f.key);j?.weak&&(f.action==="create"||f.action==="rotate")&&(f.reason=`${f.reason} (weak: ${j.weakReason}, allowed by --allow-weak)`)}const _=[...b,...u].sort((f,j)=>ue(f.action)-ue(j.action)||f.key.localeCompare(j.key)),fe=St({existing:k,plan:b,byKey:E}),N=Me(fe),M=b.filter(f=>f.action==="create"||f.action==="rotate");if(e.reportJson){if(console.log(JSON.stringify({source:o,sourceTag:O(o),mode:t.mode,shape:t.shape??null,dryRun:!e.apply,minLength:l,allowWeak:e.allowWeak,duplicateKeys:n,inputProblems:t.problems??[],counts:H(_),plan:_.map(f=>({key:f.key,action:f.action,reason:f.reason??null,length:f.length??null})),missing:A,scanBudget:{windowLengths:N.windowLengths,maxPasteChars:N.ceiling===1/0?null:N.ceiling,warn:N.ceiling<Z,atCharacterCap:N.atCharacterCap,legacySecrets:N.legacySecrets,maxPasteCharsIfReenrolled:N.ceilingIfReenrolled===1/0?null:N.ceilingIfReenrolled,serverStoresScanPrefilter:v}},null,2)),!e.apply)return 0}else{for(const f of t.problems??[]){const j=f.line!==void 0?`line ${f.line}`:f.key;console.log(`${s.yellow}!${s.reset} ${j}: ${f.message}`)}n>0&&console.log(`${s.dim}${n} duplicate key(s) in the input; the last value of each was used.${s.reset}`),v||pe(),R?ct({rows:_,missing:A,source:o,dryRun:!e.apply,budget:N,projectName:p?p.name:null,byKey:E}):at({rows:_,missing:A,source:o,dryRun:!e.apply,budget:N,projectName:p?p.name:null}),gt({writes:M,byKey:E,serverUrl:h,projectId:p?p.id:null,source:o,dryRun:!e.apply,showRequest:e.showRequest,viaSession:a}),R&&!e.apply&&(w(""),w(` ${g.bold("Dry run. Nothing was sent.")} ${g.dim("Re-run with --apply to register.")}`)),R&&w("")}if(!e.apply)return 0;if(M.length===0)return console.log(`${s.dim}Nothing to write.${s.reset}`),0;if(!e.yes){const f=H(b);if(!await dt(`Register ${f.create} new and rotate ${f.rotate} existing fingerprint(s) for this org? [y/N]`))return console.log("Aborted."),0}console.log("");const T=await ut({rows:M,byKey:E,serverUrl:h,token:d,source:o,projectId:p?p.id:null}),L=T.filter(f=>!f.ok);return console.log(""),console.log(L.length===0?`${s.green}${T.length} fingerprint(s) registered.${s.reset}`:`${s.red}${L.length} of ${T.length} failed.${s.reset}`),q(N),R&&(w(""),B(L.length===0?"Done":"Finished with errors",["",...K([["Registered",`${T.length-L.length} of ${T.length}`],["Sent",`${z(T.sentBytes??0)} in ${T.requests??0} request${T.requests===1?"":"s"}`],["Secret values sent",g.green("0 B")],["Takes effect","in every connected browser within about a minute"]],{indent:0}),""],{tone:L.length===0?"green":"red",width:78})),console.log(""),L.length===0?0:1}const he=["create","rotate","conflict","skip","rejected"],ue=e=>{const t=he.indexOf(e);return t===-1?he.length:t};function St({existing:e,plan:t,byKey:o}){const r=e.map(i=>({...i})),n=new Map(r.map(i=>[i.id,i]));for(const i of t){const h=o.get(i.key);if(!h)continue;const d=h.digests;if(i.action==="create"){r.push({id:`pending:${i.key}`,label:i.key,hmacHex:d.digest,length:d.length,hmacHexStripped:d.hmacHexStripped,lengthStripped:d.lengthStripped,hmacHexLower:d.hmacHexLower,lengthLower:d.lengthLower,scanPrefilter:d.scanPrefilter,tags:[]});continue}if(i.action==="rotate"){const c=n.get(i.id);if(!c)continue;c.hmacHex=d.digest,c.length=d.length,c.hmacHexStripped=d.hmacHexStripped,c.lengthStripped=d.lengthStripped,c.hmacHexLower=d.hmacHexLower,c.lengthLower=d.lengthLower,c.scanPrefilter=d.scanPrefilter}}return r}function Rt(){try{return ye(process.argv[1])}catch{return process.argv[1]}}const Nt=!!process.argv[1]&&import.meta.url===we(Rt()).href;Nt&&bt().then(e=>process.exit(e)).catch(e=>{e instanceof m&&(console.error(`${s.red}${e.message}${s.reset}`),process.exit(2)),console.error(`${s.red}Fatal: ${e instanceof Error?e.message:e}${s.reset}`),process.exit(1)});export{Y as DEFAULT_MIN_LENGTH,ot as decodeJwtPayload,et as diffAgainstServer,Ue as entriesFromJsonDocument,Ve as junkVerdict,Xe as normalizeSource,Fe as parseDotenv,Be as parseFlatYaml,oe as parseJsonSecrets,Me as scanBudgetForSecrets,O as sourceTag,st as tokenRoleProblem,ne as unwrapSecretsDocument};
69
+ `)}async function kt(e){const t=[e.env&&"env",e.jsonFile&&"json",e.yaml&&"yaml",e.stdin&&"stdin"].filter(Boolean);if(t.length===0)throw new m("Nothing to import. Pass one of --env, --json, --yaml or --stdin (see --help).");if(t.length>1)throw new m(`Pick one input mode, got: ${t.map(i=>"--"+i).join(", ")}`);const o=t[0];if(o==="env")return{...Fe(F(e.env,"--env")),mode:o,defaultSource:K(e.env)};if(o==="json")return{...oe(F(e.jsonFile,"--json")),mode:o,defaultSource:K(e.jsonFile)};if(o==="yaml")return{...Be(F(e.yaml,"--yaml")),mode:o,defaultSource:K(e.yaml)};const r=await Ze();if(r.trim()==="")throw new m("Nothing arrived on stdin.");return{...oe(r),mode:o,defaultSource:"stdin"}}async function vt(e){const t=process.env.REDAKTYN_TOKEN||process.env.REDAKTYN_JWT;let o=null;if(!t){const l=U();if(l)try{o=await Re(l)}catch(d){throw new m(d.message)}}const r=e.server||!t&&o?.serverUrl||Ne(),n=t||o?.token;if(!n)throw new m("Run `redaktyn-login` to sign in as an OWNER or ADMIN (or set REDAKTYN_TOKEN for a script).");const i=st(n),h=it(i);if(h)throw new m(h);const a=e.orgId||i?.orgId||i?.org_id||process.env.REDAKTYN_ORG_ID;if(!a)throw new m("Could not determine the org id from the token. Pass --org-id.");const c=e.orgId||process.env.REDAKTYN_ORG_ID;if(c&&i?.orgId&&c!==i.orgId)throw new m("The org id given does not match the token's org id.");let p;try{p=await xe({server:r,token:n,orgId:a,who:o?`Signed in as ${o.email}${o.orgName?` (${o.orgName})`:""}.`:null,label:"Org passphrase",record:!!e.apply})}catch(l){throw new m(l.message)}return{serverUrl:r,token:n,orgId:a,passphrase:p}}async function bt(e){const o=process.env.REDAKTYN_TOKEN||process.env.REDAKTYN_JWT||U()?null:Ee();if(o){let l;try{l=await Ae(o)}catch(d){throw new m(d.message)}if(e.project){const d=e.project.trim().toLowerCase();if(d!==String(l.projectId).toLowerCase()&&d!==String(l.projectName||"").toLowerCase())throw new m(`This machine is connected to project "${l.projectName??l.projectId}" only, not "${e.project}". Drop --project, or ask for an invite to the other project.`)}if(!l.projectId)throw new m("This session is not tied to a project. Ask for a new invite link.");if(e.apply&&!l.canEnrol)throw new m("This invite lets you scan but not enrol secrets. Ask your admin for a link made with: redaktyn-invite --can-enrol");return{serverUrl:e.server||l.serverUrl,token:l.token,key:Buffer.from(l.key,"hex"),project:{id:l.projectId,name:l.projectName??l.projectId,usesOrgKey:l.projectUsesOrgKey===!0},viaSession:!0}}const{serverUrl:r,token:n,orgId:i,passphrase:h}=await vt(e),a=await be(h,i),c=e.project?await nt(r,n,e.project):null,p=c&&!c.usesOrgKey?Se(a,c.id):a;return{serverUrl:r,token:n,key:p,project:c,viaSession:!1}}async function St(){const e=Je(process.argv);if(e.help)return wt(),0;e.reportJson||Te("import secrets",_e);const t=await kt(e),o=Xe(e.source??t.defaultSource);j&&!e.reportJson&&w(` ${g.green("\u2714")} Read ${t.entries.length} key${t.entries.length===1?"":"s"} ${g.dim(`(${t.mode}); the values stay in memory`)}`);const r=new Map;for(const f of t.entries)r.set(f.key,f);const n=t.entries.length-r.size;let i=[...r.values()];if(e.only.length>0&&(i=i.filter(f=>ie(f.key,e.only))),e.exclude.length>0&&(i=i.filter(f=>!ie(f.key,e.exclude))),i.length===0)throw new m(`No usable keys found in the input (${t.mode}). `+(t.problems?.length?`${t.problems.length} line(s) were skipped \u2014 see above.`:""));const{serverUrl:h,token:a,key:c,project:p,viaSession:l}=await bt(e),d=e.minLength??Y,y=[],u=[],$=j&&!e.reportJson?G("Fingerprinting on this machine"):null;for(const f of i){if(f.key.length>200){u.push({key:f.key,action:"rejected",reason:"key longer than 200 characters"});continue}const A=ke(f.value),P=Ve(A,{minLength:d});if(!P.ok&&!e.allowWeak){u.push({key:f.key,action:"rejected",reason:P.reason,length:A.length});continue}const ge=ve(f.value,c);y.push({key:f.key,digests:ge,weak:!P.ok,weakReason:P.reason})}$?.succeed(`${y.length} fingerprint${y.length===1?"":"s"} computed here ${g.dim("(three variants each)")}`),j&&!e.reportJson&&y.length>0&&await yt({label:y[0].key,cand:y[0],viaSession:l});const S=j&&!e.reportJson?G("Comparing with what your workspace already holds"):null;let k=await ot(h,a,l);p&&(k=k.filter(f=>f&&f.projectId===p.id)),S?.succeed(`${k.length} existing secret${k.length===1?"":"s"} compared`);const b=We(k);if(!b)for(const f of y)delete f.digests.scanPrefilter;const{plan:v,missing:E}=et({candidates:y,existing:k,source:o});p||await rt({plan:v,existing:k,serverUrl:h,token:a});const N=new Map(y.map(f=>[f.key,f]));for(const f of v){const A=N.get(f.key);A?.weak&&(f.action==="create"||f.action==="rotate")&&(f.reason=`${f.reason} (weak: ${A.weakReason}, allowed by --allow-weak)`)}const _=[...v,...u].sort((f,A)=>ue(f.action)-ue(A.action)||f.key.localeCompare(A.key)),fe=jt({existing:k,plan:v,byKey:N}),R=Me(fe),W=v.filter(f=>f.action==="create"||f.action==="rotate");if(e.reportJson){if(console.log(JSON.stringify({source:o,sourceTag:O(o),mode:t.mode,shape:t.shape??null,dryRun:!e.apply,minLength:d,allowWeak:e.allowWeak,duplicateKeys:n,inputProblems:t.problems??[],counts:M(_),plan:_.map(f=>({key:f.key,action:f.action,reason:f.reason??null,length:f.length??null})),missing:E,scanBudget:{windowLengths:R.windowLengths,maxPasteChars:R.ceiling===1/0?null:R.ceiling,warn:R.ceiling<Z,atCharacterCap:R.atCharacterCap,legacySecrets:R.legacySecrets,maxPasteCharsIfReenrolled:R.ceilingIfReenrolled===1/0?null:R.ceilingIfReenrolled,serverStoresScanPrefilter:b}},null,2)),!e.apply)return 0}else{for(const f of t.problems??[]){const A=f.line!==void 0?`line ${f.line}`:f.key;console.log(`${s.yellow}!${s.reset} ${A}: ${f.message}`)}n>0&&console.log(`${s.dim}${n} duplicate key(s) in the input; the last value of each was used.${s.reset}`),b||pe(),j?dt({rows:_,missing:E,source:o,dryRun:!e.apply,budget:R,projectName:p?p.name:null,byKey:N}):lt({rows:_,missing:E,source:o,dryRun:!e.apply,budget:R,projectName:p?p.name:null}),mt({writes:W,byKey:N,serverUrl:h,projectId:p?p.id:null,source:o,dryRun:!e.apply,showRequest:e.showRequest,viaSession:l}),j&&!e.apply&&(w(""),w(` ${g.bold("Dry run. Nothing was sent.")} ${g.dim("Re-run with --apply to register.")}`)),j&&w("")}if(!e.apply)return 0;if(W.length===0)return console.log(`${s.dim}Nothing to write.${s.reset}`),0;if(!e.yes){const f=M(v);if(!await pt(`Register ${f.create} new and rotate ${f.rotate} existing fingerprint(s) for this org? [y/N]`))return console.log("Aborted."),0}console.log("");const T=await ft({rows:W,byKey:N,serverUrl:h,token:a,source:o,projectId:p?p.id:null}),I=T.filter(f=>!f.ok);return console.log(""),console.log(I.length===0?`${s.green}${T.length} fingerprint(s) registered.${s.reset}`:`${s.red}${I.length} of ${T.length} failed.${s.reset}`),q(R),j&&(w(""),B(I.length===0?"Done":"Finished with errors",["",...J([["Registered",`${T.length-I.length} of ${T.length}`],["Sent",`${z(T.sentBytes??0)} in ${T.requests??0} request${T.requests===1?"":"s"}`],["Secret values sent",g.green("0 B")],["Takes effect","in every connected browser within about a minute"]],{indent:0}),""],{tone:I.length===0?"green":"red",width:78})),console.log(""),I.length===0?0:1}const he=["create","rotate","conflict","skip","rejected"],ue=e=>{const t=he.indexOf(e);return t===-1?he.length:t};function jt({existing:e,plan:t,byKey:o}){const r=e.map(i=>({...i})),n=new Map(r.map(i=>[i.id,i]));for(const i of t){const h=o.get(i.key);if(!h)continue;const a=h.digests;if(i.action==="create"){r.push({id:`pending:${i.key}`,label:i.key,hmacHex:a.digest,length:a.length,hmacHexStripped:a.hmacHexStripped,lengthStripped:a.lengthStripped,hmacHexLower:a.hmacHexLower,lengthLower:a.lengthLower,scanPrefilter:a.scanPrefilter,tags:[]});continue}if(i.action==="rotate"){const c=n.get(i.id);if(!c)continue;c.hmacHex=a.digest,c.length=a.length,c.hmacHexStripped=a.hmacHexStripped,c.lengthStripped=a.lengthStripped,c.hmacHexLower=a.hmacHexLower,c.lengthLower=a.lengthLower,c.scanPrefilter=a.scanPrefilter}}return r}function Rt(){try{return ye(process.argv[1])}catch{return process.argv[1]}}const At=!!process.argv[1]&&import.meta.url===we(Rt()).href;At&&St().then(e=>process.exit(e)).catch(e=>{e instanceof m&&(console.error(`${s.red}${e.message}${s.reset}`),process.exit(2)),console.error(`${s.red}Fatal: ${e instanceof Error?e.message:e}${s.reset}`),process.exit(1)});export{Y as DEFAULT_MIN_LENGTH,st as decodeJwtPayload,et as diffAgainstServer,Ue as entriesFromJsonDocument,Ve as junkVerdict,Xe as normalizeSource,Fe as parseDotenv,Be as parseFlatYaml,oe as parseJsonSecrets,Me as scanBudgetForSecrets,O as sourceTag,it as tokenRoleProblem,ne as unwrapSecretsDocument};
@@ -1,2 +1,2 @@
1
- import{createHmac as R}from"node:crypto";import{createRequire as $}from"node:module";import{deriveKey as b}from"./redaktyn-fingerprint.mjs";import{SessionError as f,apiJson as m,readHidden as k}from"./redaktyn-session.mjs";import{box as P,k as n,rich as c,say as u,step as v}from"./redaktyn-ui.mjs";const H="vaultx-passphrase-verify-v1",A=3,r=e=>process.stderr.write(e+`
2
- `),_=$(import.meta.url);function T(e){try{const s=_("./redaktyn-shared.cjs");if(typeof s.validateNewPassphrase=="function")return s.validateNewPassphrase(e)}catch{}return e.length>=12?{ok:!0}:{ok:!1,error:"Passphrase must be at least 12 characters."}}async function D({server:e,token:s}){const o=await m(e,"GET","/api/org/passphrase-verifier",{token:s});if(!o.ok)return{state:"unknown"};const h=o.data?.verifier;return typeof h=="string"&&h.length>0?{state:"anchored",verifier:h}:{state:"none"}}async function E(e,s){const o=await b(e,s);return R("sha256",o).update(H,"utf8").digest("hex")}async function N(e,s,o){return s.state!=="anchored"?"unchecked":await E(e,o)===s.verifier?"ok":"wrong"}async function Y(e,{server:s,token:o,orgId:h}){const y=await E(e,h),w=await m(s,"PUT","/api/org/passphrase-verifier",{token:o,body:{verifier:y}});if(w.status===409)throw new f("This workspace already has a different passphrase, set a moment ago by someone else. Run this again and use that one.");return w.ok}async function F({server:e,token:s,orgId:o,who:h=null,label:y="Workspace passphrase",record:w=!0}){h&&(c?u(` ${n.green("\u2714")} ${h.replace(/^Signed in as /,"Signed in as ").replace(/\.$/,"")}`):r(h));const l=await D({server:e,token:s}),g=l.state==="none",p=process.env.REDAKTYN_PASSPHRASE,S=async t=>{if(!w){r(c?` ${n.dim("Dry run: this passphrase is accepted for the preview but not recorded. Run with --apply to set it.")}`:"Dry run: this passphrase is accepted for the preview but not recorded. Run with --apply to set it.");return}const a=v("Setting this as the workspace passphrase");await Y(t,{server:e,token:s,orgId:o})?a.succeed("Workspace passphrase set. Every device and the dashboard are now checked against it"):a.succeed("Passphrase accepted, but the server did not record it yet. It will be checked once it is"),r(c?` ${n.dim("Nobody can reset it for you. Set recovery codes in the dashboard if you have not.")}`:"Nobody can reset it for you. Set recovery codes in the dashboard if you have not.")};if(p){if(g){const i=T(p);if(!i.ok)throw new f(`This workspace has no passphrase yet, so REDAKTYN_PASSPHRASE would become it. ${i.error}`);return await S(p),p}const t=v("Checking the passphrase from REDAKTYN_PASSPHRASE"),a=await N(p,l,o);if(a==="wrong")throw t.fail("REDAKTYN_PASSPHRASE is not this workspace's passphrase"),new f("REDAKTYN_PASSPHRASE is not this workspace's passphrase.");return t.succeed(a==="ok"?"Passphrase from REDAKTYN_PASSPHRASE verified":"Passphrase from REDAKTYN_PASSPHRASE accepted. The server has nothing to check it against"),p}if(!process.stdin.isTTY)throw new f("Set REDAKTYN_PASSPHRASE. It is used locally to derive the key and is never sent.");if(g){const t=["This workspace has no passphrase yet, so what you type here becomes it.","It derives your keys on this machine and is never sent.","Nobody can reset it for you."];c?(u(""),P("Choose your workspace passphrase",t,{tone:"clay"}),u("")):(r(""),t.forEach(a=>r(a)));for(let a=A;a>0;a--){const i=await k(c?` ${n.clay("\u203A")} New passphrase ${n.dim("(hidden)")} `:"New passphrase > ");if(!i){r("Nothing was typed.");continue}const d=T(i);if(!d.ok){r(c?` ${n.amber("\u25B2")} ${d.error}`:d.error);continue}if(await k(c?` ${n.clay("\u203A")} Type it again ${n.dim("(hidden)")} `:"Type it again > ")!==i){r("Those two did not match. Nothing was set.");continue}return await S(i),i}throw new f("No passphrase was set after 3 tries. Nothing was changed.")}c?(u(""),P(y,["This derives your keys on this machine and is never sent,","never stored, and not shown while you type."],{tone:"clay"}),u("")):(r(""),r(`${y}: this derives the key on your machine and is never sent. Nothing shows while you type.`));for(let t=A;t>0;t--){const a=await k(c?` ${n.clay("\u203A")} Passphrase ${n.dim("(hidden)")} `:"Type it, then press Enter > ");if(!a){r("Nothing was typed.");continue}const i=v(c?"Checking it against your workspace":"Checking"),d=await N(a,l,o);if(d!=="wrong")return i.succeed(d==="ok"?"Passphrase verified. It matches your workspace":"Passphrase accepted. This workspace has nothing to check it against"),a;i.fail("That is not this workspace's passphrase"),r(c?t>1?` ${n.dim(`Try again (${t-1} left).`)}`:"":t>1?`That is not this workspace's passphrase. Try again (${t-1} left).`:"That is not this workspace's passphrase.")}throw new f("No correct passphrase after 3 tries. Nothing was changed.")}export{F as askWorkspacePassphrase};
1
+ import{createHmac as E}from"node:crypto";import{createRequire as N}from"node:module";import{createInterface as b}from"node:readline";import{deriveKey as $}from"./redaktyn-fingerprint.mjs";import{SessionError as d,apiJson as S,readHidden as D}from"./redaktyn-session.mjs";import{box as m,k as c,rich as i,say as f,step as k}from"./redaktyn-ui.mjs";const H="vaultx-passphrase-verify-v1",P=3,r=e=>process.stderr.write(e+`
2
+ `),Y=N(import.meta.url);function _(e){return new Promise(a=>{const s=b({input:process.stdin,output:process.stderr});s.question(e,o=>{s.close(),a(o)})})}function A(){let e=null;try{e=Y("./redaktyn-shared.cjs")}catch{}if(!e||typeof e.generateOrgPassphrase!="function"||typeof e.validateGeneratedPassphrase!="function")throw new d("This workspace has no passphrase yet, and this copy of the CLI cannot generate one. Reinstall it (npm install -g @redaktyn/cli@latest), or from a checkout rebuild shared, and run this again.");return e}async function K({server:e,token:a}){const s=await S(e,"GET","/api/org/passphrase-verifier",{token:a});if(!s.ok)return{state:"unknown"};const o=s.data?.verifier;return typeof o=="string"&&o.length>0?{state:"anchored",verifier:o}:{state:"none"}}async function T(e,a){const s=await $(e,a);return E("sha256",s).update(H,"utf8").digest("hex")}async function R(e,a,s){return a.state!=="anchored"?"unchecked":await T(e,s)===a.verifier?"ok":"wrong"}async function I(e,{server:a,token:s,orgId:o}){const w=await T(e,o),y=await S(a,"PUT","/api/org/passphrase-verifier",{token:s,body:{verifier:w}});if(y.status===409)throw new d("This workspace already has a different passphrase, set a moment ago by someone else. Run this again and use that one.");return y.ok}async function O({server:e,token:a,orgId:s,who:o=null,label:w="Workspace passphrase",record:y=!0}){o&&(i?f(` ${c.green("\u2714")} ${o.replace(/^Signed in as /,"Signed in as ").replace(/\.$/,"")}`):r(o));const l=await K({server:e,token:a}),v=l.state==="none",u=process.env.REDAKTYN_PASSPHRASE,g=async n=>{if(!y){r(i?` ${c.dim("Dry run: this passphrase is accepted for the preview but not recorded. Run with --apply to set it.")}`:"Dry run: this passphrase is accepted for the preview but not recorded. Run with --apply to set it.");return}const t=k("Setting this as the workspace passphrase");await I(n,{server:e,token:a,orgId:s})?t.succeed("Workspace passphrase set. Every device and the dashboard are now checked against it"):t.succeed("Passphrase accepted, but the server did not record it yet. It will be checked once it is"),r(i?` ${c.dim("Nobody can reset it for you. Set recovery codes in the dashboard if you have not.")}`:"Nobody can reset it for you. Set recovery codes in the dashboard if you have not.")};if(u){if(v){if(!A().validateGeneratedPassphrase(u).ok)throw new d("This workspace has no passphrase yet, so REDAKTYN_PASSPHRASE would become it, and a new workspace's passphrase has to be generated. Run this once in a terminal to get one, then set REDAKTYN_PASSPHRASE to it.");return await g(u),u}const n=k("Checking the passphrase from REDAKTYN_PASSPHRASE"),t=await R(u,l,s);if(t==="wrong")throw n.fail("REDAKTYN_PASSPHRASE is not this workspace's passphrase"),new d("REDAKTYN_PASSPHRASE is not this workspace's passphrase.");return n.succeed(t==="ok"?"Passphrase from REDAKTYN_PASSPHRASE verified":"Passphrase from REDAKTYN_PASSPHRASE accepted. The server has nothing to check it against"),u}if(!process.stdin.isTTY)throw new d("Set REDAKTYN_PASSPHRASE. It is used locally to derive the key and is never sent.");if(v){const t=A().generateOrgPassphrase();if(!y)return r(i?` ${c.dim("Dry run: this workspace has no passphrase yet. The preview uses a throwaway one. Run with --apply to generate the real one.")}`:"Dry run: this workspace has no passphrase yet. The preview uses a throwaway one. Run with --apply to generate the real one."),t;const h=["This workspace has no passphrase yet, so one was generated for you.","It derives your keys on this machine and is never sent.","Nobody can reset it for you.","",t,"","Save it in your password manager now.","It stays in this terminal's scrollback until you clear it."];i?(f(""),m("Your workspace passphrase",h,{tone:"clay"}),f("")):(r(""),h.forEach(p=>r(p)),r(""));for(let p=P;p>0;p--){if((await _(i?` ${c.clay("\u203A")} Type ${c.dim("saved")} once you have kept it `:"Type 'saved' once you have kept it > ")).trim().toLowerCase()==="saved")return await g(t),t;r("Not set yet. Save the passphrase above, then type: saved")}throw new d("No passphrase was set after 3 tries. Nothing was changed.")}i?(f(""),m(w,["This derives your keys on this machine and is never sent,","never stored, and not shown while you type."],{tone:"clay"}),f("")):(r(""),r(`${w}: this derives the key on your machine and is never sent. Nothing shows while you type.`));for(let n=P;n>0;n--){const t=await D(i?` ${c.clay("\u203A")} Passphrase ${c.dim("(hidden)")} `:"Type it, then press Enter > ");if(!t){r("Nothing was typed.");continue}const h=k(i?"Checking it against your workspace":"Checking"),p=await R(t,l,s);if(p!=="wrong")return h.succeed(p==="ok"?"Passphrase verified. It matches your workspace":"Passphrase accepted. This workspace has nothing to check it against"),t;h.fail("That is not this workspace's passphrase"),r(i?n>1?` ${c.dim(`Try again (${n-1} left).`)}`:"":n>1?`That is not this workspace's passphrase. Try again (${n-1} left).`:"That is not this workspace's passphrase.")}throw new d("No correct passphrase after 3 tries. Nothing was changed.")}export{O as askWorkspacePassphrase};
@@ -1,7 +1,9 @@
1
- "use strict";var oe=Object.defineProperty;var wt=Object.getOwnPropertyDescriptor;var Rt=Object.getOwnPropertyNames;var Tt=Object.prototype.hasOwnProperty;var Ct=(e,t)=>{for(var n in t)oe(e,n,{get:t[n],enumerable:!0})},Pt=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Rt(t))!Tt.call(e,o)&&o!==n&&oe(e,o,{get:()=>t[o],enumerable:!(a=wt(t,o))||a.enumerable});return e};var _t=e=>Pt(oe({},"__esModule",{value:!0}),e);var ln={};Ct(ln,{AIToolCategory:()=>ae,AI_REGISTRY:()=>Y,ANNUAL_MONTHS_FREE:()=>Ft,ASSIGNED_SECRET_SLUG:()=>Xr,AlertChannel:()=>_e,AlertTrigger:()=>Ue,CATEGORISED_SLUGS:()=>sn,COVERAGE_SLUGS:()=>kt,DETECTION_CATEGORIES:()=>we,DETECTION_FAMILY_BLURBS:()=>en,DETECTION_FAMILY_NAMES:()=>St,DETECTION_PROOF_NAMES:()=>tn,DETECTION_UNIVERSAL_IGNORES:()=>rn,DIGEST_VERSION_HMAC_V1:()=>ur,ENTERPRISE_FEATURES:()=>pe,EventAction:()=>Te,EventType:()=>He,FREE_FEATURES:()=>le,FREE_SEATS:()=>ce,INVISIBLE_CHARS_CLASS:()=>tt,KDF_ITERATIONS:()=>gr,KDF_VERSION_V2:()=>mr,MATRIX_TIERS:()=>zt,MAX_ACTIVITY_SESSIONS_PER_BATCH:()=>ro,MAX_SCAN_WINDOWS:()=>ne,MAX_TOTAL_SCAN_CHARS:()=>W,MIN_SECRET_LENGTH:()=>pr,NORMALIZATION_VERSION_V1:()=>hr,NORMALIZATION_VERSION_V2:()=>fr,OrgPlan:()=>Pe,PASSPHRASE_VERIFY_LABEL:()=>nt,PASTE_CEILING_ALARM_CHARS:()=>xt,PASTE_CEILING_WARN_CHARS:()=>yt,PLAN_DESCRIPTORS:()=>jt,PLAN_FEATURE_MATRIX:()=>Yt,PLAN_FEATURE_TIERS:()=>Kt,PLAN_LIMITS:()=>Le,PLAN_PRICING:()=>Nt,PRIVACY_EMAIL:()=>Jt,PROJECT_KDF_LABEL:()=>rt,PRO_BANDS:()=>m,PRO_ENTRY_BAND:()=>A,PRO_FEATURES:()=>de,PRO_TOP_BAND:()=>Ot,RiskLevel:()=>se,SAFE_BLOCK_EVENT_FIELDS:()=>Ut,SALES_EMAIL:()=>$t,SCAN_PREFILTER_LABEL:()=>lt,SCAN_PREFILTER_PATTERN:()=>ut,SCAN_PREFILTER_SPACE:()=>Ie,SCAN_PREFILTER_WINDOWS_PER_SIGNATURE:()=>bt,SECRET_PROVIDER_NAMES:()=>De,SECRET_PROVIDER_SLUGS:()=>It,SECURITY_EMAIL:()=>qt,TRIAL_DAYS:()=>Wt,UNRECOGNISED_PROVIDER_SLUG:()=>V,UserRole:()=>Ce,annualBilledNote:()=>Oe,appendPasskeyEnvelope:()=>Br,behaviorExplanation:()=>vt,canonicalSecretPlaintextForHmac:()=>X,categoryOfSlug:()=>nn,computePassphraseVerifyHmac:()=>Mr,customPolicyDomains:()=>cn,decodeScanPrefilter:()=>ke,deriveBehaviorRisk:()=>Ht,deriveHmacKeyFromPassphrase:()=>Ar,deriveProjectKey:()=>kr,deriveScanPrefilterSeed:()=>ft,encodeScanPrefilter:()=>Et,extractAddedLinesFromUnifiedDiff:()=>Vr,familyDisplayName:()=>an,familyOfSlug:()=>Mt,findBand:()=>Gt,findPasskeyEnvelope:()=>Wr,foldUuidHexCase:()=>N,generateHmacKey:()=>Dr,generatePrfSalt:()=>Lr,getInjectionHostnames:()=>Be,getLimitsForPlan:()=>Lt,getPrfSaltBytes:()=>Gr,hexToKey:()=>Rr,hmacDigestHex:()=>Q,isAIToolDomain:()=>Zt,isInjectionScopedHostname:()=>he,isKnownProviderSlug:()=>Zr,isProtectableSlug:()=>on,isV1PassphraseEnvelope:()=>st,isV2Envelope:()=>at,keyToHex:()=>wr,matchDomain:()=>Ge,matchPatternsForHostname:()=>tr,maxScannablePasteChars:()=>qr,maxScannablePasteCharsFor:()=>re,normalizeAndHmacHex:()=>xr,normalizeAndHmacHexCollapsed:()=>br,normalizeAndHmacHexLower:()=>yr,normalizeDomainInput:()=>fe,normalizeSecretPlaintextCollapsed:()=>G,normalizeSecretPlaintextForMatch:()=>be,normalizeSecretPlaintextLower:()=>Z,perMonthOnAnnual:()=>Vt,policyNamedDomains:()=>Dt,projectedScanCost:()=>Me,providerDisplayName:()=>Qr,removePasskeyEnvelope:()=>Fr,scanBudgetFor:()=>Jr,scanPrefilterFingerprint:()=>te,scanPrefilterForRawSecret:()=>jr,scanPrefilterParams:()=>ht,scanPrefilterRoller:()=>Yr,scanPrefilterUnits:()=>mt,scanSweeps:()=>Se,scanWindowLengths:()=>$r,smallestBandFor:()=>Bt,unwrapHmacKeyWithPrf:()=>Nr,upgradeEnvelopeToV2:()=>Ur,usd:()=>C,validateNewPassphrase:()=>_r,validatePassphraseStrength:()=>ot,wrapHmacKeyWithPrf:()=>Or});module.exports=_t(ln);var ae=(c=>(c.CODE_GEN="CODE_GEN",c.IMAGE_GEN="IMAGE_GEN",c.WRITING="WRITING",c.DATA_ANALYSIS="DATA_ANALYSIS",c.CHATBOT="CHATBOT",c.SEARCH="SEARCH",c.OTHER="OTHER",c))(ae||{}),se=(o=>(o.LOW="LOW",o.MEDIUM="MEDIUM",o.HIGH="HIGH",o.CRITICAL="CRITICAL",o))(se||{}),Te=(n=>(n.BLOCKED="BLOCKED",n.LOGGED="LOGGED",n))(Te||{}),Ce=(o=>(o.OWNER="OWNER",o.ADMIN="ADMIN",o.USER="USER",o.VIEWER="VIEWER",o))(Ce||{}),Pe=(a=>(a.FREE="FREE",a.PRO="PRO",a.ENTERPRISE="ENTERPRISE",a))(Pe||{}),_e=(n=>(n.EMAIL="EMAIL",n.WEBHOOK="WEBHOOK",n))(_e||{}),Ue=(a=>(a.CRITICAL_BLOCK="CRITICAL_BLOCK",a.DAILY_SUMMARY="DAILY_SUMMARY",a.WEEKLY_REPORT="WEEKLY_REPORT",a))(Ue||{}),He=(o=>(o.PASTE="PASTE",o.FILE_UPLOAD="FILE_UPLOAD",o.PASTE_REDACTED="PASTE_REDACTED",o.DETECTED="DETECTED",o))(He||{}),Ut=["event","type","secretLabel","secretLabels","attemptCount","risk","toolDomain","sourceUrl","timestamp","eventType","scanMethod","scanMs","hmacBatches","secretIds","matchReason","matchReasonSource","bypassVariant","incidentId","detectedAt","policyAction"];function Ht(e){return e<=1?"low":e===2?"medium":"high"}function vt(e){return e<=1?"User likely made an accidental paste.":e===2?"User may not be aware this is sensitive.":"Repeated attempts detected \u2014 potential risk."}var _={maxUsers:5,maxInviteCodes:5,alerts:["EMAIL"],customDetection:!1,advancedReports:!1,exportReports:!1,siem:!1,sso:!1},ie={maxUsers:200,maxInviteCodes:200,alerts:["EMAIL","WEBHOOK"],customDetection:!0,advancedReports:!0,exportReports:!1,siem:!1,sso:!1},ve={maxUsers:9999,maxInviteCodes:9999,alerts:["EMAIL","WEBHOOK"],customDetection:!0,advancedReports:!0,exportReports:!0,siem:!0,sso:!0},Le={FREE:_,PRO:ie,ENTERPRISE:ve};function Lt(e){return Le[e]??_}var ce=_.maxUsers,m=[{id:"team15",name:"Team",maxUsers:15,monthlyUsd:39,annualUsd:390},{id:"growth30",name:"Growth",maxUsers:30,monthlyUsd:79,annualUsd:790},{id:"business75",name:"Business",maxUsers:75,monthlyUsd:149,annualUsd:1490},{id:"scale200",name:"Scale",maxUsers:200,monthlyUsd:349,annualUsd:3490}],un=m[m.length-1].maxUsers,A=m[0],Ot=m[m.length-1],Nt={PRO:{monthlyUsd:A.monthlyUsd,annualUsd:A.annualUsd}};function Gt(e){return m.find(t=>t.id===e)}function Bt(e){return m.find(t=>t.maxUsers>=e)}var Ft=2,Wt=14;function C(e){return`$${Number.isInteger(e)?e.toLocaleString("en-US"):e.toFixed(2)}`}function Vt(e){return C(e/12)}function Oe(e,t){return`${C(t)} billed yearly \xB7 save ${C(e*12-t)}`}var le=["The full detection engine \u2014 paste, send, typed input, drag and file upload","Chrome, Edge and Safari","Bypass detection \u2014 whitespace injection and case folding","Unregistered-secret suggestions \u2014 spots keys nobody registered, admin opt-in, never a block","Zero-knowledge by construction: only HMAC digests leave the device",`Up to ${ce} monitored users`,`${_.maxInviteCodes} invite codes`,"Email alerts","30-day compliance history","Community support"],de=[`Pick your team's size \u2014 ${m.map(e=>`${e.name} to ${e.maxUsers} people, ${C(e.monthlyUsd)}/mo`).join("; ")}`,"Everyone inside your size is covered; no per-seat metering or proration between invites","As many unused invite links as your size has seats","Webhook alerts alongside email","Domain policies \u2014 add any site, beyond the built-in AI tools, to the places Redaktyn blocks","365-day compliance history","Priority support"],pe=["Custom seat limits, agreed rather than published","CSV export of the full event log","SIEM webhook delivery","SSO \u2014 SAML and OIDC","Dedicated support"],Kt=[{key:"FREE",name:"Free",features:le},{key:"PRO",name:"Pro",features:de},{key:"ENTERPRISE",name:"Enterprise",features:pe}],zt=[{key:"FREE",name:"Free",price:"$0"},{key:"PRO",name:"Pro",price:`From ${C(A.monthlyUsd)}/mo`},{key:"ENTERPRISE",name:"Enterprise",price:"Contact us"}],Yt=[{section:"Limits",rows:[{label:"People covered",note:`Pro is bought in ${m.length} sizes, up to ${m.map(e=>e.maxUsers).join(", ")} people \u2014 the figure here is the largest; a workspace's own limit is the size it bought.`,gate:"maxUsers",values:{FREE:String(ce),PRO:"200",ENTERPRISE:"Custom"}},{label:"Invite codes",note:"Unused links held at once. A link is spent when a browser connects and takes a seat, so on Pro this is the size you bought.",gate:"maxInviteCodes",values:{FREE:String(_.maxInviteCodes),PRO:String(ie.maxInviteCodes),ENTERPRISE:"Unlimited"}},{label:"Compliance history",note:"How far back a compliance report may be run. Event data itself is not deleted on any plan.",gate:"advancedReports",values:{FREE:"30 days",PRO:"365 days",ENTERPRISE:"365 days"}}]},{section:"Detection and blocking",rows:[{label:"Paste, send, typed input, drag and file upload",note:"All six enforcement paths, on every plan. Detection has never been plan-gated and is the last thing that should be.",ungated:"No plan check exists on any enforcement path in the extension.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Chrome, Edge and Safari",ungated:"The extension reports its browser; no route reads a plan before accepting the heartbeat.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Bypass detection \u2014 whitespace injection, case folding",ungated:"Runs inside the same scan as the direct match; there is no flag to turn it off.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Detection engine \u2014 50 categories nobody registered",note:"Credentials, infrastructure files and personal data, each proven by a checksum, a decoded structure or the provider's format. On by default; suggests, never blocks.",ungated:"The org switch is an admin setting with no plan check, and the extension's resolver reads only that switch.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Personal-data detection \u2014 cards, Aadhaar, PAN, SSN, IBAN",note:"Checksum-verified and labelled, offered for removal only. Its own switch, on by default.",ungated:"The personal-data switch is an admin setting with no plan check; the resolver passes it straight to the engine.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Unprotected-secret counts by category",note:"A daily count per category on the dashboard \u2014 never a value, a fingerprint or a name.",ungated:"The coverage route checks the org's reporting switch and the enrolment, never the plan.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Custom domain policies",note:"Add a site that is not one of the built-in AI tools to the places Redaktyn blocks. Older warn and log policies keep working.",gate:"customDetection",values:{FREE:!1,PRO:!0,ENTERPRISE:!0}}]},{section:"Alerting and reporting",rows:[{label:"Email alerts",ungated:"EMAIL is in every plan's channel list, so the row is true by construction.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Webhook alerts",gate:"alerts",channel:"WEBHOOK",values:{FREE:!1,PRO:!0,ENTERPRISE:!0}},{label:"Executive PDF report",note:"Emailed every Monday, and downloadable at any time from Reports.",gate:"advancedReports",values:{FREE:!1,PRO:!0,ENTERPRISE:!0}},{label:"CSV export of the event log",gate:"exportReports",values:{FREE:!1,PRO:!1,ENTERPRISE:!0}},{label:"SIEM webhook delivery",gate:"siem",values:{FREE:!1,PRO:!1,ENTERPRISE:!0}}]},{section:"Access and support",rows:[{label:"SSO \u2014 SAML and OIDC",gate:"sso",values:{FREE:!1,PRO:!1,ENTERPRISE:!0}},{label:"Support",note:"A commitment from people, not a switch in the code \u2014 which is why no flag backs this row.",ungated:"Support tiering is contractual; no route reads a plan to answer a support request.",values:{FREE:"Community",PRO:"Priority",ENTERPRISE:"Dedicated"}}]}],jt=[{id:"FREE",name:"Free",tagline:"The whole detection engine, for a team that is still proving it works",priceMonthly:0,priceLabel:"$0",priceNote:"Forever free \xB7 no card",limits:_,features:le,featuresHeading:"What's included",highlighted:!1,cta:"Get started"},{id:"PRO",name:"Pro",tagline:"For a team that has to answer questions about its own exposure",priceMonthly:A.monthlyUsd,priceLabel:C(A.monthlyUsd),priceNote:`per month \xB7 up to ${A.maxUsers} people`,annualNote:Oe(A.monthlyUsd,A.annualUsd),limits:ie,features:de,featuresHeading:"Everything in Free, plus",highlighted:!0,cta:"Start free, then upgrade"},{id:"ENTERPRISE",name:"Enterprise",tagline:"For satisfying somebody else's auditor or IT department",priceMonthly:null,priceLabel:"Custom",priceNote:"Contact sales",limits:ve,features:pe,featuresHeading:"Everything in Pro, plus",highlighted:!1,cta:"Contact sales"}],Ne="ak8340651733@gmail.com",$t=Ne,qt=Ne,Jt="support@redaktyn.com";function r(e,t,n,a="MEDIUM",o={}){return{domain:e,name:t,category:n,riskLevel:a,isEnterprise:o.isEnterprise??!1,...o.personalVersionDomain?{personalVersionDomain:o.personalVersionDomain}:{}}}var Y=[r("chat.openai.com","ChatGPT","CODE_GEN","HIGH"),r("chatgpt.com","ChatGPT","CODE_GEN","HIGH"),r("platform.openai.com","OpenAI Platform","CODE_GEN","HIGH"),r("claude.ai","Claude","CODE_GEN","HIGH"),r("gemini.google.com","Gemini","CODE_GEN","MEDIUM"),r("aistudio.google.com","Google AI Studio","CODE_GEN","MEDIUM"),r("copilot.github.com","GitHub Copilot","CODE_GEN","MEDIUM"),r("github.com/copilot","GitHub Copilot Chat","CODE_GEN","MEDIUM"),r("cursor.sh","Cursor","CODE_GEN","MEDIUM"),r("cursor.com","Cursor","CODE_GEN","MEDIUM"),r("replit.com","Replit","CODE_GEN","HIGH"),r("codeium.com","Codeium","CODE_GEN","MEDIUM"),r("tabnine.com","Tabnine","CODE_GEN","MEDIUM"),r("codewhisperer.aws","Amazon CodeWhisperer","CODE_GEN","LOW",{isEnterprise:!0}),r("aws.amazon.com/codewhisperer","Amazon CodeWhisperer","CODE_GEN","LOW",{isEnterprise:!0}),r("phind.com","Phind","CODE_GEN","MEDIUM"),r("continue.dev","Continue","CODE_GEN","MEDIUM"),r("askcodi.com","AskCodi","CODE_GEN","MEDIUM"),r("sourcegraph.com","Sourcegraph Cody","CODE_GEN","MEDIUM"),r("windsurf.ai","Windsurf","CODE_GEN","MEDIUM"),r("v0.dev","Vercel v0","CODE_GEN","MEDIUM"),r("bolt.new","Bolt","CODE_GEN","HIGH"),r("lovable.dev","Lovable","CODE_GEN","HIGH"),r("aider.chat","Aider","CODE_GEN","MEDIUM"),r("cody.dev","Cody","CODE_GEN","MEDIUM"),r("blackbox.ai","Blackbox AI","CODE_GEN","HIGH"),r("deepcode.ai","DeepCode","CODE_GEN","MEDIUM"),r("codiga.io","Codiga","CODE_GEN","MEDIUM"),r("mutable.ai","Mutable AI","CODE_GEN","MEDIUM"),r("pieces.app","Pieces","CODE_GEN","MEDIUM"),r("codium.ai","CodiumAI","CODE_GEN","MEDIUM"),r("coderabbit.ai","CodeRabbit","CODE_GEN","MEDIUM"),r("devin.ai","Devin","CODE_GEN","HIGH"),r("idx.dev","Project IDX","CODE_GEN","MEDIUM"),r("stackblitz.com","StackBlitz","CODE_GEN","MEDIUM"),r("codepen.io","CodePen AI","CODE_GEN","MEDIUM"),r("codesandbox.io","CodeSandbox AI","CODE_GEN","MEDIUM"),r("gitpod.io","Gitpod","CODE_GEN","MEDIUM"),r("poe.com","Poe","CHATBOT","MEDIUM"),r("character.ai","Character.AI","CHATBOT","MEDIUM"),r("beta.character.ai","Character.AI Beta","CHATBOT","MEDIUM"),r("huggingface.co/chat","HuggingChat","CHATBOT","MEDIUM"),r("pi.ai","Pi","CHATBOT","LOW"),r("chat.mistral.ai","Mistral Chat","CHATBOT","MEDIUM"),r("chat.deepseek.com","DeepSeek Chat","CHATBOT","HIGH"),r("deepseek.com","DeepSeek","CHATBOT","HIGH"),r("groq.com","Groq","CHATBOT","MEDIUM"),r("console.groq.com","Groq Console","CHATBOT","MEDIUM"),r("cohere.com","Cohere","CHATBOT","MEDIUM"),r("coral.cohere.com","Cohere Coral","CHATBOT","MEDIUM"),r("inflection.ai","Inflection","CHATBOT","MEDIUM"),r("chat.lmsys.org","LMSYS Chatbot Arena","CHATBOT","HIGH"),r("open-assistant.io","Open Assistant","CHATBOT","MEDIUM"),r("bard.google.com","Google Bard","CHATBOT","MEDIUM"),r("copilot.microsoft.com","Microsoft Copilot","CHATBOT","LOW",{isEnterprise:!0}),r("bing.com/chat","Bing Chat","CHATBOT","MEDIUM"),r("meta.ai","Meta AI","CHATBOT","MEDIUM"),r("labs.perplexity.ai","Perplexity Labs","CHATBOT","MEDIUM"),r("together.ai","Together AI","CHATBOT","MEDIUM"),r("api.together.xyz","Together API","CHATBOT","MEDIUM"),r("fireworks.ai","Fireworks AI","CHATBOT","MEDIUM"),r("anyscale.com","Anyscale","CHATBOT","MEDIUM"),r("replicate.com","Replicate","CHATBOT","MEDIUM"),r("lepton.ai","Lepton AI","CHATBOT","MEDIUM"),r("forefront.ai","Forefront","CHATBOT","MEDIUM"),r("chat.vercel.ai","Vercel AI Chat","CHATBOT","MEDIUM"),r("llama.meta.com","Llama","CHATBOT","MEDIUM"),r("grok.com","Grok","CHATBOT","HIGH"),r("grok.x.ai","Grok","CHATBOT","MEDIUM"),r("x.ai","xAI","CHATBOT","MEDIUM"),r("duckduckgo.com/aichat","DuckDuckGo AI Chat","CHATBOT","LOW"),r("chatglm.cn","ChatGLM","CHATBOT","HIGH"),r("yiyan.baidu.com","Ernie Bot","CHATBOT","HIGH"),r("qianwen.aliyun.com","Qwen","CHATBOT","HIGH"),r("abacus.ai","Abacus AI","CHATBOT","MEDIUM"),r("midjourney.com","Midjourney","IMAGE_GEN","MEDIUM"),r("discord.com/channels/midjourney","Midjourney Discord","IMAGE_GEN","MEDIUM"),r("openai.com/dall-e","DALL-E","IMAGE_GEN","MEDIUM"),r("labs.openai.com","DALL-E Labs","IMAGE_GEN","MEDIUM"),r("stability.ai","Stable Diffusion","IMAGE_GEN","MEDIUM"),r("dreamstudio.ai","DreamStudio","IMAGE_GEN","MEDIUM"),r("leonardo.ai","Leonardo.ai","IMAGE_GEN","MEDIUM"),r("app.leonardo.ai","Leonardo.ai App","IMAGE_GEN","MEDIUM"),r("ideogram.ai","Ideogram","IMAGE_GEN","MEDIUM"),r("firefly.adobe.com","Adobe Firefly","IMAGE_GEN","LOW",{isEnterprise:!0}),r("clipdrop.co","ClipDrop","IMAGE_GEN","MEDIUM"),r("playground.ai","Playground AI","IMAGE_GEN","MEDIUM"),r("nightcafe.studio","NightCafe","IMAGE_GEN","MEDIUM"),r("creator.nightcafe.studio","NightCafe Creator","IMAGE_GEN","MEDIUM"),r("runwayml.com","Runway","IMAGE_GEN","MEDIUM"),r("app.runwayml.com","Runway App","IMAGE_GEN","MEDIUM"),r("canva.com/ai-image-generator","Canva AI","IMAGE_GEN","LOW"),r("imagine.meta.com","Meta Imagine","IMAGE_GEN","MEDIUM"),r("pika.art","Pika","IMAGE_GEN","MEDIUM"),r("kaiber.ai","Kaiber","IMAGE_GEN","MEDIUM"),r("bing.com/images/create","Bing Image Creator","IMAGE_GEN","MEDIUM"),r("designer.microsoft.com","Microsoft Designer","IMAGE_GEN","MEDIUM"),r("craiyon.com","Craiyon","IMAGE_GEN","LOW"),r("starryai.com","StarryAI","IMAGE_GEN","LOW"),r("hotpot.ai","Hotpot AI","IMAGE_GEN","LOW"),r("lexica.art","Lexica","IMAGE_GEN","LOW"),r("jasper.ai","Jasper","WRITING","MEDIUM"),r("app.jasper.ai","Jasper App","WRITING","MEDIUM"),r("copy.ai","Copy.ai","WRITING","MEDIUM"),r("app.copy.ai","Copy.ai App","WRITING","MEDIUM"),r("writesonic.com","Writesonic","WRITING","MEDIUM"),r("app.writesonic.com","Writesonic App","WRITING","MEDIUM"),r("grammarly.com","Grammarly AI","WRITING","MEDIUM"),r("app.grammarly.com","Grammarly App","WRITING","MEDIUM"),r("notion.so","Notion AI","WRITING","MEDIUM"),r("quillbot.com","QuillBot","WRITING","MEDIUM"),r("wordtune.com","Wordtune","WRITING","MEDIUM"),r("rytr.me","Rytr","WRITING","MEDIUM"),r("anyword.com","Anyword","WRITING","MEDIUM"),r("hyperwriteai.com","HyperWrite","WRITING","MEDIUM"),r("writer.com","Writer","WRITING","MEDIUM",{isEnterprise:!0}),r("textcortex.com","TextCortex","WRITING","MEDIUM"),r("app.textcortex.com","TextCortex App","WRITING","MEDIUM"),r("peppertype.ai","Peppertype","WRITING","MEDIUM"),r("simplified.com","Simplified AI","WRITING","MEDIUM"),r("contentbot.ai","ContentBot","WRITING","MEDIUM"),r("ink.co","INK Editor","WRITING","MEDIUM"),r("sudowrite.com","Sudowrite","WRITING","MEDIUM"),r("novelai.net","NovelAI","WRITING","LOW"),r("shortlyai.com","ShortlyAI","WRITING","MEDIUM"),r("lex.page","Lex","WRITING","MEDIUM"),r("julius.ai","Julius","DATA_ANALYSIS","HIGH"),r("hex.tech","Hex","DATA_ANALYSIS","HIGH"),r("app.hex.tech","Hex App","DATA_ANALYSIS","HIGH"),r("obviously.ai","Obviously AI","DATA_ANALYSIS","HIGH"),r("akkio.com","Akkio","DATA_ANALYSIS","HIGH"),r("monkeylearn.com","MonkeyLearn","DATA_ANALYSIS","HIGH"),r("rows.com","Rows","DATA_ANALYSIS","MEDIUM"),r("breadcrumbs.io","Breadcrumbs","DATA_ANALYSIS","MEDIUM"),r("polymer.co","Polymer","DATA_ANALYSIS","HIGH"),r("databricks.com","Databricks AI","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("datarobot.com","DataRobot","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("h2o.ai","H2O.ai","DATA_ANALYSIS","MEDIUM"),r("rapidminer.com","RapidMiner","DATA_ANALYSIS","MEDIUM"),r("knime.com","KNIME","DATA_ANALYSIS","MEDIUM"),r("alteryx.com","Alteryx","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("tableau.com","Tableau AI","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("mode.com","Mode Analytics","DATA_ANALYSIS","MEDIUM"),r("deepnote.com","Deepnote","DATA_ANALYSIS","HIGH"),r("observable.com","Observable","DATA_ANALYSIS","MEDIUM"),r("noteable.io","Noteable","DATA_ANALYSIS","HIGH"),r("perplexity.ai","Perplexity Search","SEARCH","MEDIUM"),r("you.com","You.com Search","SEARCH","MEDIUM"),r("andi.ai","Andi","SEARCH","LOW"),r("kagi.com","Kagi","SEARCH","LOW"),r("metaphor.systems","Metaphor","SEARCH","MEDIUM"),r("exa.ai","Exa","SEARCH","MEDIUM"),r("tavily.com","Tavily","SEARCH","MEDIUM"),r("consensus.app","Consensus","SEARCH","LOW"),r("elicit.com","Elicit","SEARCH","MEDIUM"),r("elicit.org","Elicit","SEARCH","MEDIUM"),r("searchgpt.com","SearchGPT","SEARCH","MEDIUM"),r("brave.com/search/ai","Brave AI Search","SEARCH","LOW"),r("neeva.com","Neeva","SEARCH","LOW"),r("socratic.org","Socratic","SEARCH","LOW"),r("devv.ai","Devv AI","SEARCH","MEDIUM"),r("iask.ai","iAsk AI","SEARCH","LOW"),r("chatpdf.com","ChatPDF","SEARCH","MEDIUM"),r("smodin.io","Smodin","WRITING","MEDIUM"),r("ai-writer.com","AI Writer","WRITING","MEDIUM"),r("scalenut.com","Scalenut","WRITING","MEDIUM"),r("closerscopy.com","ClosersCopy","WRITING","MEDIUM"),r("longshot.ai","LongShot AI","WRITING","MEDIUM"),r("fig.io","Fig AI","CODE_GEN","MEDIUM"),r("warp.dev","Warp Terminal AI","CODE_GEN","MEDIUM"),r("raycast.com","Raycast AI","CODE_GEN","MEDIUM"),r("app.codeanywhere.com","Codeanywhere AI","CODE_GEN","MEDIUM"),r("zed.dev","Zed AI","CODE_GEN","MEDIUM"),r("gencraft.com","Gencraft","IMAGE_GEN","LOW"),r("deepai.org","DeepAI","IMAGE_GEN","LOW"),r("artbreeder.com","Artbreeder","IMAGE_GEN","LOW"),r("fotor.com/ai","Fotor AI","IMAGE_GEN","LOW"),r("remove.bg","Remove.bg","IMAGE_GEN","LOW"),r("photoroom.com","PhotoRoom AI","IMAGE_GEN","LOW"),r("app.recraft.ai","Recraft AI","IMAGE_GEN","MEDIUM"),r("pecan.ai","Pecan AI","DATA_ANALYSIS","HIGH"),r("apteo.co","Apteo","DATA_ANALYSIS","HIGH"),r("mindsdb.com","MindsDB","DATA_ANALYSIS","MEDIUM"),r("zapier.com/ai","Zapier AI","OTHER","MEDIUM"),r("make.com","Make (Integromat) AI","OTHER","MEDIUM"),r("otter.ai","Otter.ai","OTHER","HIGH"),r("fireflies.ai","Fireflies.ai","OTHER","HIGH"),r("descript.com","Descript","OTHER","MEDIUM"),r("synthesia.io","Synthesia","OTHER","MEDIUM"),r("elevenlabs.io","ElevenLabs","OTHER","MEDIUM"),r("murf.ai","Murf AI","OTHER","MEDIUM"),r("resemble.ai","Resemble AI","OTHER","MEDIUM"),r("loom.com","Loom AI","OTHER","MEDIUM"),r("beautiful.ai","Beautiful.ai","OTHER","LOW"),r("gamma.app","Gamma","OTHER","MEDIUM"),r("tome.app","Tome","OTHER","MEDIUM"),r("magician.design","Magician","OTHER","MEDIUM"),r("uizard.io","Uizard","OTHER","MEDIUM"),r("huggingface.co/spaces","HuggingFace Spaces","OTHER","MEDIUM"),r("roboflow.com","Roboflow","OTHER","MEDIUM"),r("scale.com","Scale AI","OTHER","MEDIUM"),r("labelbox.com","Labelbox","OTHER","MEDIUM")],gn=new Set(Y.map(e=>e.domain.toLowerCase())),O=new Map;for(let e of Y){let t=e.domain.toLowerCase();O.has(t)||O.set(t,e)}function Xt(e){try{return e.includes("://")||(e="https://"+e),new URL(e).hostname.toLowerCase()}catch{return null}}function Ge(e){let t=Xt(e);if(!t)return null;let n=O.get(t);if(n)return n;try{let o=new URL(e.includes("://")?e:"https://"+e),s=(o.hostname+o.pathname).toLowerCase().replace(/\/+$/,""),i=O.get(s);if(i)return i}catch{}let a=t.split(".");for(let o=1;o<a.length-1;o++){let s=a.slice(o).join("."),i=O.get(s);if(i)return i}return null}function Zt(e){return Ge(e)!==null}var Qt=new Set(["replit.com","sourcegraph.com","idx.dev","stackblitz.com","codepen.io","codesandbox.io","gitpod.io","fig.io","warp.dev","raycast.com","app.codeanywhere.com","zed.dev","anyscale.com","grammarly.com","notion.so","hex.tech","app.hex.tech","rows.com","breadcrumbs.io","databricks.com","datarobot.com","h2o.ai","rapidminer.com","knime.com","alteryx.com","tableau.com","mode.com","deepnote.com","observable.com","noteable.io","mindsdb.com","kagi.com","make.com","loom.com","roboflow.com","scale.com","labelbox.com"]),er=["redaktyn.com"];function Be(){let e=new Set;for(let t of Y){let n=t.domain.toLowerCase();n.includes("/")||Qt.has(n)||e.add(n)}for(let t of er)e.add(t.toLowerCase());return Array.from(e).sort()}var ue=null;function he(e){ue||(ue=new Set(Be()));let t=e.toLowerCase();for(let n of ue)if(t===n||t.endsWith(`.${n}`))return!0;return!1}function tr(e){let t=e.toLowerCase();return[`*://${t}/*`,`*://*.${t}/*`]}function fe(e){let t=e.trim().toLowerCase();return!t||(t=t.replace(/^[a-z][a-z0-9+.-]*:\/\//,""),t=t.split(/[/?#]/)[0],t=t.split("@").pop(),t=t.split(":")[0],!/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/.test(t))?null:t}function rr(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function M(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("positive integer expected, got "+e)}function D(e,...t){if(!rr(e))throw new Error("Uint8Array expected");if(t.length>0&&!t.includes(e.length))throw new Error("Uint8Array expected of length "+t+", got length="+e.length)}function P(e){if(typeof e!="function"||typeof e.create!="function")throw new Error("Hash should be wrapped by utils.createHasher");M(e.outputLen),M(e.blockLen)}function H(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function We(e,t){D(e);let n=t.outputLen;if(e.length<n)throw new Error("digestInto() expects output buffer of length at least "+n)}function g(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function v(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function E(e,t){return e<<32-t|e>>>t}var Ve=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",nr=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function j(e){if(D(e),Ve)return e.toHex();let t="";for(let n=0;n<e.length;n++)t+=nr[e[n]];return t}var I={_0:48,_9:57,A:65,F:70,a:97,f:102};function Fe(e){if(e>=I._0&&e<=I._9)return e-I._0;if(e>=I.A&&e<=I.F)return e-(I.A-10);if(e>=I.a&&e<=I.f)return e-(I.a-10)}function Ke(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if(Ve)return Uint8Array.fromHex(e);let t=e.length,n=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);let a=new Uint8Array(n);for(let o=0,s=0;o<n;o++,s+=2){let i=Fe(e.charCodeAt(s)),c=Fe(e.charCodeAt(s+1));if(i===void 0||c===void 0){let d=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+d+'" at index '+s)}a[o]=i*16+c}return a}var or=async()=>{};async function ze(e,t,n){let a=Date.now();for(let o=0;o<e;o++){n(o);let s=Date.now()-a;s>=0&&s<t||(await or(),a+=s)}}function b(e){if(typeof e!="string")throw new Error("string expected");return new Uint8Array(new TextEncoder().encode(e))}function w(e){return typeof e=="string"&&(e=b(e)),D(e),e}function me(e){return typeof e=="string"&&(e=b(e)),D(e),e}function Ye(e,t){if(t!==void 0&&{}.toString.call(t)!=="[object Object]")throw new Error("options should be object or undefined");return Object.assign(e,t)}var U=class{};function je(e){let t=a=>e().update(w(a)).digest(),n=e();return t.outputLen=n.outputLen,t.blockLen=n.blockLen,t.create=()=>e(),t}var $=class extends U{constructor(t,n){super(),this.finished=!1,this.destroyed=!1,P(t);let a=w(n);if(this.iHash=t.create(),typeof this.iHash.update!="function")throw new Error("Expected instance of class which extends utils.Hash");this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;let o=this.blockLen,s=new Uint8Array(o);s.set(a.length>o?t.create().update(a).digest():a);for(let i=0;i<s.length;i++)s[i]^=54;this.iHash.update(s),this.oHash=t.create();for(let i=0;i<s.length;i++)s[i]^=106;this.oHash.update(s),g(s)}update(t){return H(this),this.iHash.update(t),this}digestInto(t){H(this),D(t,this.outputLen),this.finished=!0,this.iHash.digestInto(t),this.oHash.update(t),this.oHash.digestInto(t),this.destroy()}digest(){let t=new Uint8Array(this.oHash.outputLen);return this.digestInto(t),t}_cloneInto(t){t||(t=Object.create(Object.getPrototypeOf(this),{}));let{oHash:n,iHash:a,finished:o,destroyed:s,blockLen:i,outputLen:c}=this;return t=t,t.finished=o,t.destroyed=s,t.blockLen=i,t.outputLen=c,t.oHash=n._cloneInto(t.oHash),t.iHash=a._cloneInto(t.iHash),t}clone(){return this._cloneInto()}destroy(){this.destroyed=!0,this.oHash.destroy(),this.iHash.destroy()}},y=(e,t,n)=>new $(e,t).update(n).digest();y.create=(e,t)=>new $(e,t);function ar(e,t,n,a){if(typeof e.setBigUint64=="function")return e.setBigUint64(t,n,a);let o=BigInt(32),s=BigInt(4294967295),i=Number(n>>o&s),c=Number(n&s),d=a?4:0,u=a?0:4;e.setUint32(t+d,i,a),e.setUint32(t+u,c,a)}function $e(e,t,n){return e&t^~e&n}function qe(e,t,n){return e&t^e&n^t&n}var q=class extends U{constructor(t,n,a,o){super(),this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.blockLen=t,this.outputLen=n,this.padOffset=a,this.isLE=o,this.buffer=new Uint8Array(t),this.view=v(this.buffer)}update(t){H(this),t=w(t),D(t);let{view:n,buffer:a,blockLen:o}=this,s=t.length;for(let i=0;i<s;){let c=Math.min(o-this.pos,s-i);if(c===o){let d=v(t);for(;o<=s-i;i+=o)this.process(d,i);continue}a.set(t.subarray(i,i+c),this.pos),this.pos+=c,i+=c,this.pos===o&&(this.process(n,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){H(this),We(t,this),this.finished=!0;let{buffer:n,view:a,blockLen:o,isLE:s}=this,{pos:i}=this;n[i++]=128,g(this.buffer.subarray(i)),this.padOffset>o-i&&(this.process(a,0),i=0);for(let p=i;p<o;p++)n[p]=0;ar(a,o-8,BigInt(this.length*8),s),this.process(a,0);let c=v(t),d=this.outputLen;if(d%4)throw new Error("_sha2: outputLen should be aligned to 32bit");let u=d/4,h=this.get();if(u>h.length)throw new Error("_sha2: outputLen bigger than state");for(let p=0;p<u;p++)c.setUint32(4*p,h[p],s)}digest(){let{buffer:t,outputLen:n}=this;this.digestInto(t);let a=t.slice(0,n);return this.destroy(),a}_cloneInto(t){t||(t=new this.constructor),t.set(...this.get());let{blockLen:n,buffer:a,length:o,finished:s,destroyed:i,pos:c}=this;return t.destroyed=i,t.finished=s,t.length=o,t.pos=c,o%n&&t.buffer.set(a),t}clone(){return this._cloneInto()}},k=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var sr=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),R=new Uint32Array(64),J=class extends q{constructor(t=32){super(64,t,8,!1),this.A=k[0]|0,this.B=k[1]|0,this.C=k[2]|0,this.D=k[3]|0,this.E=k[4]|0,this.F=k[5]|0,this.G=k[6]|0,this.H=k[7]|0}get(){let{A:t,B:n,C:a,D:o,E:s,F:i,G:c,H:d}=this;return[t,n,a,o,s,i,c,d]}set(t,n,a,o,s,i,c,d){this.A=t|0,this.B=n|0,this.C=a|0,this.D=o|0,this.E=s|0,this.F=i|0,this.G=c|0,this.H=d|0}process(t,n){for(let p=0;p<16;p++,n+=4)R[p]=t.getUint32(n,!1);for(let p=16;p<64;p++){let x=R[p-15],f=R[p-2],L=E(x,7)^E(x,18)^x>>>3,S=E(f,17)^E(f,19)^f>>>10;R[p]=S+R[p-7]+L+R[p-16]|0}let{A:a,B:o,C:s,D:i,E:c,F:d,G:u,H:h}=this;for(let p=0;p<64;p++){let x=E(c,6)^E(c,11)^E(c,25),f=h+x+$e(c,d,u)+sr[p]+R[p]|0,S=(E(a,2)^E(a,13)^E(a,22))+qe(a,o,s)|0;h=u,u=d,d=c,c=i+f|0,i=s,s=o,o=a,a=f+S|0}a=a+this.A|0,o=o+this.B|0,s=s+this.C|0,i=i+this.D|0,c=c+this.E|0,d=d+this.F|0,u=u+this.G|0,h=h+this.H|0,this.set(a,o,s,i,c,d,u,h)}roundClean(){g(R)}destroy(){this.set(0,0,0,0,0,0,0,0),g(this.buffer)}};var Je=je(()=>new J);var T=Je;function ir(e,t,n,a){P(e);let o=Ye({dkLen:32,asyncTick:10},a),{c:s,dkLen:i,asyncTick:c}=o;if(M(s),M(i),M(c),s<1)throw new Error("iterations (c) should be >= 1");let d=me(t),u=me(n),h=new Uint8Array(i),p=y.create(e,d),x=p._cloneInto().update(u);return{c:s,dkLen:i,asyncTick:c,DK:h,PRF:p,PRFSalt:x}}function cr(e,t,n,a,o){return e.destroy(),t.destroy(),a&&a.destroy(),g(o),n}async function Xe(e,t,n,a){let{c:o,dkLen:s,asyncTick:i,DK:c,PRF:d,PRFSalt:u}=ir(e,t,n,a),h,p=new Uint8Array(4),x=v(p),f=new Uint8Array(d.outputLen);for(let L=1,S=0;S<s;L++,S+=d.outputLen){let K=c.subarray(S,S+d.outputLen);x.setInt32(0,L,!1),(h=u._cloneInto(h)).update(p).digestInto(f),K.set(f.subarray(0,K.length)),await ze(o-1,i,()=>{d._cloneInto(h).update(f).digestInto(f);for(let z=0;z<K.length;z++)K[z]^=f[z]})}return cr(d,u,c,h,f)}function lr(e,t,n){return P(e),n===void 0&&(n=new Uint8Array(e.outputLen)),y(e,w(n),w(t))}var ge=Uint8Array.from([0]),Ze=Uint8Array.of();function dr(e,t,n,a=32){P(e),M(a);let o=e.outputLen;if(a>255*o)throw new Error("Length should be <= 255*HashLen");let s=Math.ceil(a/o);n===void 0&&(n=Ze);let i=new Uint8Array(s*o),c=y.create(e,t),d=c._cloneInto(),u=new Uint8Array(c.outputLen);for(let h=0;h<s;h++)ge[0]=h+1,d.update(h===0?Ze:u).update(n).update(ge).digestInto(u),i.set(u,o*h),c._cloneInto(d);return c.destroy(),d.destroy(),g(u,ge),i.slice(0,a)}var Qe=(e,t,n,a,o)=>dr(e,lr(e,t,n),a,o);var pr=8,ur="hmac-sha256-v1",hr="normalization-v1",fr="normalization-v2",mr="pbkdf2-sha256-600k-v2",et=6e5,gr=et,Ee=32,tt="[\\u00ad\\u200b-\\u200f\\u2060-\\u2064\\ufeff]",Er=new RegExp(tt,"g");function be(e){let t=e.normalize("NFC");return t=t.replace(/\r\n/g,`
1
+ "use strict";var ie=Object.defineProperty;var vt=Object.getOwnPropertyDescriptor;var Lt=Object.getOwnPropertyNames;var Nt=Object.prototype.hasOwnProperty;var Ot=(e,t)=>{for(var n in t)ie(e,n,{get:t[n],enumerable:!0})},Gt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Lt(t))!Nt.call(e,a)&&a!==n&&ie(e,a,{get:()=>t[a],enumerable:!(o=vt(t,a))||o.enumerable});return e};var Bt=e=>Gt(ie({},"__esModule",{value:!0}),e);var Tn={};Ot(Tn,{AIToolCategory:()=>ce,AI_REGISTRY:()=>Y,ANNUAL_MONTHS_FREE:()=>qt,ASSIGNED_SECRET_SLUG:()=>bn,AlertChannel:()=>Ne,AlertTrigger:()=>Oe,CATEGORISED_SLUGS:()=>Rn,COVERAGE_SLUGS:()=>Pt,DETECTION_CATEGORIES:()=>_e,DETECTION_FAMILY_BLURBS:()=>An,DETECTION_FAMILY_NAMES:()=>_t,DETECTION_PROOF_NAMES:()=>In,DETECTION_UNIVERSAL_IGNORES:()=>kn,DIGEST_VERSION_HMAC_V1:()=>xr,ENTERPRISE_FEATURES:()=>fe,EventAction:()=>He,EventType:()=>Ge,FREE_FEATURES:()=>ue,FREE_SEATS:()=>pe,GENERATED_PASSPHRASE_ENTROPY_BITS:()=>Vr,GENERATED_PASSPHRASE_REQUIRED_MESSAGE:()=>pt,INVISIBLE_CHARS_CLASS:()=>st,KDF_ITERATIONS:()=>Sr,KDF_VERSION_V2:()=>kr,MATRIX_TIERS:()=>Qt,MAX_ACTIVITY_SESSIONS_PER_BATCH:()=>Mo,MAX_SCAN_WINDOWS:()=>se,MAX_TOTAL_SCAN_CHARS:()=>W,MIN_SECRET_LENGTH:()=>yr,NORMALIZATION_VERSION_V1:()=>Ar,NORMALIZATION_VERSION_V2:()=>Ir,OrgPlan:()=>Le,PASSPHRASE_CREDENTIAL_NAME:()=>te,PASSPHRASE_CREDENTIAL_URL:()=>ke,PASSPHRASE_VERIFY_LABEL:()=>ct,PASTE_CEILING_ALARM_CHARS:()=>wt,PASTE_CEILING_WARN_CHARS:()=>Rt,PLAN_DESCRIPTORS:()=>tr,PLAN_FEATURE_MATRIX:()=>er,PLAN_FEATURE_TIERS:()=>Zt,PLAN_LIMITS:()=>Fe,PLAN_PRICING:()=>Yt,PRIVACY_EMAIL:()=>or,PROJECT_KDF_LABEL:()=>it,PRO_BANDS:()=>m,PRO_ENTRY_BAND:()=>A,PRO_FEATURES:()=>he,PRO_TOP_BAND:()=>zt,RiskLevel:()=>le,SAFE_BLOCK_EVENT_FIELDS:()=>Ft,SALES_EMAIL:()=>rr,SCAN_PREFILTER_LABEL:()=>Et,SCAN_PREFILTER_PATTERN:()=>xt,SCAN_PREFILTER_SPACE:()=>Re,SCAN_PREFILTER_WINDOWS_PER_SIGNATURE:()=>Dt,SECRET_PROVIDER_NAMES:()=>Pe,SECRET_PROVIDER_SLUGS:()=>Ct,SECURITY_EMAIL:()=>nr,TRIAL_DAYS:()=>Jt,UNRECOGNISED_PROVIDER_SLUG:()=>V,UserRole:()=>ve,annualBilledNote:()=>We,appendPasskeyEnvelope:()=>sn,behaviorExplanation:()=>Vt,canonicalSecretPlaintextForHmac:()=>X,categoryOfSlug:()=>Sn,computePassphraseVerifyHmac:()=>Ur,customPolicyDomains:()=>wn,decodeScanPrefilter:()=>we,deriveBehaviorRisk:()=>Wt,deriveHmacKeyFromPassphrase:()=>Tr,deriveProjectKey:()=>Pr,deriveScanPrefilterSeed:()=>It,encodeScanPrefilter:()=>Mt,extractAddedLinesFromUnifiedDiff:()=>dn,familyDisplayName:()=>Dn,familyOfSlug:()=>Ut,findBand:()=>jt,findPasskeyEnvelope:()=>ln,foldUuidHexCase:()=>O,generateHmacKey:()=>Hr,generateOrgPassphrase:()=>Yr,generatePrfSalt:()=>rn,getInjectionHostnames:()=>ze,getLimitsForPlan:()=>Kt,getPrfSaltBytes:()=>an,hexToKey:()=>Lr,hmacDigestHex:()=>Q,isAIToolDomain:()=>sr,isGeneratedPassphraseFormat:()=>ut,isInjectionScopedHostname:()=>ge,isKnownProviderSlug:()=>yn,isProtectableSlug:()=>Mn,isV1PassphraseEnvelope:()=>ft,isV2Envelope:()=>ht,keyToHex:()=>vr,matchDomain:()=>Ke,matchPatternsForHostname:()=>lr,maxScannablePasteChars:()=>gn,maxScannablePasteCharsFor:()=>ae,normalizeAndHmacHex:()=>wr,normalizeAndHmacHexCollapsed:()=>Dr,normalizeAndHmacHexLower:()=>Rr,normalizeDomainInput:()=>Ee,normalizeSecretPlaintextCollapsed:()=>G,normalizeSecretPlaintextForMatch:()=>Ae,normalizeSecretPlaintextLower:()=>Z,passphraseCsvText:()=>qr,passphraseSheetText:()=>jr,perMonthOnAnnual:()=>Xt,policyNamedDomains:()=>Ht,projectedScanCost:()=>Ce,providerDisplayName:()=>xn,removePasskeyEnvelope:()=>cn,scanBudgetFor:()=>En,scanPrefilterFingerprint:()=>oe,scanPrefilterForRawSecret:()=>fn,scanPrefilterParams:()=>At,scanPrefilterRoller:()=>hn,scanPrefilterUnits:()=>kt,scanSweeps:()=>Te,scanWindowLengths:()=>mn,smallestBandFor:()=>$t,unwrapHmacKeyWithPrf:()=>on,upgradeEnvelopeToV2:()=>Qr,usd:()=>C,validateGeneratedPassphrase:()=>Zr,validateNewPassphrase:()=>ee,validatePassphraseStrength:()=>lt,wrapHmacKeyWithPrf:()=>nn});module.exports=Bt(Tn);var ce=(c=>(c.CODE_GEN="CODE_GEN",c.IMAGE_GEN="IMAGE_GEN",c.WRITING="WRITING",c.DATA_ANALYSIS="DATA_ANALYSIS",c.CHATBOT="CHATBOT",c.SEARCH="SEARCH",c.OTHER="OTHER",c))(ce||{}),le=(a=>(a.LOW="LOW",a.MEDIUM="MEDIUM",a.HIGH="HIGH",a.CRITICAL="CRITICAL",a))(le||{}),He=(n=>(n.BLOCKED="BLOCKED",n.LOGGED="LOGGED",n))(He||{}),ve=(a=>(a.OWNER="OWNER",a.ADMIN="ADMIN",a.USER="USER",a.VIEWER="VIEWER",a))(ve||{}),Le=(o=>(o.FREE="FREE",o.PRO="PRO",o.ENTERPRISE="ENTERPRISE",o))(Le||{}),Ne=(n=>(n.EMAIL="EMAIL",n.WEBHOOK="WEBHOOK",n))(Ne||{}),Oe=(o=>(o.CRITICAL_BLOCK="CRITICAL_BLOCK",o.DAILY_SUMMARY="DAILY_SUMMARY",o.WEEKLY_REPORT="WEEKLY_REPORT",o))(Oe||{}),Ge=(a=>(a.PASTE="PASTE",a.FILE_UPLOAD="FILE_UPLOAD",a.PASTE_REDACTED="PASTE_REDACTED",a.DETECTED="DETECTED",a))(Ge||{}),Ft=["event","type","secretLabel","secretLabels","attemptCount","risk","toolDomain","sourceUrl","timestamp","eventType","scanMethod","scanMs","hmacBatches","secretIds","matchReason","matchReasonSource","bypassVariant","incidentId","detectedAt","policyAction"];function Wt(e){return e<=1?"low":e===2?"medium":"high"}function Vt(e){return e<=1?"User likely made an accidental paste.":e===2?"User may not be aware this is sensitive.":"Repeated attempts detected \u2014 potential risk."}var _={maxUsers:5,maxInviteCodes:5,alerts:["EMAIL"],customDetection:!1,advancedReports:!1,exportReports:!1,siem:!1,sso:!1},de={maxUsers:200,maxInviteCodes:200,alerts:["EMAIL","WEBHOOK"],customDetection:!0,advancedReports:!0,exportReports:!1,siem:!1,sso:!1},Be={maxUsers:9999,maxInviteCodes:9999,alerts:["EMAIL","WEBHOOK"],customDetection:!0,advancedReports:!0,exportReports:!0,siem:!0,sso:!0},Fe={FREE:_,PRO:de,ENTERPRISE:Be};function Kt(e){return Fe[e]??_}var pe=_.maxUsers,m=[{id:"team15",name:"Team",maxUsers:15,monthlyUsd:59,annualUsd:590},{id:"growth30",name:"Growth",maxUsers:30,monthlyUsd:119,annualUsd:1190},{id:"business75",name:"Business",maxUsers:75,monthlyUsd:279,annualUsd:2790},{id:"scale200",name:"Scale",maxUsers:200,monthlyUsd:649,annualUsd:6490}],_n=m[m.length-1].maxUsers,A=m[0],zt=m[m.length-1],Yt={PRO:{monthlyUsd:A.monthlyUsd,annualUsd:A.annualUsd}};function jt(e){return m.find(t=>t.id===e)}function $t(e){return m.find(t=>t.maxUsers>=e)}var qt=2,Jt=14;function C(e){return`$${Number.isInteger(e)?e.toLocaleString("en-US"):e.toFixed(2)}`}function Xt(e){return C(e/12)}function We(e,t){return`${C(t)} billed yearly \xB7 save ${C(e*12-t)}`}var ue=["The full detection engine \u2014 paste, send, typed input, drag and file upload","Chrome, Edge and Safari","Bypass detection \u2014 whitespace injection and case folding","Unregistered-secret suggestions \u2014 spots keys nobody registered, admin opt-in, never a block","Zero-knowledge by construction: only HMAC digests leave the device",`Up to ${pe} monitored users`,`${_.maxInviteCodes} invite codes`,"Email alerts","30-day compliance history","Community support"],he=[`Pick your team's size \u2014 ${m.map(e=>`${e.name} to ${e.maxUsers} people, ${C(e.monthlyUsd)}/mo`).join("; ")}`,"Everyone inside your size is covered; no per-seat metering or proration between invites","As many unused invite links as your size has seats","Webhook alerts alongside email","Domain policies \u2014 add any site, beyond the built-in AI tools, to the places Redaktyn blocks","365-day compliance history","Priority support"],fe=["Custom seat limits, agreed rather than published","CSV export of the full event log","SIEM webhook delivery","SSO \u2014 SAML and OIDC","Dedicated support"],Zt=[{key:"FREE",name:"Free",features:ue},{key:"PRO",name:"Pro",features:he},{key:"ENTERPRISE",name:"Enterprise",features:fe}],Qt=[{key:"FREE",name:"Free",price:"$0"},{key:"PRO",name:"Pro",price:`From ${C(A.monthlyUsd)}/mo`},{key:"ENTERPRISE",name:"Enterprise",price:"Contact us"}],er=[{section:"Limits",rows:[{label:"People covered",note:`Pro is bought in ${m.length} sizes, up to ${m.map(e=>e.maxUsers).join(", ")} people \u2014 the figure here is the largest; a workspace's own limit is the size it bought.`,gate:"maxUsers",values:{FREE:String(pe),PRO:"200",ENTERPRISE:"Custom"}},{label:"Invite codes",note:"Unused links held at once. A link is spent when a browser connects and takes a seat, so on Pro this is the size you bought.",gate:"maxInviteCodes",values:{FREE:String(_.maxInviteCodes),PRO:String(de.maxInviteCodes),ENTERPRISE:"Unlimited"}},{label:"Compliance history",note:"How far back a compliance report may be run. Event data itself is not deleted on any plan.",gate:"advancedReports",values:{FREE:"30 days",PRO:"365 days",ENTERPRISE:"365 days"}}]},{section:"Detection and blocking",rows:[{label:"Paste, send, typed input, drag and file upload",note:"All six enforcement paths, on every plan. Detection has never been plan-gated and is the last thing that should be.",ungated:"No plan check exists on any enforcement path in the extension.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Chrome, Edge and Safari",ungated:"The extension reports its browser; no route reads a plan before accepting the heartbeat.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Bypass detection \u2014 whitespace injection, case folding",ungated:"Runs inside the same scan as the direct match; there is no flag to turn it off.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Detection engine \u2014 50 categories nobody registered",note:"Credentials, infrastructure files and personal data, each proven by a checksum, a decoded structure or the provider's format. On by default; suggests, never blocks.",ungated:"The org switch is an admin setting with no plan check, and the extension's resolver reads only that switch.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Personal-data detection \u2014 cards, Aadhaar, PAN, SSN, IBAN",note:"Checksum-verified and labelled, offered for removal only. Its own switch, on by default.",ungated:"The personal-data switch is an admin setting with no plan check; the resolver passes it straight to the engine.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Unprotected-secret counts by category",note:"A daily count per category on the dashboard \u2014 never a value, a fingerprint or a name.",ungated:"The coverage route checks the org's reporting switch and the enrolment, never the plan.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Custom domain policies",note:"Add a site that is not one of the built-in AI tools to the places Redaktyn blocks. Older warn and log policies keep working.",gate:"customDetection",values:{FREE:!1,PRO:!0,ENTERPRISE:!0}}]},{section:"Alerting and reporting",rows:[{label:"Email alerts",ungated:"EMAIL is in every plan's channel list, so the row is true by construction.",values:{FREE:!0,PRO:!0,ENTERPRISE:!0}},{label:"Webhook alerts",gate:"alerts",channel:"WEBHOOK",values:{FREE:!1,PRO:!0,ENTERPRISE:!0}},{label:"Executive PDF report",note:"Emailed every Monday, and downloadable at any time from Reports.",gate:"advancedReports",values:{FREE:!1,PRO:!0,ENTERPRISE:!0}},{label:"CSV export of the event log",gate:"exportReports",values:{FREE:!1,PRO:!1,ENTERPRISE:!0}},{label:"SIEM webhook delivery",gate:"siem",values:{FREE:!1,PRO:!1,ENTERPRISE:!0}}]},{section:"Access and support",rows:[{label:"SSO \u2014 SAML and OIDC",gate:"sso",values:{FREE:!1,PRO:!1,ENTERPRISE:!0}},{label:"Support",note:"A commitment from people, not a switch in the code \u2014 which is why no flag backs this row.",ungated:"Support tiering is contractual; no route reads a plan to answer a support request.",values:{FREE:"Community",PRO:"Priority",ENTERPRISE:"Dedicated"}}]}],tr=[{id:"FREE",name:"Free",tagline:"The whole detection engine, for a team that is still proving it works",priceMonthly:0,priceLabel:"$0",priceNote:"Forever free \xB7 no card",limits:_,features:ue,featuresHeading:"What's included",highlighted:!1,cta:"Get started"},{id:"PRO",name:"Pro",tagline:"For a team that has to answer questions about its own exposure",priceMonthly:A.monthlyUsd,priceLabel:C(A.monthlyUsd),priceNote:`per month \xB7 up to ${A.maxUsers} people`,annualNote:We(A.monthlyUsd,A.annualUsd),limits:de,features:he,featuresHeading:"Everything in Free, plus",highlighted:!0,cta:"Start free, then upgrade"},{id:"ENTERPRISE",name:"Enterprise",tagline:"For satisfying somebody else's auditor or IT department",priceMonthly:null,priceLabel:"Custom",priceNote:"Contact sales",limits:Be,features:fe,featuresHeading:"Everything in Pro, plus",highlighted:!1,cta:"Contact sales"}],Ve="ak8340651733@gmail.com",rr=Ve,nr=Ve,or="support@redaktyn.com";function r(e,t,n,o="MEDIUM",a={}){return{domain:e,name:t,category:n,riskLevel:o,isEnterprise:a.isEnterprise??!1,...a.personalVersionDomain?{personalVersionDomain:a.personalVersionDomain}:{}}}var Y=[r("chat.openai.com","ChatGPT","CODE_GEN","HIGH"),r("chatgpt.com","ChatGPT","CODE_GEN","HIGH"),r("platform.openai.com","OpenAI Platform","CODE_GEN","HIGH"),r("claude.ai","Claude","CODE_GEN","HIGH"),r("gemini.google.com","Gemini","CODE_GEN","MEDIUM"),r("aistudio.google.com","Google AI Studio","CODE_GEN","MEDIUM"),r("copilot.github.com","GitHub Copilot","CODE_GEN","MEDIUM"),r("github.com/copilot","GitHub Copilot Chat","CODE_GEN","MEDIUM"),r("cursor.sh","Cursor","CODE_GEN","MEDIUM"),r("cursor.com","Cursor","CODE_GEN","MEDIUM"),r("replit.com","Replit","CODE_GEN","HIGH"),r("codeium.com","Codeium","CODE_GEN","MEDIUM"),r("tabnine.com","Tabnine","CODE_GEN","MEDIUM"),r("codewhisperer.aws","Amazon CodeWhisperer","CODE_GEN","LOW",{isEnterprise:!0}),r("aws.amazon.com/codewhisperer","Amazon CodeWhisperer","CODE_GEN","LOW",{isEnterprise:!0}),r("phind.com","Phind","CODE_GEN","MEDIUM"),r("continue.dev","Continue","CODE_GEN","MEDIUM"),r("askcodi.com","AskCodi","CODE_GEN","MEDIUM"),r("sourcegraph.com","Sourcegraph Cody","CODE_GEN","MEDIUM"),r("windsurf.ai","Windsurf","CODE_GEN","MEDIUM"),r("v0.dev","Vercel v0","CODE_GEN","MEDIUM"),r("bolt.new","Bolt","CODE_GEN","HIGH"),r("lovable.dev","Lovable","CODE_GEN","HIGH"),r("aider.chat","Aider","CODE_GEN","MEDIUM"),r("cody.dev","Cody","CODE_GEN","MEDIUM"),r("blackbox.ai","Blackbox AI","CODE_GEN","HIGH"),r("deepcode.ai","DeepCode","CODE_GEN","MEDIUM"),r("codiga.io","Codiga","CODE_GEN","MEDIUM"),r("mutable.ai","Mutable AI","CODE_GEN","MEDIUM"),r("pieces.app","Pieces","CODE_GEN","MEDIUM"),r("codium.ai","CodiumAI","CODE_GEN","MEDIUM"),r("coderabbit.ai","CodeRabbit","CODE_GEN","MEDIUM"),r("devin.ai","Devin","CODE_GEN","HIGH"),r("idx.dev","Project IDX","CODE_GEN","MEDIUM"),r("stackblitz.com","StackBlitz","CODE_GEN","MEDIUM"),r("codepen.io","CodePen AI","CODE_GEN","MEDIUM"),r("codesandbox.io","CodeSandbox AI","CODE_GEN","MEDIUM"),r("gitpod.io","Gitpod","CODE_GEN","MEDIUM"),r("poe.com","Poe","CHATBOT","MEDIUM"),r("character.ai","Character.AI","CHATBOT","MEDIUM"),r("beta.character.ai","Character.AI Beta","CHATBOT","MEDIUM"),r("huggingface.co/chat","HuggingChat","CHATBOT","MEDIUM"),r("pi.ai","Pi","CHATBOT","LOW"),r("chat.mistral.ai","Mistral Chat","CHATBOT","MEDIUM"),r("chat.deepseek.com","DeepSeek Chat","CHATBOT","HIGH"),r("deepseek.com","DeepSeek","CHATBOT","HIGH"),r("groq.com","Groq","CHATBOT","MEDIUM"),r("console.groq.com","Groq Console","CHATBOT","MEDIUM"),r("cohere.com","Cohere","CHATBOT","MEDIUM"),r("coral.cohere.com","Cohere Coral","CHATBOT","MEDIUM"),r("inflection.ai","Inflection","CHATBOT","MEDIUM"),r("chat.lmsys.org","LMSYS Chatbot Arena","CHATBOT","HIGH"),r("open-assistant.io","Open Assistant","CHATBOT","MEDIUM"),r("bard.google.com","Google Bard","CHATBOT","MEDIUM"),r("copilot.microsoft.com","Microsoft Copilot","CHATBOT","LOW",{isEnterprise:!0}),r("bing.com/chat","Bing Chat","CHATBOT","MEDIUM"),r("meta.ai","Meta AI","CHATBOT","MEDIUM"),r("labs.perplexity.ai","Perplexity Labs","CHATBOT","MEDIUM"),r("together.ai","Together AI","CHATBOT","MEDIUM"),r("api.together.xyz","Together API","CHATBOT","MEDIUM"),r("fireworks.ai","Fireworks AI","CHATBOT","MEDIUM"),r("anyscale.com","Anyscale","CHATBOT","MEDIUM"),r("replicate.com","Replicate","CHATBOT","MEDIUM"),r("lepton.ai","Lepton AI","CHATBOT","MEDIUM"),r("forefront.ai","Forefront","CHATBOT","MEDIUM"),r("chat.vercel.ai","Vercel AI Chat","CHATBOT","MEDIUM"),r("llama.meta.com","Llama","CHATBOT","MEDIUM"),r("grok.com","Grok","CHATBOT","HIGH"),r("grok.x.ai","Grok","CHATBOT","MEDIUM"),r("x.ai","xAI","CHATBOT","MEDIUM"),r("duckduckgo.com/aichat","DuckDuckGo AI Chat","CHATBOT","LOW"),r("chatglm.cn","ChatGLM","CHATBOT","HIGH"),r("yiyan.baidu.com","Ernie Bot","CHATBOT","HIGH"),r("qianwen.aliyun.com","Qwen","CHATBOT","HIGH"),r("abacus.ai","Abacus AI","CHATBOT","MEDIUM"),r("midjourney.com","Midjourney","IMAGE_GEN","MEDIUM"),r("discord.com/channels/midjourney","Midjourney Discord","IMAGE_GEN","MEDIUM"),r("openai.com/dall-e","DALL-E","IMAGE_GEN","MEDIUM"),r("labs.openai.com","DALL-E Labs","IMAGE_GEN","MEDIUM"),r("stability.ai","Stable Diffusion","IMAGE_GEN","MEDIUM"),r("dreamstudio.ai","DreamStudio","IMAGE_GEN","MEDIUM"),r("leonardo.ai","Leonardo.ai","IMAGE_GEN","MEDIUM"),r("app.leonardo.ai","Leonardo.ai App","IMAGE_GEN","MEDIUM"),r("ideogram.ai","Ideogram","IMAGE_GEN","MEDIUM"),r("firefly.adobe.com","Adobe Firefly","IMAGE_GEN","LOW",{isEnterprise:!0}),r("clipdrop.co","ClipDrop","IMAGE_GEN","MEDIUM"),r("playground.ai","Playground AI","IMAGE_GEN","MEDIUM"),r("nightcafe.studio","NightCafe","IMAGE_GEN","MEDIUM"),r("creator.nightcafe.studio","NightCafe Creator","IMAGE_GEN","MEDIUM"),r("runwayml.com","Runway","IMAGE_GEN","MEDIUM"),r("app.runwayml.com","Runway App","IMAGE_GEN","MEDIUM"),r("canva.com/ai-image-generator","Canva AI","IMAGE_GEN","LOW"),r("imagine.meta.com","Meta Imagine","IMAGE_GEN","MEDIUM"),r("pika.art","Pika","IMAGE_GEN","MEDIUM"),r("kaiber.ai","Kaiber","IMAGE_GEN","MEDIUM"),r("bing.com/images/create","Bing Image Creator","IMAGE_GEN","MEDIUM"),r("designer.microsoft.com","Microsoft Designer","IMAGE_GEN","MEDIUM"),r("craiyon.com","Craiyon","IMAGE_GEN","LOW"),r("starryai.com","StarryAI","IMAGE_GEN","LOW"),r("hotpot.ai","Hotpot AI","IMAGE_GEN","LOW"),r("lexica.art","Lexica","IMAGE_GEN","LOW"),r("jasper.ai","Jasper","WRITING","MEDIUM"),r("app.jasper.ai","Jasper App","WRITING","MEDIUM"),r("copy.ai","Copy.ai","WRITING","MEDIUM"),r("app.copy.ai","Copy.ai App","WRITING","MEDIUM"),r("writesonic.com","Writesonic","WRITING","MEDIUM"),r("app.writesonic.com","Writesonic App","WRITING","MEDIUM"),r("grammarly.com","Grammarly AI","WRITING","MEDIUM"),r("app.grammarly.com","Grammarly App","WRITING","MEDIUM"),r("notion.so","Notion AI","WRITING","MEDIUM"),r("quillbot.com","QuillBot","WRITING","MEDIUM"),r("wordtune.com","Wordtune","WRITING","MEDIUM"),r("rytr.me","Rytr","WRITING","MEDIUM"),r("anyword.com","Anyword","WRITING","MEDIUM"),r("hyperwriteai.com","HyperWrite","WRITING","MEDIUM"),r("writer.com","Writer","WRITING","MEDIUM",{isEnterprise:!0}),r("textcortex.com","TextCortex","WRITING","MEDIUM"),r("app.textcortex.com","TextCortex App","WRITING","MEDIUM"),r("peppertype.ai","Peppertype","WRITING","MEDIUM"),r("simplified.com","Simplified AI","WRITING","MEDIUM"),r("contentbot.ai","ContentBot","WRITING","MEDIUM"),r("ink.co","INK Editor","WRITING","MEDIUM"),r("sudowrite.com","Sudowrite","WRITING","MEDIUM"),r("novelai.net","NovelAI","WRITING","LOW"),r("shortlyai.com","ShortlyAI","WRITING","MEDIUM"),r("lex.page","Lex","WRITING","MEDIUM"),r("julius.ai","Julius","DATA_ANALYSIS","HIGH"),r("hex.tech","Hex","DATA_ANALYSIS","HIGH"),r("app.hex.tech","Hex App","DATA_ANALYSIS","HIGH"),r("obviously.ai","Obviously AI","DATA_ANALYSIS","HIGH"),r("akkio.com","Akkio","DATA_ANALYSIS","HIGH"),r("monkeylearn.com","MonkeyLearn","DATA_ANALYSIS","HIGH"),r("rows.com","Rows","DATA_ANALYSIS","MEDIUM"),r("breadcrumbs.io","Breadcrumbs","DATA_ANALYSIS","MEDIUM"),r("polymer.co","Polymer","DATA_ANALYSIS","HIGH"),r("databricks.com","Databricks AI","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("datarobot.com","DataRobot","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("h2o.ai","H2O.ai","DATA_ANALYSIS","MEDIUM"),r("rapidminer.com","RapidMiner","DATA_ANALYSIS","MEDIUM"),r("knime.com","KNIME","DATA_ANALYSIS","MEDIUM"),r("alteryx.com","Alteryx","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("tableau.com","Tableau AI","DATA_ANALYSIS","LOW",{isEnterprise:!0}),r("mode.com","Mode Analytics","DATA_ANALYSIS","MEDIUM"),r("deepnote.com","Deepnote","DATA_ANALYSIS","HIGH"),r("observable.com","Observable","DATA_ANALYSIS","MEDIUM"),r("noteable.io","Noteable","DATA_ANALYSIS","HIGH"),r("perplexity.ai","Perplexity Search","SEARCH","MEDIUM"),r("you.com","You.com Search","SEARCH","MEDIUM"),r("andi.ai","Andi","SEARCH","LOW"),r("kagi.com","Kagi","SEARCH","LOW"),r("metaphor.systems","Metaphor","SEARCH","MEDIUM"),r("exa.ai","Exa","SEARCH","MEDIUM"),r("tavily.com","Tavily","SEARCH","MEDIUM"),r("consensus.app","Consensus","SEARCH","LOW"),r("elicit.com","Elicit","SEARCH","MEDIUM"),r("elicit.org","Elicit","SEARCH","MEDIUM"),r("searchgpt.com","SearchGPT","SEARCH","MEDIUM"),r("brave.com/search/ai","Brave AI Search","SEARCH","LOW"),r("neeva.com","Neeva","SEARCH","LOW"),r("socratic.org","Socratic","SEARCH","LOW"),r("devv.ai","Devv AI","SEARCH","MEDIUM"),r("iask.ai","iAsk AI","SEARCH","LOW"),r("chatpdf.com","ChatPDF","SEARCH","MEDIUM"),r("smodin.io","Smodin","WRITING","MEDIUM"),r("ai-writer.com","AI Writer","WRITING","MEDIUM"),r("scalenut.com","Scalenut","WRITING","MEDIUM"),r("closerscopy.com","ClosersCopy","WRITING","MEDIUM"),r("longshot.ai","LongShot AI","WRITING","MEDIUM"),r("fig.io","Fig AI","CODE_GEN","MEDIUM"),r("warp.dev","Warp Terminal AI","CODE_GEN","MEDIUM"),r("raycast.com","Raycast AI","CODE_GEN","MEDIUM"),r("app.codeanywhere.com","Codeanywhere AI","CODE_GEN","MEDIUM"),r("zed.dev","Zed AI","CODE_GEN","MEDIUM"),r("gencraft.com","Gencraft","IMAGE_GEN","LOW"),r("deepai.org","DeepAI","IMAGE_GEN","LOW"),r("artbreeder.com","Artbreeder","IMAGE_GEN","LOW"),r("fotor.com/ai","Fotor AI","IMAGE_GEN","LOW"),r("remove.bg","Remove.bg","IMAGE_GEN","LOW"),r("photoroom.com","PhotoRoom AI","IMAGE_GEN","LOW"),r("app.recraft.ai","Recraft AI","IMAGE_GEN","MEDIUM"),r("pecan.ai","Pecan AI","DATA_ANALYSIS","HIGH"),r("apteo.co","Apteo","DATA_ANALYSIS","HIGH"),r("mindsdb.com","MindsDB","DATA_ANALYSIS","MEDIUM"),r("zapier.com/ai","Zapier AI","OTHER","MEDIUM"),r("make.com","Make (Integromat) AI","OTHER","MEDIUM"),r("otter.ai","Otter.ai","OTHER","HIGH"),r("fireflies.ai","Fireflies.ai","OTHER","HIGH"),r("descript.com","Descript","OTHER","MEDIUM"),r("synthesia.io","Synthesia","OTHER","MEDIUM"),r("elevenlabs.io","ElevenLabs","OTHER","MEDIUM"),r("murf.ai","Murf AI","OTHER","MEDIUM"),r("resemble.ai","Resemble AI","OTHER","MEDIUM"),r("loom.com","Loom AI","OTHER","MEDIUM"),r("beautiful.ai","Beautiful.ai","OTHER","LOW"),r("gamma.app","Gamma","OTHER","MEDIUM"),r("tome.app","Tome","OTHER","MEDIUM"),r("magician.design","Magician","OTHER","MEDIUM"),r("uizard.io","Uizard","OTHER","MEDIUM"),r("huggingface.co/spaces","HuggingFace Spaces","OTHER","MEDIUM"),r("roboflow.com","Roboflow","OTHER","MEDIUM"),r("scale.com","Scale AI","OTHER","MEDIUM"),r("labelbox.com","Labelbox","OTHER","MEDIUM")],Ln=new Set(Y.map(e=>e.domain.toLowerCase())),N=new Map;for(let e of Y){let t=e.domain.toLowerCase();N.has(t)||N.set(t,e)}function ar(e){try{return e.includes("://")||(e="https://"+e),new URL(e).hostname.toLowerCase()}catch{return null}}function Ke(e){let t=ar(e);if(!t)return null;let n=N.get(t);if(n)return n;try{let a=new URL(e.includes("://")?e:"https://"+e),s=(a.hostname+a.pathname).toLowerCase().replace(/\/+$/,""),i=N.get(s);if(i)return i}catch{}let o=t.split(".");for(let a=1;a<o.length-1;a++){let s=o.slice(a).join("."),i=N.get(s);if(i)return i}return null}function sr(e){return Ke(e)!==null}var ir=new Set(["replit.com","sourcegraph.com","idx.dev","stackblitz.com","codepen.io","codesandbox.io","gitpod.io","fig.io","warp.dev","raycast.com","app.codeanywhere.com","zed.dev","anyscale.com","grammarly.com","notion.so","hex.tech","app.hex.tech","rows.com","breadcrumbs.io","databricks.com","datarobot.com","h2o.ai","rapidminer.com","knime.com","alteryx.com","tableau.com","mode.com","deepnote.com","observable.com","noteable.io","mindsdb.com","kagi.com","make.com","loom.com","roboflow.com","scale.com","labelbox.com"]),cr=["redaktyn.com"];function ze(){let e=new Set;for(let t of Y){let n=t.domain.toLowerCase();n.includes("/")||ir.has(n)||e.add(n)}for(let t of cr)e.add(t.toLowerCase());return Array.from(e).sort()}var me=null;function ge(e){me||(me=new Set(ze()));let t=e.toLowerCase();for(let n of me)if(t===n||t.endsWith(`.${n}`))return!0;return!1}function lr(e){let t=e.toLowerCase();return[`*://${t}/*`,`*://*.${t}/*`]}function Ee(e){let t=e.trim().toLowerCase();return!t||(t=t.replace(/^[a-z][a-z0-9+.-]*:\/\//,""),t=t.split(/[/?#]/)[0],t=t.split("@").pop(),t=t.split(":")[0],!/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/.test(t))?null:t}function dr(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function M(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("positive integer expected, got "+e)}function D(e,...t){if(!dr(e))throw new Error("Uint8Array expected");if(t.length>0&&!t.includes(e.length))throw new Error("Uint8Array expected of length "+t+", got length="+e.length)}function P(e){if(typeof e!="function"||typeof e.create!="function")throw new Error("Hash should be wrapped by utils.createHasher");M(e.outputLen),M(e.blockLen)}function H(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function je(e,t){D(e);let n=t.outputLen;if(e.length<n)throw new Error("digestInto() expects output buffer of length at least "+n)}function g(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function v(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function E(e,t){return e<<32-t|e>>>t}var $e=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",pr=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function j(e){if(D(e),$e)return e.toHex();let t="";for(let n=0;n<e.length;n++)t+=pr[e[n]];return t}var I={_0:48,_9:57,A:65,F:70,a:97,f:102};function Ye(e){if(e>=I._0&&e<=I._9)return e-I._0;if(e>=I.A&&e<=I.F)return e-(I.A-10);if(e>=I.a&&e<=I.f)return e-(I.a-10)}function qe(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if($e)return Uint8Array.fromHex(e);let t=e.length,n=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);let o=new Uint8Array(n);for(let a=0,s=0;a<n;a++,s+=2){let i=Ye(e.charCodeAt(s)),c=Ye(e.charCodeAt(s+1));if(i===void 0||c===void 0){let d=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+d+'" at index '+s)}o[a]=i*16+c}return o}var ur=async()=>{};async function Je(e,t,n){let o=Date.now();for(let a=0;a<e;a++){n(a);let s=Date.now()-o;s>=0&&s<t||(await ur(),o+=s)}}function b(e){if(typeof e!="string")throw new Error("string expected");return new Uint8Array(new TextEncoder().encode(e))}function R(e){return typeof e=="string"&&(e=b(e)),D(e),e}function be(e){return typeof e=="string"&&(e=b(e)),D(e),e}function Xe(e,t){if(t!==void 0&&{}.toString.call(t)!=="[object Object]")throw new Error("options should be object or undefined");return Object.assign(e,t)}var U=class{};function Ze(e){let t=o=>e().update(R(o)).digest(),n=e();return t.outputLen=n.outputLen,t.blockLen=n.blockLen,t.create=()=>e(),t}var $=class extends U{constructor(t,n){super(),this.finished=!1,this.destroyed=!1,P(t);let o=R(n);if(this.iHash=t.create(),typeof this.iHash.update!="function")throw new Error("Expected instance of class which extends utils.Hash");this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;let a=this.blockLen,s=new Uint8Array(a);s.set(o.length>a?t.create().update(o).digest():o);for(let i=0;i<s.length;i++)s[i]^=54;this.iHash.update(s),this.oHash=t.create();for(let i=0;i<s.length;i++)s[i]^=106;this.oHash.update(s),g(s)}update(t){return H(this),this.iHash.update(t),this}digestInto(t){H(this),D(t,this.outputLen),this.finished=!0,this.iHash.digestInto(t),this.oHash.update(t),this.oHash.digestInto(t),this.destroy()}digest(){let t=new Uint8Array(this.oHash.outputLen);return this.digestInto(t),t}_cloneInto(t){t||(t=Object.create(Object.getPrototypeOf(this),{}));let{oHash:n,iHash:o,finished:a,destroyed:s,blockLen:i,outputLen:c}=this;return t=t,t.finished=a,t.destroyed=s,t.blockLen=i,t.outputLen=c,t.oHash=n._cloneInto(t.oHash),t.iHash=o._cloneInto(t.iHash),t}clone(){return this._cloneInto()}destroy(){this.destroyed=!0,this.oHash.destroy(),this.iHash.destroy()}},y=(e,t,n)=>new $(e,t).update(n).digest();y.create=(e,t)=>new $(e,t);function hr(e,t,n,o){if(typeof e.setBigUint64=="function")return e.setBigUint64(t,n,o);let a=BigInt(32),s=BigInt(4294967295),i=Number(n>>a&s),c=Number(n&s),d=o?4:0,u=o?0:4;e.setUint32(t+d,i,o),e.setUint32(t+u,c,o)}function Qe(e,t,n){return e&t^~e&n}function et(e,t,n){return e&t^e&n^t&n}var q=class extends U{constructor(t,n,o,a){super(),this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.blockLen=t,this.outputLen=n,this.padOffset=o,this.isLE=a,this.buffer=new Uint8Array(t),this.view=v(this.buffer)}update(t){H(this),t=R(t),D(t);let{view:n,buffer:o,blockLen:a}=this,s=t.length;for(let i=0;i<s;){let c=Math.min(a-this.pos,s-i);if(c===a){let d=v(t);for(;a<=s-i;i+=a)this.process(d,i);continue}o.set(t.subarray(i,i+c),this.pos),this.pos+=c,i+=c,this.pos===a&&(this.process(n,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){H(this),je(t,this),this.finished=!0;let{buffer:n,view:o,blockLen:a,isLE:s}=this,{pos:i}=this;n[i++]=128,g(this.buffer.subarray(i)),this.padOffset>a-i&&(this.process(o,0),i=0);for(let p=i;p<a;p++)n[p]=0;hr(o,a-8,BigInt(this.length*8),s),this.process(o,0);let c=v(t),d=this.outputLen;if(d%4)throw new Error("_sha2: outputLen should be aligned to 32bit");let u=d/4,h=this.get();if(u>h.length)throw new Error("_sha2: outputLen bigger than state");for(let p=0;p<u;p++)c.setUint32(4*p,h[p],s)}digest(){let{buffer:t,outputLen:n}=this;this.digestInto(t);let o=t.slice(0,n);return this.destroy(),o}_cloneInto(t){t||(t=new this.constructor),t.set(...this.get());let{blockLen:n,buffer:o,length:a,finished:s,destroyed:i,pos:c}=this;return t.destroyed=i,t.finished=s,t.length=a,t.pos=c,a%n&&t.buffer.set(o),t}clone(){return this._cloneInto()}},k=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var fr=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),w=new Uint32Array(64),J=class extends q{constructor(t=32){super(64,t,8,!1),this.A=k[0]|0,this.B=k[1]|0,this.C=k[2]|0,this.D=k[3]|0,this.E=k[4]|0,this.F=k[5]|0,this.G=k[6]|0,this.H=k[7]|0}get(){let{A:t,B:n,C:o,D:a,E:s,F:i,G:c,H:d}=this;return[t,n,o,a,s,i,c,d]}set(t,n,o,a,s,i,c,d){this.A=t|0,this.B=n|0,this.C=o|0,this.D=a|0,this.E=s|0,this.F=i|0,this.G=c|0,this.H=d|0}process(t,n){for(let p=0;p<16;p++,n+=4)w[p]=t.getUint32(n,!1);for(let p=16;p<64;p++){let x=w[p-15],f=w[p-2],L=E(x,7)^E(x,18)^x>>>3,S=E(f,17)^E(f,19)^f>>>10;w[p]=S+w[p-7]+L+w[p-16]|0}let{A:o,B:a,C:s,D:i,E:c,F:d,G:u,H:h}=this;for(let p=0;p<64;p++){let x=E(c,6)^E(c,11)^E(c,25),f=h+x+Qe(c,d,u)+fr[p]+w[p]|0,S=(E(o,2)^E(o,13)^E(o,22))+et(o,a,s)|0;h=u,u=d,d=c,c=i+f|0,i=s,s=a,a=o,o=f+S|0}o=o+this.A|0,a=a+this.B|0,s=s+this.C|0,i=i+this.D|0,c=c+this.E|0,d=d+this.F|0,u=u+this.G|0,h=h+this.H|0,this.set(o,a,s,i,c,d,u,h)}roundClean(){g(w)}destroy(){this.set(0,0,0,0,0,0,0,0),g(this.buffer)}};var tt=Ze(()=>new J);var T=tt;function mr(e,t,n,o){P(e);let a=Xe({dkLen:32,asyncTick:10},o),{c:s,dkLen:i,asyncTick:c}=a;if(M(s),M(i),M(c),s<1)throw new Error("iterations (c) should be >= 1");let d=be(t),u=be(n),h=new Uint8Array(i),p=y.create(e,d),x=p._cloneInto().update(u);return{c:s,dkLen:i,asyncTick:c,DK:h,PRF:p,PRFSalt:x}}function gr(e,t,n,o,a){return e.destroy(),t.destroy(),o&&o.destroy(),g(a),n}async function rt(e,t,n,o){let{c:a,dkLen:s,asyncTick:i,DK:c,PRF:d,PRFSalt:u}=mr(e,t,n,o),h,p=new Uint8Array(4),x=v(p),f=new Uint8Array(d.outputLen);for(let L=1,S=0;S<s;L++,S+=d.outputLen){let K=c.subarray(S,S+d.outputLen);x.setInt32(0,L,!1),(h=u._cloneInto(h)).update(p).digestInto(f),K.set(f.subarray(0,K.length)),await Je(a-1,i,()=>{d._cloneInto(h).update(f).digestInto(f);for(let z=0;z<K.length;z++)K[z]^=f[z]})}return gr(d,u,c,h,f)}function Er(e,t,n){return P(e),n===void 0&&(n=new Uint8Array(e.outputLen)),y(e,R(n),R(t))}var ye=Uint8Array.from([0]),nt=Uint8Array.of();function br(e,t,n,o=32){P(e),M(o);let a=e.outputLen;if(o>255*a)throw new Error("Length should be <= 255*HashLen");let s=Math.ceil(o/a);n===void 0&&(n=nt);let i=new Uint8Array(s*a),c=y.create(e,t),d=c._cloneInto(),u=new Uint8Array(c.outputLen);for(let h=0;h<s;h++)ye[0]=h+1,d.update(h===0?nt:u).update(n).update(ye).digestInto(u),i.set(u,a*h),c._cloneInto(d);return c.destroy(),d.destroy(),g(u,ye),i.slice(0,o)}var ot=(e,t,n,o,a)=>br(e,Er(e,t,n),o,a);var yr=8,xr="hmac-sha256-v1",Ar="normalization-v1",Ir="normalization-v2",kr="pbkdf2-sha256-600k-v2",at=6e5,Sr=at,xe=32,st="[\\u00ad\\u200b-\\u200f\\u2060-\\u2064\\ufeff]",Mr=new RegExp(st,"g");function Ae(e){let t=e.normalize("NFC");return t=t.replace(/\r\n/g,`
2
2
  `).replace(/[\r\u2028\u2029]/g,`
3
- `),t=t.replace(Er,""),t=t.trim(),t}function N(e){if(e.length===36&&e[8]==="-"&&e[13]==="-"&&e[18]==="-"&&e[23]==="-"){let t=e.replace(/-/g,"");if(/^[0-9a-fA-F]{32}$/.test(t))return e.toLowerCase()}return e}function X(e){return N(be(e))}function G(e){return be(e).replace(/\s/g,"")}function br(e,t){return Q(N(G(e)),t)}function Z(e){return G(e).toLowerCase()}function yr(e,t){return Q(Z(e),t)}function Q(e,t){return j(y(T,t,b(e)))}function xr(e,t){return Q(X(e),t)}async function Ar(e,t){let n=b(e),a=T(b(t));return Xe(T,n,a,{c:et,dkLen:Ee})}var rt="redaktyn-project-key-v1",Ir=b(rt);function kr(e,t){if(e.length!==Ee)throw new Error("deriveProjectKey: org key must be 32 bytes");if(!t)throw new Error("deriveProjectKey: projectId is required");return Qe(T,e,b(t),Ir,Ee)}var nt="vaultx-passphrase-verify-v1",Sr=b(nt);function Mr(e){return j(y(T,e,Sr))}function Dr(){return crypto.getRandomValues(new Uint8Array(32))}function wr(e){return j(e)}function Rr(e){return Ke(e)}function ot(e){return e.length<12?{ok:!1,error:"Passphrase must be at least 12 characters."}:/[A-Z]/.test(e)?/[a-z]/.test(e)?/[0-9]/.test(e)?/[^A-Za-z0-9]/.test(e)?{ok:!0}:{ok:!1,error:"Passphrase must include at least one special character (e.g. !@#$%)."}:{ok:!1,error:"Passphrase must include at least one number."}:{ok:!1,error:"Passphrase must include at least one lowercase letter."}:{ok:!1,error:"Passphrase must include at least one uppercase letter."}}var Tr=["password","passphrase","letmein","welcome","monkey","dragon","qwerty","qwertyuiop","asdfgh","zxcvbn","iloveyou","sunshine","princess","football","baseball","superman","batman","master","shadow","michael","jennifer","trustno","starwars","whatever","freedom","computer","internet","samsung","google","facebook","admin","administrator","root","changeme","secret","default","login","abc","test","temp","demo","company","corporate"];function Cr(e){return e.toLowerCase().replace(/[@4]/g,"a").replace(/[3]/g,"e").replace(/[1!|]/g,"i").replace(/[0]/g,"o").replace(/[5$]/g,"s").replace(/[7]/g,"t")}function Pr(e){let t=e.toLowerCase();if(/^(.)\1+$/.test(t))return!0;let n=["abcdefghijklmnopqrstuvwxyz","0123456789","qwertyuiopasdfghjklzxcvbnm"],a=t.replace(/[^a-z0-9]/g,"");if(a.length>=6){for(let o of n)if(o.includes(a)||[...o].reverse().join("").includes(a))return!0}return!1}function _r(e){let t=ot(e);if(!t.ok)return t;let a=Cr(e).replace(/[^a-z]/g,"");for(let o of Tr)if(a===o||a.startsWith(o)||a.endsWith(o))return{ok:!1,error:"That passphrase is built on a word attackers try first. Because the server stores a verifier for this key, a guessable passphrase can be cracked offline \u2014 pick something unrelated to a common word."};return Pr(e)?{ok:!1,error:"That passphrase is a repeated character or a keyboard sequence. Pick something without a predictable pattern."}:new Set(e).size<8?{ok:!1,error:"That passphrase reuses too few distinct characters. Use at least eight different ones."}:{ok:!0}}function at(e){return!e||typeof e!="object"?!1:e.version===2}function st(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.encryptedKey=="string"&&t.encryptedKey.length>0&&typeof t.iv=="string"&&t.iv.length>0&&typeof t.salt=="string"&&t.salt.length>0}function Ur(e){return at(e)?e:st(e)?{version:2,passphrase:e}:null}function B(e){let t=new ArrayBuffer(e.byteLength);return new Uint8Array(t).set(e),t}function ye(e){let t="";for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function xe(e){let t=atob(e),n=new Uint8Array(t.length);for(let a=0;a<t.length;a++)n[a]=t.charCodeAt(a);return n}function it(e){let t=new Uint8Array(e);return crypto.getRandomValues(t),t}var ee=32,Hr=256,vr=12;function Lr(){return it(ee)}async function ct(e){if(e.byteLength===0)throw new Error("PRF output is empty");let t=await crypto.subtle.digest("SHA-256",B(e));return crypto.subtle.importKey("raw",t,{name:"AES-GCM",length:Hr},!1,["encrypt","decrypt"])}async function Or(e,t,n,a,o){if(e.byteLength!==32)throw new Error("HMAC key must be 32 bytes");if(t.byteLength!==ee)throw new Error("PRF output must be 32 bytes");if(n.byteLength!==ee)throw new Error("PRF salt must be 32 bytes");if(!a)throw new Error("credentialId is required");let s=await ct(t),i=it(vr),c=await crypto.subtle.encrypt({name:"AES-GCM",iv:B(i)},s,B(e)),d={credentialId:a,prfSalt:ye(n),iv:ye(i),ciphertext:ye(new Uint8Array(c)),createdAt:Date.now()};return o&&o.trim().length>0&&(d.label=o.trim().slice(0,64)),d}async function Nr(e,t){if(t.byteLength!==ee)throw new Error("PRF output must be 32 bytes");let n=await ct(t),a=xe(e.iv),o=xe(e.ciphertext),s=await crypto.subtle.decrypt({name:"AES-GCM",iv:B(a)},n,B(o)),i=new Uint8Array(s);if(i.byteLength!==32)throw i.fill(0),new Error("Invalid HMAC key material");return i}function Gr(e){return xe(e.prfSalt)}function Br(e,t){let a=(e?.passkey??[]).filter(o=>o.credentialId!==t.credentialId);return{version:2,passphrase:e?.passphrase,passkey:[...a,t]}}function Fr(e,t){let n=e?.passkey??[];return{version:2,passphrase:e?.passphrase,passkey:n.filter(a=>a.credentialId!==t)}}function Wr(e,t){return e?.passkey?.find(n=>n.credentialId===t)}function Vr(e){let t=e.split(/\r?\n/),n=[];for(let a of t)a.startsWith("+++")||a.startsWith("---")||a.startsWith("+")&&!a.startsWith("+++")&&n.push(a.slice(1));return n.join(`
4
- `)}var lt="redaktyn-scan-prefilter-v1",dt="v1.",pt=65535,F=Math.imul,Ie=pt+1,ut=/^v1\.[0-9a-f]{12}$/;function ht(e){if(e.length<4)throw new Error("scanPrefilterParams: seed too short");return{base:e[0]<<24|e[1]<<16|e[2]<<8|e[3]|1}}function ft(e){return y(T,e,b(lt))}function Kr(e){return(e>=65&&e<=90?e+32:e)+1}function mt(e){let t=new Int32Array(e.length);for(let n=0;n<e.length;n++)t[n]=Kr(e.charCodeAt(n));return t}function zr(e,t){let n=1,a=e|0,o=t;for(;o>0;)o&1&&(n=F(n,a)),a=F(a,a),o>>>=1;return n}function gt(e,t,n,a){let o=0;for(let s=n;s<n+a;s++)o=F(o,e)+t[s]|0;return o}function te(e,t){return gt(e.base,mt(t),0,t.length)>>>16}function Yr(e,t,n){let a=e.base,o=zr(a,n-1),s=-2,i=0;return c=>(c===s+1?i=F(i-F(t[s],o)|0,a)+t[s+n]|0:i=gt(a,t,c,n),s=c,i>>>16)}function Ae(e){return(e&pt).toString(16).padStart(4,"0")}function Et(e,t){return dt+Ae(te(e,t.exact))+Ae(te(e,t.collapsed))+Ae(te(e,t.lower))}function jr(e,t){return Et(ht(ft(t)),{exact:X(e),collapsed:N(G(e)),lower:Z(e)})}function ke(e){if(typeof e!="string"||!ut.test(e))return null;let t=e.slice(dt.length);return{exact:parseInt(t.slice(0,4),16),collapsed:parseInt(t.slice(4,8),16),lower:parseInt(t.slice(8,12),16)}}var ne=15e5,W=5*1024*1024,bt=256,yt=5e4,xt=1e4;function At(e){return ke(e.scanPrefilter)!==null}function Se(e,t=!1){let n=[new Map,new Map,new Map],a=(o,s,i)=>{if(typeof s!="number"||!(s>0))return;let c=n[o].get(s);n[o].set(s,c?{windowLen:s,prefiltered:c.prefiltered&&i,entries:c.entries+1}:{windowLen:s,prefiltered:i,entries:1})};for(let o of e){let s=t||At(o);a(0,o.length,s),a(1,o.lengthStripped,s),a(2,o.lengthLower,s)}return n.flatMap(o=>[...o.values()])}function Me(e,t){let n=0;for(let a of t){let o=Math.max(0,e-a.windowLen+1);n+=a.prefiltered?Math.ceil(o/bt)+Math.ceil(o*a.entries/Ie):o}return n}function re(e){if(e.length===0)return 1/0;if(Me(W,e)<=ne)return W;let t=0,n=W;for(;t<n;){let a=Math.ceil((t+n)/2);Me(a,e)<=ne?t=a:n=a-1}return t}function $r(e){let t=new Set,n=new Set,a=new Set;for(let o of e)o.length>0&&t.add(o.length),typeof o.lengthStripped=="number"&&o.lengthStripped>0&&n.add(o.lengthStripped),typeof o.lengthLower=="number"&&o.lengthLower>0&&a.add(o.lengthLower);return[...t,...n,...a]}function qr(e){let t=e.length;if(t===0)return 1/0;let n=e.reduce((a,o)=>a+o,0);return Math.max(0,Math.floor((ne+n-t)/t))}function Jr(e){let t=Se(e),n=re(t),o={windowLen:t.length?Math.round(t.reduce((i,c)=>i+c.windowLen,0)/t.length):40,prefiltered:!0,entries:1},s=re([...t,o,o,o]);return{windowLengths:t.length,maxPasteChars:n,severity:n<xt?"alarm":n<yt?"warn":"ok",maxPasteCharsAfterOneMore:s,legacySecrets:e.filter(i=>!At(i)).length,maxPasteCharsIfReenrolled:re(Se(e,!0)),atCharacterCap:n===W}}var ro=200;var De={"stripe-live-secret":"Stripe live secret key","stripe-restricted-live":"Stripe restricted live key","stripe-test":"Stripe test key","stripe-publishable":"Stripe publishable key","github-pat":"GitHub personal access token","github-oauth":"GitHub OAuth token","github-app":"GitHub app token","github-fine-grained":"GitHub fine-grained token","npm-token":"npm access token","aws-access-key-id":"AWS access key ID","google-api-key":"Google API key","anthropic-api-key":"Anthropic API key","openai-api-key":"OpenAI API key","gitlab-pat":"GitLab personal access token","slack-token":"Slack token","slack-app-token":"Slack app token","shopify-token":"Shopify access token","digitalocean-token":"DigitalOcean token","huggingface-token":"Hugging Face token","stripe-webhook-secret":"Stripe webhook signing secret","openrouter-api-key":"OpenRouter API key","groq-api-key":"Groq API key","xai-api-key":"xAI API key","perplexity-api-key":"Perplexity API key","replicate-token":"Replicate API token","google-oauth-client-secret":"Google OAuth client secret","azure-ad-client-secret":"Azure AD client secret","gitlab-token":"GitLab token","slack-webhook":"Slack webhook URL","discord-webhook":"Discord webhook URL","discord-bot-token":"Discord bot token","telegram-bot-token":"Telegram bot token","sendgrid-api-key":"SendGrid API key","twilio-api-key":"Twilio API key","mailgun-api-key":"Mailgun API key","mailchimp-api-key":"Mailchimp API key","pypi-token":"PyPI upload token","docker-hub-token":"Docker Hub access token","vault-token":"HashiCorp Vault token","terraform-cloud-token":"Terraform Cloud token","doppler-token":"Doppler token","linear-api-key":"Linear API key","notion-token":"Notion integration token","airtable-token":"Airtable personal access token","atlassian-api-token":"Atlassian API token","square-token":"Square access token","sentry-token":"Sentry auth token","new-relic-key":"New Relic API key","grafana-token":"Grafana token","postman-api-key":"Postman API key","supabase-token":"Supabase secret key","supabase-publishable":"Supabase publishable key","netlify-token":"Netlify access token","age-secret-key":"age secret key","private-key":"Private key","connection-string-password":"Password in a connection string","neon-db-password":"Neon database password","assigned-secret":"Value assigned to a credential name","aws-secret-access-key":"AWS secret access key","aws-session-token":"AWS session token","gcp-service-account-key":"Google Cloud service-account key","azure-storage-key":"Azure storage account key","cloudflare-api-token":"Cloudflare API token","cloud-provider-token":"Cloud platform token","hyperscaler-access-key":"Cloud access key (Alibaba, Tencent, IBM, Oracle)","bitbucket-token":"Bitbucket token","ci-token":"CI/CD token","package-registry-token":"Package registry token","pulumi-token":"Pulumi access token","managed-db-token":"Managed database token","jdbc-ado-password":"Password in a JDBC or ADO.NET connection string","warehouse-credential":"Data warehouse credential","payment-provider-secret":"Payment gateway secret","commerce-token":"Commerce platform token","llm-provider-key":"AI provider API key","email-provider-key":"Email provider key","sms-provider-secret":"SMS or voice provider secret","productivity-saas-token":"Productivity SaaS token","observability-key":"Monitoring or logging key","signing-secret":"Signing or encryption secret","oauth-client-secret":"OAuth client secret","long-lived-jwt":"Long-lived JWT","http-basic-auth":"HTTP basic-auth credentials","session-cookie":"Session cookie","config-password":"Password in configuration","crypto-wallet-secret":"Crypto wallet key or seed phrase","vpn-private-key":"VPN private key","env-file":"Secrets in an .env file","kubeconfig-credential":"Kubernetes config credential","k8s-secret-manifest":"Kubernetes Secret value","terraform-secret":"Secret in Terraform state or variables","credential-file":"Credentials file (.npmrc, .netrc, docker, git)","presigned-url":"Pre-signed URL that is still valid","payment-card-number":"Payment card number","aadhaar-number":"Aadhaar number","india-tax-id":"PAN or personal GSTIN","national-id-number":"SSN or National Insurance number","bank-account-details":"Bank account details","customer-data-dump":"Customer data export"},It=Object.keys(De),V="unrecognised",Xr="assigned-secret",kt=[...It,V];function Zr(e){return kt.includes(e)}function Qr(e){return e===V?"Unrecognised credential":De[e]??e}var St={credential:"Credentials",infra:"Infrastructure",pii:"Personal data"},en={credential:"Keys, tokens and passwords that grant access to something. An admin can protect one on the spot, and the next paste of it is blocked.",infra:"Files that carry credentials in bulk \u2014 an .env dump, a kubeconfig, a Terraform state file. One paste can hand over a whole environment.",pii:"Card, identity and bank numbers that belong to people, not to the org. Never protected, only removed from the message."},tn={checksum:"Checksum verified",structure:"Structure decoded",prefix:"Provider format",context:"Named and random"},l=(e,t,n,a,o)=>({id:e,family:t,name:n,slugs:a,...o}),we=[l(1,"credential","AWS access keys",["aws-access-key-id","aws-secret-access-key"],{proof:"prefix",catches:"AKIA\u2026 access key IDs, and the 40-character secret access key beside them in a credentials file, an env var or a chat message.",ignores:"AWS's documented example keys (AKIAIOSFODNN7EXAMPLE), ARNs and account IDs."}),l(2,"credential","AWS session tokens",["aws-session-token"],{proof:"prefix",catches:"Temporary STS session tokens (IQoJb3JpZ2lu\u2026, FwoGZXIvYXdz\u2026) copied out of a console or a CLI profile.",ignores:"Tokens cut short with an ellipsis, and placeholders."}),l(3,"credential","Google Cloud credentials",["gcp-service-account-key","google-api-key"],{proof:"structure",catches:"Service-account JSON files whose private key is a real key, and AIza\u2026 API keys.",ignores:"Service-account JSON with a truncated or random-filler private key, and AIza followed by filler."}),l(4,"credential","Azure storage keys",["azure-storage-key"],{proof:"context",catches:"AccountKey= and SharedAccessKey= inside Azure Storage, Service Bus and Event Hubs connection strings.",ignores:"The public Azurite emulator key (devstoreaccount1) and <your-account-key> placeholders."}),l(5,"credential","Azure AD client secrets",["azure-ad-client-secret"],{proof:"prefix",catches:"Entra ID app client secrets \u2014 the 40-character values with Q~ at position four.",ignores:"Tenant and client IDs, which are GUIDs and not secret."}),l(6,"credential","Cloudflare tokens",["cloudflare-api-token"],{proof:"context",catches:"Cloudflare API tokens assigned to a Cloudflare variable, and v1.0- origin CA keys.",ignores:"Zone and account IDs."}),l(7,"credential","Developer cloud tokens",["digitalocean-token","netlify-token","cloud-provider-token"],{proof:"prefix",catches:"DigitalOcean (dop_v1_), Netlify (nfp_), Heroku (HRKU-), Fly.io (fo1_), Render (rnd_) and Vercel tokens.",ignores:"App names and region settings, and tokens made of filler characters."}),l(8,"credential","Other cloud access keys",["hyperscaler-access-key"],{proof:"prefix",catches:"Alibaba Cloud (LTAI\u2026), Tencent Cloud (AKID\u2026) and IBM Cloud API keys.",ignores:"Region names and other configuration that sits next to them."}),l(9,"credential","GitHub tokens",["github-pat","github-oauth","github-app","github-fine-grained"],{proof:"checksum",catches:"Classic and fine-grained personal access tokens, OAuth tokens and app tokens (ghp_, gho_, ghs_, github_pat_) \u2014 each carries a CRC32 checksum, and it has to verify.",ignores:"Strings shaped like a GitHub token whose checksum fails, ${{ secrets.GITHUB_TOKEN }} references, and repository URLs."}),l(10,"credential","GitLab tokens",["gitlab-pat","gitlab-token"],{proof:"prefix",catches:"GitLab personal access tokens (glpat-) and runner tokens (glrt-).",ignores:"GitLab URLs and filler tokens."}),l(11,"credential","Bitbucket and Atlassian tokens",["atlassian-api-token","bitbucket-token"],{proof:"prefix",catches:"Atlassian API tokens (ATATT\u2026), Bitbucket app passwords and access tokens (ATBB\u2026).",ignores:"Jira and Confluence site URLs."}),l(12,"credential","CI/CD tokens",["ci-token"],{proof:"prefix",catches:"CircleCI (CCIPAT_), Buildkite (bkua_) and Jenkins API tokens.",ignores:"Build numbers, job URLs and pipeline names."}),l(13,"credential","Package registry tokens",["npm-token","pypi-token","docker-hub-token","package-registry-token"],{proof:"checksum",catches:"npm tokens (npm_, checksum-verified), PyPI upload tokens, Docker Hub PATs (dckr_pat_), RubyGems and NuGet keys.",ignores:"npm-shaped tokens whose checksum fails, and registry URLs."}),l(14,"credential","Infrastructure-as-code and secret-manager tokens",["vault-token","terraform-cloud-token","doppler-token","pulumi-token"],{proof:"prefix",catches:"HashiCorp Vault tokens (hvs.), Terraform Cloud tokens (.atlasv1.), Doppler (dp.st.) and Pulumi (pul-) tokens.",ignores:"Vault addresses and workspace names."}),l(15,"credential","Database connection strings",["connection-string-password"],{proof:"context",catches:"The password inside a postgres://, mysql://, mongodb+srv://, redis:// or amqp:// URL pointing at a real host.",ignores:"localhost and example.com hosts, user:password, ${DB_PASSWORD} references and <password> placeholders."}),l(16,"credential","Managed database tokens",["neon-db-password","supabase-token","supabase-publishable","managed-db-token"],{proof:"prefix",catches:"Neon passwords (npg_), Supabase service and secret keys (sbp_, sb_secret_), PlanetScale and Upstash tokens.",ignores:"Supabase publishable keys, which are meant to be public, and project IDs."}),l(17,"credential","JDBC and ADO.NET passwords",["jdbc-ado-password"],{proof:"context",catches:"password= and Password= inside JDBC URLs and SQL Server / ADO.NET connection strings.",ignores:"Password=password, ${SA_PASSWORD} and <your_password>."}),l(18,"credential","Data warehouse credentials",["warehouse-credential"],{proof:"prefix",catches:"Databricks tokens (dapi\u2026), and Snowflake and ClickHouse passwords.",ignores:"Account locators and warehouse names."}),l(19,"credential","Stripe keys",["stripe-live-secret","stripe-restricted-live","stripe-webhook-secret","stripe-test","stripe-publishable"],{proof:"prefix",catches:"Live secret keys (sk_live_), restricted live keys (rk_live_) and webhook signing secrets (whsec_).",ignores:"Test-mode keys, publishable keys (pk_), which are public, and keys cut short with an ellipsis."}),l(20,"credential","Payment gateway secrets",["square-token","payment-provider-secret"],{proof:"prefix",catches:"Square access tokens, Braintree production tokens, Plaid production secrets, Razorpay key secrets and PayPal client secrets.",ignores:"Razorpay key IDs on their own, test-mode and sandbox keys."}),l(21,"credential","Commerce platform tokens",["shopify-token","commerce-token"],{proof:"prefix",catches:"Shopify admin tokens (shpat_), WooCommerce consumer keys (ck_) and BigCommerce access tokens.",ignores:"Store domains and all-zero filler tokens."}),l(22,"credential","OpenAI keys",["openai-api-key"],{proof:"prefix",catches:"Project keys (sk-proj-\u2026 with the T3BlbkFJ marker) and legacy sk- keys.",ignores:"Model names, sk-abcdef\u2026 keyboard strings and keys masked as sk-\u2026a1B2."}),l(23,"credential","Anthropic keys",["anthropic-api-key"],{proof:"prefix",catches:"Anthropic API keys (sk-ant-api03-\u2026AA).",ignores:"Model names and sk-ant-\u2026 placeholders."}),l(24,"credential","Other AI provider keys",["groq-api-key","xai-api-key","perplexity-api-key","replicate-token","huggingface-token","openrouter-api-key","llm-provider-key"],{proof:"prefix",catches:"Groq, xAI, Perplexity, Replicate, Hugging Face, OpenRouter, DeepSeek, LangSmith and Mistral keys.",ignores:"Cache paths like HF_HOME and filler tokens."}),l(25,"credential","Slack tokens and webhooks",["slack-token","slack-app-token","slack-webhook"],{proof:"prefix",catches:"Bot, user and app tokens (xoxb-, xoxp-, xapp-) and incoming webhook URLs.",ignores:"xoxb-your-bot-token and channel names."}),l(26,"credential","Discord and Telegram bots",["discord-webhook","discord-bot-token","telegram-bot-token"],{proof:"structure",catches:"Discord webhook URLs and bot tokens, and Telegram bot tokens (a bot ID, a colon, then AA\u2026).",ignores:"Guild and channel IDs."}),l(27,"credential","Email provider keys",["sendgrid-api-key","mailgun-api-key","mailchimp-api-key","email-provider-key"],{proof:"prefix",catches:"SendGrid (SG.), Mailgun (key-), Mailchimp (\u2026-us1), Resend (re_), Brevo (xkeysib-) and Postmark keys.",ignores:"SMTP hosts and sender addresses."}),l(28,"credential","SMS and voice provider secrets",["twilio-api-key","sms-provider-secret"],{proof:"context",catches:"Twilio API keys (SK\u2026) and auth tokens, and MSG91 auth keys.",ignores:"Account SIDs and phone numbers on their own."}),l(29,"credential","Productivity SaaS tokens",["linear-api-key","notion-token","airtable-token","postman-api-key","productivity-saas-token"],{proof:"prefix",catches:"Linear, Notion, Airtable, Postman, HubSpot, Figma, Asana and Zendesk tokens.",ignores:"Database and page IDs, which are not secret."}),l(30,"credential","Monitoring and logging keys",["sentry-token","new-relic-key","grafana-token","observability-key"],{proof:"prefix",catches:"Sentry auth tokens, New Relic (NRAK-), Grafana service accounts (glsa_), Dynatrace, PostHog personal keys and Datadog API keys.",ignores:"Sentry DSNs and PostHog project keys, which are designed to ship in browser code."}),l(31,"credential","Private keys (PEM, OpenSSH, PGP)",["private-key"],{proof:"structure",catches:"RSA, EC, PKCS#8, OpenSSH and PGP private key blocks whose body decodes to a real key.",ignores:"Public keys and certificates, key blocks with ... for a body, and blocks filled with random text."}),l(32,"credential","Signing and encryption secrets",["signing-secret"],{proof:"context",catches:"JWT_SECRET, SECRET_KEY_BASE, NEXTAUTH_SECRET, Django SECRET_KEY and similar, when the value is random.",ignores:"changeme, algorithm names like HS256 and expiry settings."}),l(33,"credential","OAuth client secrets",["google-oauth-client-secret","oauth-client-secret"],{proof:"prefix",catches:"Google client secrets (GOCSPX-) and refresh tokens, and Okta, Auth0 and generic client_secret values.",ignores:"Client IDs, which are public."}),l(34,"credential","Long-lived JWTs",["long-lived-jwt"],{proof:"structure",catches:"Signed JWTs that are still valid for a long time \u2014 service-role keys, service-account tokens, tokens that never expire.",ignores:"Expired tokens, short-lived session tokens, Supabase anon keys and the jwt.io sample token."}),l(35,"credential","Basic auth and session cookies",["http-basic-auth","session-cookie"],{proof:"structure",catches:"Authorization: Basic headers that decode to user:password, curl -u credentials, and login session cookies.",ignores:"Analytics and preference cookies, and user:pass examples."}),l(36,"credential","Passwords in configuration",["config-password","assigned-secret"],{proof:"context",catches:"Values assigned to DB_PASSWORD, API_TOKEN, password: and their kin in env files, YAML and code, when they are random enough to be real.",ignores:"********, length settings, keyboard walks like qwertyuiop123, and placeholders."}),l(37,"credential","Crypto wallet keys and seed phrases",["crypto-wallet-secret"],{proof:"checksum",catches:"BIP39 recovery phrases whose checksum word verifies, WIF and xprv keys (Base58Check) and raw Ethereum private keys.",ignores:"The abandon \u2026 about test phrase, Hardhat's published dev keys, and wallet addresses."}),l(38,"credential","age and WireGuard keys",["age-secret-key","vpn-private-key"],{proof:"structure",catches:"age secret keys (AGE-SECRET-KEY-1\u2026) and the PrivateKey of a WireGuard [Interface].",ignores:"WireGuard peer public keys."}),l(39,"infra",".env files",["env-file"],{proof:"context",catches:"A pasted .env file with real secrets in it, flagged as one file rather than line by line.",ignores:".env files with only settings, ${VAR} references or your_key_here placeholders."}),l(40,"infra","Kubernetes configs",["kubeconfig-credential"],{proof:"structure",catches:"kubeconfig files carrying a client key or a bearer token for a cluster.",ignores:"kubeconfigs that authenticate through an exec plugin, and REDACTED tokens."}),l(41,"infra","Kubernetes Secret manifests",["k8s-secret-manifest"],{proof:"structure",catches:"kind: Secret manifests \u2014 the base64 under data: is decoded and checked, and stringData: is read as is.",ignores:"Secrets that decode to password or admin, and certificates."}),l(42,"infra","Terraform state and variables",["terraform-secret"],{proof:"structure",catches:"Passwords in terraform.tfstate attributes and hard-coded in .tf resources.",ignores:"null attributes and var.db_password references."}),l(43,"infra","Credential files",["credential-file"],{proof:"structure",catches:".netrc logins, Docker config.json auths, .pgpass lines and tokens embedded in git remote URLs.",ignores:"example.com entries, user:password auths and plain clone URLs."}),l(44,"infra","Pre-signed URLs",["presigned-url"],{proof:"structure",catches:"S3 pre-signed and Azure SAS URLs that have not expired yet \u2014 anyone holding one can read the file.",ignores:"Expired links, unsigned URLs and documentation pages."}),l(45,"pii","Payment card numbers",["payment-card-number"],{proof:"checksum",catches:"Visa, Mastercard, Amex, RuPay and other card numbers that pass the Luhn check and sit next to a card label, an expiry or a card network name.",ignores:"Published test cards (4242\u2026, 4111\u2026), order IDs and numbers that fail Luhn."}),l(46,"pii","Aadhaar numbers",["aadhaar-number"],{proof:"checksum",catches:"Aadhaar numbers that pass the Verhoeff check, labelled or in the 4-4-4 grouping.",ignores:"UIDAI's sample numbers, transaction references and numbers that fail Verhoeff."}),l(47,"pii","PAN and GSTIN",["india-tax-id"],{proof:"checksum",catches:"Individual PANs and GSTINs whose check character verifies.",ignores:"Company PANs, unlabelled lookalikes and GSTINs with a wrong check character."}),l(48,"pii","SSN and National Insurance numbers",["national-id-number"],{proof:"structure",catches:"US Social Security numbers and UK National Insurance numbers that follow the issuing rules and are labelled or listed.",ignores:"Numbers never issued (000, 666, 9xx areas), the famous Woolworth card number, and part numbers."}),l(49,"pii","Bank account details",["bank-account-details"],{proof:"checksum",catches:"IBANs that pass mod-97, and account numbers next to a valid ABA routing number or an IFSC code.",ignores:"Published example IBANs, IBANs with a wrong check digit and IFSC codes alone."}),l(50,"pii","Customer data exports",["customer-data-dump"],{proof:"context",catches:"Pasted tables of real people \u2014 rows with names, personal email addresses and phone numbers.",ignores:"example.com addresses, 555 phone numbers, short lists and staff email lists."})],rn=["Placeholders \u2014 <your-key>, ${VAR}, {{ secret }}, xxxx, changeme, your_key_here","Values cut short or masked \u2014 sk_live_\u2026, ****, REDACTED","Anything marked fake, mock, dummy, stub, fixture or sample \u2014 in a comment beside it or in its variable name","Vendors' published example and test keys","Variable names, file paths, URLs, hashes, UUIDs and regex source","Public keys, publishable keys and IDs that are not secret"],Re=new Map;for(let e of we)for(let t of e.slugs)Re.set(t,e);function nn(e){return Re.get(e)}function Mt(e){return e===V?"credential":Re.get(e)?.family??"credential"}function on(e){return Mt(e)!=="pii"}function an(e){return St[e]}var sn=we.flatMap(e=>e.slugs);function Dt(e){let t=new Set;for(let n of e)if(n?.isActive)for(let a of n.rules??[])for(let o of a?.specificDomains??[]){let s=fe(o);s&&t.add(s)}return Array.from(t).sort()}function cn(e){return Dt(e).filter(t=>!he(t))}0&&(module.exports={AIToolCategory,AI_REGISTRY,ANNUAL_MONTHS_FREE,ASSIGNED_SECRET_SLUG,AlertChannel,AlertTrigger,CATEGORISED_SLUGS,COVERAGE_SLUGS,DETECTION_CATEGORIES,DETECTION_FAMILY_BLURBS,DETECTION_FAMILY_NAMES,DETECTION_PROOF_NAMES,DETECTION_UNIVERSAL_IGNORES,DIGEST_VERSION_HMAC_V1,ENTERPRISE_FEATURES,EventAction,EventType,FREE_FEATURES,FREE_SEATS,INVISIBLE_CHARS_CLASS,KDF_ITERATIONS,KDF_VERSION_V2,MATRIX_TIERS,MAX_ACTIVITY_SESSIONS_PER_BATCH,MAX_SCAN_WINDOWS,MAX_TOTAL_SCAN_CHARS,MIN_SECRET_LENGTH,NORMALIZATION_VERSION_V1,NORMALIZATION_VERSION_V2,OrgPlan,PASSPHRASE_VERIFY_LABEL,PASTE_CEILING_ALARM_CHARS,PASTE_CEILING_WARN_CHARS,PLAN_DESCRIPTORS,PLAN_FEATURE_MATRIX,PLAN_FEATURE_TIERS,PLAN_LIMITS,PLAN_PRICING,PRIVACY_EMAIL,PROJECT_KDF_LABEL,PRO_BANDS,PRO_ENTRY_BAND,PRO_FEATURES,PRO_TOP_BAND,RiskLevel,SAFE_BLOCK_EVENT_FIELDS,SALES_EMAIL,SCAN_PREFILTER_LABEL,SCAN_PREFILTER_PATTERN,SCAN_PREFILTER_SPACE,SCAN_PREFILTER_WINDOWS_PER_SIGNATURE,SECRET_PROVIDER_NAMES,SECRET_PROVIDER_SLUGS,SECURITY_EMAIL,TRIAL_DAYS,UNRECOGNISED_PROVIDER_SLUG,UserRole,annualBilledNote,appendPasskeyEnvelope,behaviorExplanation,canonicalSecretPlaintextForHmac,categoryOfSlug,computePassphraseVerifyHmac,customPolicyDomains,decodeScanPrefilter,deriveBehaviorRisk,deriveHmacKeyFromPassphrase,deriveProjectKey,deriveScanPrefilterSeed,encodeScanPrefilter,extractAddedLinesFromUnifiedDiff,familyDisplayName,familyOfSlug,findBand,findPasskeyEnvelope,foldUuidHexCase,generateHmacKey,generatePrfSalt,getInjectionHostnames,getLimitsForPlan,getPrfSaltBytes,hexToKey,hmacDigestHex,isAIToolDomain,isInjectionScopedHostname,isKnownProviderSlug,isProtectableSlug,isV1PassphraseEnvelope,isV2Envelope,keyToHex,matchDomain,matchPatternsForHostname,maxScannablePasteChars,maxScannablePasteCharsFor,normalizeAndHmacHex,normalizeAndHmacHexCollapsed,normalizeAndHmacHexLower,normalizeDomainInput,normalizeSecretPlaintextCollapsed,normalizeSecretPlaintextForMatch,normalizeSecretPlaintextLower,perMonthOnAnnual,policyNamedDomains,projectedScanCost,providerDisplayName,removePasskeyEnvelope,scanBudgetFor,scanPrefilterFingerprint,scanPrefilterForRawSecret,scanPrefilterParams,scanPrefilterRoller,scanPrefilterUnits,scanSweeps,scanWindowLengths,smallestBandFor,unwrapHmacKeyWithPrf,upgradeEnvelopeToV2,usd,validateNewPassphrase,validatePassphraseStrength,wrapHmacKeyWithPrf});
3
+ `),t=t.replace(Mr,""),t=t.trim(),t}function O(e){if(e.length===36&&e[8]==="-"&&e[13]==="-"&&e[18]==="-"&&e[23]==="-"){let t=e.replace(/-/g,"");if(/^[0-9a-fA-F]{32}$/.test(t))return e.toLowerCase()}return e}function X(e){return O(Ae(e))}function G(e){return Ae(e).replace(/\s/g,"")}function Dr(e,t){return Q(O(G(e)),t)}function Z(e){return G(e).toLowerCase()}function Rr(e,t){return Q(Z(e),t)}function Q(e,t){return j(y(T,t,b(e)))}function wr(e,t){return Q(X(e),t)}async function Tr(e,t){let n=b(e),o=T(b(t));return rt(T,n,o,{c:at,dkLen:xe})}var it="redaktyn-project-key-v1",Cr=b(it);function Pr(e,t){if(e.length!==xe)throw new Error("deriveProjectKey: org key must be 32 bytes");if(!t)throw new Error("deriveProjectKey: projectId is required");return ot(T,e,b(t),Cr,xe)}var ct="vaultx-passphrase-verify-v1",_r=b(ct);function Ur(e){return j(y(T,e,_r))}function Hr(){return crypto.getRandomValues(new Uint8Array(32))}function vr(e){return j(e)}function Lr(e){return qe(e)}function lt(e){return e.length<12?{ok:!1,error:"Passphrase must be at least 12 characters."}:/[A-Z]/.test(e)?/[a-z]/.test(e)?/[0-9]/.test(e)?/[^A-Za-z0-9]/.test(e)?{ok:!0}:{ok:!1,error:"Passphrase must include at least one special character (e.g. !@#$%)."}:{ok:!1,error:"Passphrase must include at least one number."}:{ok:!1,error:"Passphrase must include at least one lowercase letter."}:{ok:!1,error:"Passphrase must include at least one uppercase letter."}}var Nr=["password","passphrase","letmein","welcome","monkey","dragon","qwerty","qwertyuiop","asdfgh","zxcvbn","iloveyou","sunshine","princess","football","baseball","superman","batman","master","shadow","michael","jennifer","trustno","starwars","whatever","freedom","computer","internet","samsung","google","facebook","admin","administrator","root","changeme","secret","default","login","abc","test","temp","demo","company","corporate"];function Or(e){return e.toLowerCase().replace(/[@4]/g,"a").replace(/[3]/g,"e").replace(/[1!|]/g,"i").replace(/[0]/g,"o").replace(/[5$]/g,"s").replace(/[7]/g,"t")}function Gr(e){let t=e.toLowerCase();if(/^(.)\1+$/.test(t))return!0;let n=["abcdefghijklmnopqrstuvwxyz","0123456789","qwertyuiopasdfghjklzxcvbnm"],o=t.replace(/[^a-z0-9]/g,"");if(o.length>=6){for(let a of n)if(a.includes(o)||[...a].reverse().join("").includes(o))return!0}return!1}function ee(e){let t=lt(e);if(!t.ok)return t;let o=Or(e).replace(/[^a-z]/g,"");for(let a of Nr)if(o===a||o.startsWith(a)||o.endsWith(a))return{ok:!1,error:"That passphrase is built on a word attackers try first. Because the server stores a verifier for this key, a guessable passphrase can be cracked offline \u2014 pick something unrelated to a common word."};return Gr(e)?{ok:!1,error:"That passphrase is a repeated character or a keyboard sequence. Pick something without a predictable pattern."}:new Set(e).size<8?{ok:!1,error:"That passphrase reuses too few distinct characters. Use at least eight different ones."}:{ok:!0}}var Br="ABCDEFGHJKLMNPQRSTUVWXYZ",Fr="abcdefghijkmnpqrstuvwxyz",Wr="23456789",re=Br+Fr+Wr,dt=5,Ie=5,Vr=128;function Kr(e){let t=256-256%e,n=new Uint8Array(1);for(;;){globalThis.crypto.getRandomValues(n);let o=n[0]??255;if(o<t)return o%e}}function zr(){let e=[];for(let t=0;t<dt;t++){let n="";for(let o=0;o<Ie;o++)n+=re[Kr(re.length)];e.push(n)}return e.join("-")}function Yr(){for(;;){let e=zr();if(!(!/[A-Z]/.test(e)||!/[a-z]/.test(e)||!/[0-9]/.test(e))&&ee(e).ok)return e}}function jr(e,t){return["Redaktyn workspace passphrase","",e,"",`Created ${t.toISOString().slice(0,10)}.`,"","This passphrase derives the key your workspace's fingerprints are made with.","Redaktyn never receives it, so nobody can reset it for you.","Move it into a password manager or a safe, then delete this file.",""].join(`
4
+ `)}var te="Redaktyn workspace",ke="https://passphrase.redaktyn.invalid/";function $r(e){return`"${e.replace(/"/g,'""')}"`}function qr(e){let t="Redaktyn workspace passphrase. Nobody can reset it. Delete this file after importing it.";for(let n of[te,ke,e,t])if(/^[=+\-@\t\r]/.test(n))throw new Error("A password-manager file field cannot start with a formula character");return["name,url,username,password,note",[te,ke,te,e,t].map($r).join(","),""].join(`
5
+ `)}var pt='A new workspace needs a generated passphrase. Because the server stores a verifier for this key, a passphrase a person chose can be guessed offline from a copy of the database. Use "Generate" to create one.',Jr=new RegExp(`^[${re}]{${Ie}}(?:-[${re}]{${Ie}}){${dt-1}}$`),Xr=12;function ut(e){if(!Jr.test(e))return!1;let t=e.replace(/-/g,"");return new Set(t).size>=Xr}function Zr(e){return ut(e)?ee(e):{ok:!1,error:pt}}function ht(e){return!e||typeof e!="object"?!1:e.version===2}function ft(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.encryptedKey=="string"&&t.encryptedKey.length>0&&typeof t.iv=="string"&&t.iv.length>0&&typeof t.salt=="string"&&t.salt.length>0}function Qr(e){return ht(e)?e:ft(e)?{version:2,passphrase:e}:null}function B(e){let t=new ArrayBuffer(e.byteLength);return new Uint8Array(t).set(e),t}function Se(e){let t="";for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function Me(e){let t=atob(e),n=new Uint8Array(t.length);for(let o=0;o<t.length;o++)n[o]=t.charCodeAt(o);return n}function mt(e){let t=new Uint8Array(e);return crypto.getRandomValues(t),t}var ne=32,en=256,tn=12;function rn(){return mt(ne)}async function gt(e){if(e.byteLength===0)throw new Error("PRF output is empty");let t=await crypto.subtle.digest("SHA-256",B(e));return crypto.subtle.importKey("raw",t,{name:"AES-GCM",length:en},!1,["encrypt","decrypt"])}async function nn(e,t,n,o,a){if(e.byteLength!==32)throw new Error("HMAC key must be 32 bytes");if(t.byteLength!==ne)throw new Error("PRF output must be 32 bytes");if(n.byteLength!==ne)throw new Error("PRF salt must be 32 bytes");if(!o)throw new Error("credentialId is required");let s=await gt(t),i=mt(tn),c=await crypto.subtle.encrypt({name:"AES-GCM",iv:B(i)},s,B(e)),d={credentialId:o,prfSalt:Se(n),iv:Se(i),ciphertext:Se(new Uint8Array(c)),createdAt:Date.now()};return a&&a.trim().length>0&&(d.label=a.trim().slice(0,64)),d}async function on(e,t){if(t.byteLength!==ne)throw new Error("PRF output must be 32 bytes");let n=await gt(t),o=Me(e.iv),a=Me(e.ciphertext),s=await crypto.subtle.decrypt({name:"AES-GCM",iv:B(o)},n,B(a)),i=new Uint8Array(s);if(i.byteLength!==32)throw i.fill(0),new Error("Invalid HMAC key material");return i}function an(e){return Me(e.prfSalt)}function sn(e,t){let o=(e?.passkey??[]).filter(a=>a.credentialId!==t.credentialId);return{version:2,passphrase:e?.passphrase,passkey:[...o,t]}}function cn(e,t){let n=e?.passkey??[];return{version:2,passphrase:e?.passphrase,passkey:n.filter(o=>o.credentialId!==t)}}function ln(e,t){return e?.passkey?.find(n=>n.credentialId===t)}function dn(e){let t=e.split(/\r?\n/),n=[];for(let o of t)o.startsWith("+++")||o.startsWith("---")||o.startsWith("+")&&!o.startsWith("+++")&&n.push(o.slice(1));return n.join(`
6
+ `)}var Et="redaktyn-scan-prefilter-v1",bt="v1.",yt=65535,F=Math.imul,Re=yt+1,xt=/^v1\.[0-9a-f]{12}$/;function At(e){if(e.length<4)throw new Error("scanPrefilterParams: seed too short");return{base:e[0]<<24|e[1]<<16|e[2]<<8|e[3]|1}}function It(e){return y(T,e,b(Et))}function pn(e){return(e>=65&&e<=90?e+32:e)+1}function kt(e){let t=new Int32Array(e.length);for(let n=0;n<e.length;n++)t[n]=pn(e.charCodeAt(n));return t}function un(e,t){let n=1,o=e|0,a=t;for(;a>0;)a&1&&(n=F(n,o)),o=F(o,o),a>>>=1;return n}function St(e,t,n,o){let a=0;for(let s=n;s<n+o;s++)a=F(a,e)+t[s]|0;return a}function oe(e,t){return St(e.base,kt(t),0,t.length)>>>16}function hn(e,t,n){let o=e.base,a=un(o,n-1),s=-2,i=0;return c=>(c===s+1?i=F(i-F(t[s],a)|0,o)+t[s+n]|0:i=St(o,t,c,n),s=c,i>>>16)}function De(e){return(e&yt).toString(16).padStart(4,"0")}function Mt(e,t){return bt+De(oe(e,t.exact))+De(oe(e,t.collapsed))+De(oe(e,t.lower))}function fn(e,t){return Mt(At(It(t)),{exact:X(e),collapsed:O(G(e)),lower:Z(e)})}function we(e){if(typeof e!="string"||!xt.test(e))return null;let t=e.slice(bt.length);return{exact:parseInt(t.slice(0,4),16),collapsed:parseInt(t.slice(4,8),16),lower:parseInt(t.slice(8,12),16)}}var se=15e5,W=5*1024*1024,Dt=256,Rt=5e4,wt=1e4;function Tt(e){return we(e.scanPrefilter)!==null}function Te(e,t=!1){let n=[new Map,new Map,new Map],o=(a,s,i)=>{if(typeof s!="number"||!(s>0))return;let c=n[a].get(s);n[a].set(s,c?{windowLen:s,prefiltered:c.prefiltered&&i,entries:c.entries+1}:{windowLen:s,prefiltered:i,entries:1})};for(let a of e){let s=t||Tt(a);o(0,a.length,s),o(1,a.lengthStripped,s),o(2,a.lengthLower,s)}return n.flatMap(a=>[...a.values()])}function Ce(e,t){let n=0;for(let o of t){let a=Math.max(0,e-o.windowLen+1);n+=o.prefiltered?Math.ceil(a/Dt)+Math.ceil(a*o.entries/Re):a}return n}function ae(e){if(e.length===0)return 1/0;if(Ce(W,e)<=se)return W;let t=0,n=W;for(;t<n;){let o=Math.ceil((t+n)/2);Ce(o,e)<=se?t=o:n=o-1}return t}function mn(e){let t=new Set,n=new Set,o=new Set;for(let a of e)a.length>0&&t.add(a.length),typeof a.lengthStripped=="number"&&a.lengthStripped>0&&n.add(a.lengthStripped),typeof a.lengthLower=="number"&&a.lengthLower>0&&o.add(a.lengthLower);return[...t,...n,...o]}function gn(e){let t=e.length;if(t===0)return 1/0;let n=e.reduce((o,a)=>o+a,0);return Math.max(0,Math.floor((se+n-t)/t))}function En(e){let t=Te(e),n=ae(t),a={windowLen:t.length?Math.round(t.reduce((i,c)=>i+c.windowLen,0)/t.length):40,prefiltered:!0,entries:1},s=ae([...t,a,a,a]);return{windowLengths:t.length,maxPasteChars:n,severity:n<wt?"alarm":n<Rt?"warn":"ok",maxPasteCharsAfterOneMore:s,legacySecrets:e.filter(i=>!Tt(i)).length,maxPasteCharsIfReenrolled:ae(Te(e,!0)),atCharacterCap:n===W}}var Mo=200;var Pe={"stripe-live-secret":"Stripe live secret key","stripe-restricted-live":"Stripe restricted live key","stripe-test":"Stripe test key","stripe-publishable":"Stripe publishable key","github-pat":"GitHub personal access token","github-oauth":"GitHub OAuth token","github-app":"GitHub app token","github-fine-grained":"GitHub fine-grained token","npm-token":"npm access token","aws-access-key-id":"AWS access key ID","google-api-key":"Google API key","anthropic-api-key":"Anthropic API key","openai-api-key":"OpenAI API key","gitlab-pat":"GitLab personal access token","slack-token":"Slack token","slack-app-token":"Slack app token","shopify-token":"Shopify access token","digitalocean-token":"DigitalOcean token","huggingface-token":"Hugging Face token","stripe-webhook-secret":"Stripe webhook signing secret","openrouter-api-key":"OpenRouter API key","groq-api-key":"Groq API key","xai-api-key":"xAI API key","perplexity-api-key":"Perplexity API key","replicate-token":"Replicate API token","google-oauth-client-secret":"Google OAuth client secret","azure-ad-client-secret":"Azure AD client secret","gitlab-token":"GitLab token","slack-webhook":"Slack webhook URL","discord-webhook":"Discord webhook URL","discord-bot-token":"Discord bot token","telegram-bot-token":"Telegram bot token","sendgrid-api-key":"SendGrid API key","twilio-api-key":"Twilio API key","mailgun-api-key":"Mailgun API key","mailchimp-api-key":"Mailchimp API key","pypi-token":"PyPI upload token","docker-hub-token":"Docker Hub access token","vault-token":"HashiCorp Vault token","terraform-cloud-token":"Terraform Cloud token","doppler-token":"Doppler token","linear-api-key":"Linear API key","notion-token":"Notion integration token","airtable-token":"Airtable personal access token","atlassian-api-token":"Atlassian API token","square-token":"Square access token","sentry-token":"Sentry auth token","new-relic-key":"New Relic API key","grafana-token":"Grafana token","postman-api-key":"Postman API key","supabase-token":"Supabase secret key","supabase-publishable":"Supabase publishable key","netlify-token":"Netlify access token","age-secret-key":"age secret key","private-key":"Private key","connection-string-password":"Password in a connection string","neon-db-password":"Neon database password","assigned-secret":"Value assigned to a credential name","aws-secret-access-key":"AWS secret access key","aws-session-token":"AWS session token","gcp-service-account-key":"Google Cloud service-account key","azure-storage-key":"Azure storage account key","cloudflare-api-token":"Cloudflare API token","cloud-provider-token":"Cloud platform token","hyperscaler-access-key":"Cloud access key (Alibaba, Tencent, IBM, Oracle)","bitbucket-token":"Bitbucket token","ci-token":"CI/CD token","package-registry-token":"Package registry token","pulumi-token":"Pulumi access token","managed-db-token":"Managed database token","jdbc-ado-password":"Password in a JDBC or ADO.NET connection string","warehouse-credential":"Data warehouse credential","payment-provider-secret":"Payment gateway secret","commerce-token":"Commerce platform token","llm-provider-key":"AI provider API key","email-provider-key":"Email provider key","sms-provider-secret":"SMS or voice provider secret","productivity-saas-token":"Productivity SaaS token","observability-key":"Monitoring or logging key","signing-secret":"Signing or encryption secret","oauth-client-secret":"OAuth client secret","long-lived-jwt":"Long-lived JWT","http-basic-auth":"HTTP basic-auth credentials","session-cookie":"Session cookie","config-password":"Password in configuration","crypto-wallet-secret":"Crypto wallet key or seed phrase","vpn-private-key":"VPN private key","env-file":"Secrets in an .env file","kubeconfig-credential":"Kubernetes config credential","k8s-secret-manifest":"Kubernetes Secret value","terraform-secret":"Secret in Terraform state or variables","credential-file":"Credentials file (.npmrc, .netrc, docker, git)","presigned-url":"Pre-signed URL that is still valid","payment-card-number":"Payment card number","aadhaar-number":"Aadhaar number","india-tax-id":"PAN or personal GSTIN","national-id-number":"SSN or National Insurance number","bank-account-details":"Bank account details","customer-data-dump":"Customer data export"},Ct=Object.keys(Pe),V="unrecognised",bn="assigned-secret",Pt=[...Ct,V];function yn(e){return Pt.includes(e)}function xn(e){return e===V?"Unrecognised credential":Pe[e]??e}var _t={credential:"Credentials",infra:"Infrastructure",pii:"Personal data"},An={credential:"Keys, tokens and passwords that grant access to something. An admin can protect one on the spot, and the next paste of it is blocked.",infra:"Files that carry credentials in bulk \u2014 an .env dump, a kubeconfig, a Terraform state file. One paste can hand over a whole environment.",pii:"Card, identity and bank numbers that belong to people, not to the org. Never protected, only removed from the message."},In={checksum:"Checksum verified",structure:"Structure decoded",prefix:"Provider format",context:"Named and random"},l=(e,t,n,o,a)=>({id:e,family:t,name:n,slugs:o,...a}),_e=[l(1,"credential","AWS access keys",["aws-access-key-id","aws-secret-access-key"],{proof:"prefix",catches:"AKIA\u2026 access key IDs, and the 40-character secret access key beside them in a credentials file, an env var or a chat message.",ignores:"AWS's documented example keys (AKIAIOSFODNN7EXAMPLE), ARNs and account IDs."}),l(2,"credential","AWS session tokens",["aws-session-token"],{proof:"prefix",catches:"Temporary STS session tokens (IQoJb3JpZ2lu\u2026, FwoGZXIvYXdz\u2026) copied out of a console or a CLI profile.",ignores:"Tokens cut short with an ellipsis, and placeholders."}),l(3,"credential","Google Cloud credentials",["gcp-service-account-key","google-api-key"],{proof:"structure",catches:"Service-account JSON files whose private key is a real key, and AIza\u2026 API keys.",ignores:"Service-account JSON with a truncated or random-filler private key, and AIza followed by filler."}),l(4,"credential","Azure storage keys",["azure-storage-key"],{proof:"context",catches:"AccountKey= and SharedAccessKey= inside Azure Storage, Service Bus and Event Hubs connection strings.",ignores:"The public Azurite emulator key (devstoreaccount1) and <your-account-key> placeholders."}),l(5,"credential","Azure AD client secrets",["azure-ad-client-secret"],{proof:"prefix",catches:"Entra ID app client secrets \u2014 the 40-character values with Q~ at position four.",ignores:"Tenant and client IDs, which are GUIDs and not secret."}),l(6,"credential","Cloudflare tokens",["cloudflare-api-token"],{proof:"context",catches:"Cloudflare API tokens assigned to a Cloudflare variable, and v1.0- origin CA keys.",ignores:"Zone and account IDs."}),l(7,"credential","Developer cloud tokens",["digitalocean-token","netlify-token","cloud-provider-token"],{proof:"prefix",catches:"DigitalOcean (dop_v1_), Netlify (nfp_), Heroku (HRKU-), Fly.io (fo1_), Render (rnd_) and Vercel tokens.",ignores:"App names and region settings, and tokens made of filler characters."}),l(8,"credential","Other cloud access keys",["hyperscaler-access-key"],{proof:"prefix",catches:"Alibaba Cloud (LTAI\u2026), Tencent Cloud (AKID\u2026) and IBM Cloud API keys.",ignores:"Region names and other configuration that sits next to them."}),l(9,"credential","GitHub tokens",["github-pat","github-oauth","github-app","github-fine-grained"],{proof:"checksum",catches:"Classic and fine-grained personal access tokens, OAuth tokens and app tokens (ghp_, gho_, ghs_, github_pat_) \u2014 each carries a CRC32 checksum, and it has to verify.",ignores:"Strings shaped like a GitHub token whose checksum fails, ${{ secrets.GITHUB_TOKEN }} references, and repository URLs."}),l(10,"credential","GitLab tokens",["gitlab-pat","gitlab-token"],{proof:"prefix",catches:"GitLab personal access tokens (glpat-) and runner tokens (glrt-).",ignores:"GitLab URLs and filler tokens."}),l(11,"credential","Bitbucket and Atlassian tokens",["atlassian-api-token","bitbucket-token"],{proof:"prefix",catches:"Atlassian API tokens (ATATT\u2026), Bitbucket app passwords and access tokens (ATBB\u2026).",ignores:"Jira and Confluence site URLs."}),l(12,"credential","CI/CD tokens",["ci-token"],{proof:"prefix",catches:"CircleCI (CCIPAT_), Buildkite (bkua_) and Jenkins API tokens.",ignores:"Build numbers, job URLs and pipeline names."}),l(13,"credential","Package registry tokens",["npm-token","pypi-token","docker-hub-token","package-registry-token"],{proof:"checksum",catches:"npm tokens (npm_, checksum-verified), PyPI upload tokens, Docker Hub PATs (dckr_pat_), RubyGems and NuGet keys.",ignores:"npm-shaped tokens whose checksum fails, and registry URLs."}),l(14,"credential","Infrastructure-as-code and secret-manager tokens",["vault-token","terraform-cloud-token","doppler-token","pulumi-token"],{proof:"prefix",catches:"HashiCorp Vault tokens (hvs.), Terraform Cloud tokens (.atlasv1.), Doppler (dp.st.) and Pulumi (pul-) tokens.",ignores:"Vault addresses and workspace names."}),l(15,"credential","Database connection strings",["connection-string-password"],{proof:"context",catches:"The password inside a postgres://, mysql://, mongodb+srv://, redis:// or amqp:// URL pointing at a real host.",ignores:"localhost and example.com hosts, user:password, ${DB_PASSWORD} references and <password> placeholders."}),l(16,"credential","Managed database tokens",["neon-db-password","supabase-token","supabase-publishable","managed-db-token"],{proof:"prefix",catches:"Neon passwords (npg_), Supabase service and secret keys (sbp_, sb_secret_), PlanetScale and Upstash tokens.",ignores:"Supabase publishable keys, which are meant to be public, and project IDs."}),l(17,"credential","JDBC and ADO.NET passwords",["jdbc-ado-password"],{proof:"context",catches:"password= and Password= inside JDBC URLs and SQL Server / ADO.NET connection strings.",ignores:"Password=password, ${SA_PASSWORD} and <your_password>."}),l(18,"credential","Data warehouse credentials",["warehouse-credential"],{proof:"prefix",catches:"Databricks tokens (dapi\u2026), and Snowflake and ClickHouse passwords.",ignores:"Account locators and warehouse names."}),l(19,"credential","Stripe keys",["stripe-live-secret","stripe-restricted-live","stripe-webhook-secret","stripe-test","stripe-publishable"],{proof:"prefix",catches:"Live secret keys (sk_live_), restricted live keys (rk_live_) and webhook signing secrets (whsec_).",ignores:"Test-mode keys, publishable keys (pk_), which are public, and keys cut short with an ellipsis."}),l(20,"credential","Payment gateway secrets",["square-token","payment-provider-secret"],{proof:"prefix",catches:"Square access tokens, Braintree production tokens, Plaid production secrets, Razorpay key secrets and PayPal client secrets.",ignores:"Razorpay key IDs on their own, test-mode and sandbox keys."}),l(21,"credential","Commerce platform tokens",["shopify-token","commerce-token"],{proof:"prefix",catches:"Shopify admin tokens (shpat_), WooCommerce consumer keys (ck_) and BigCommerce access tokens.",ignores:"Store domains and all-zero filler tokens."}),l(22,"credential","OpenAI keys",["openai-api-key"],{proof:"prefix",catches:"Project keys (sk-proj-\u2026 with the T3BlbkFJ marker) and legacy sk- keys.",ignores:"Model names, sk-abcdef\u2026 keyboard strings and keys masked as sk-\u2026a1B2."}),l(23,"credential","Anthropic keys",["anthropic-api-key"],{proof:"prefix",catches:"Anthropic API keys (sk-ant-api03-\u2026AA).",ignores:"Model names and sk-ant-\u2026 placeholders."}),l(24,"credential","Other AI provider keys",["groq-api-key","xai-api-key","perplexity-api-key","replicate-token","huggingface-token","openrouter-api-key","llm-provider-key"],{proof:"prefix",catches:"Groq, xAI, Perplexity, Replicate, Hugging Face, OpenRouter, DeepSeek, LangSmith and Mistral keys.",ignores:"Cache paths like HF_HOME and filler tokens."}),l(25,"credential","Slack tokens and webhooks",["slack-token","slack-app-token","slack-webhook"],{proof:"prefix",catches:"Bot, user and app tokens (xoxb-, xoxp-, xapp-) and incoming webhook URLs.",ignores:"xoxb-your-bot-token and channel names."}),l(26,"credential","Discord and Telegram bots",["discord-webhook","discord-bot-token","telegram-bot-token"],{proof:"structure",catches:"Discord webhook URLs and bot tokens, and Telegram bot tokens (a bot ID, a colon, then AA\u2026).",ignores:"Guild and channel IDs."}),l(27,"credential","Email provider keys",["sendgrid-api-key","mailgun-api-key","mailchimp-api-key","email-provider-key"],{proof:"prefix",catches:"SendGrid (SG.), Mailgun (key-), Mailchimp (\u2026-us1), Resend (re_), Brevo (xkeysib-) and Postmark keys.",ignores:"SMTP hosts and sender addresses."}),l(28,"credential","SMS and voice provider secrets",["twilio-api-key","sms-provider-secret"],{proof:"context",catches:"Twilio API keys (SK\u2026) and auth tokens, and MSG91 auth keys.",ignores:"Account SIDs and phone numbers on their own."}),l(29,"credential","Productivity SaaS tokens",["linear-api-key","notion-token","airtable-token","postman-api-key","productivity-saas-token"],{proof:"prefix",catches:"Linear, Notion, Airtable, Postman, HubSpot, Figma, Asana and Zendesk tokens.",ignores:"Database and page IDs, which are not secret."}),l(30,"credential","Monitoring and logging keys",["sentry-token","new-relic-key","grafana-token","observability-key"],{proof:"prefix",catches:"Sentry auth tokens, New Relic (NRAK-), Grafana service accounts (glsa_), Dynatrace, PostHog personal keys and Datadog API keys.",ignores:"Sentry DSNs and PostHog project keys, which are designed to ship in browser code."}),l(31,"credential","Private keys (PEM, OpenSSH, PGP)",["private-key"],{proof:"structure",catches:"RSA, EC, PKCS#8, OpenSSH and PGP private key blocks whose body decodes to a real key.",ignores:"Public keys and certificates, key blocks with ... for a body, and blocks filled with random text."}),l(32,"credential","Signing and encryption secrets",["signing-secret"],{proof:"context",catches:"JWT_SECRET, SECRET_KEY_BASE, NEXTAUTH_SECRET, Django SECRET_KEY and similar, when the value is random.",ignores:"changeme, algorithm names like HS256 and expiry settings."}),l(33,"credential","OAuth client secrets",["google-oauth-client-secret","oauth-client-secret"],{proof:"prefix",catches:"Google client secrets (GOCSPX-) and refresh tokens, and Okta, Auth0 and generic client_secret values.",ignores:"Client IDs, which are public."}),l(34,"credential","Long-lived JWTs",["long-lived-jwt"],{proof:"structure",catches:"Signed JWTs that are still valid for a long time \u2014 service-role keys, service-account tokens, tokens that never expire.",ignores:"Expired tokens, short-lived session tokens, Supabase anon keys and the jwt.io sample token."}),l(35,"credential","Basic auth and session cookies",["http-basic-auth","session-cookie"],{proof:"structure",catches:"Authorization: Basic headers that decode to user:password, curl -u credentials, and login session cookies.",ignores:"Analytics and preference cookies, and user:pass examples."}),l(36,"credential","Passwords in configuration",["config-password","assigned-secret"],{proof:"context",catches:"Values assigned to DB_PASSWORD, API_TOKEN, password: and their kin in env files, YAML and code, when they are random enough to be real.",ignores:"********, length settings, keyboard walks like qwertyuiop123, and placeholders."}),l(37,"credential","Crypto wallet keys and seed phrases",["crypto-wallet-secret"],{proof:"checksum",catches:"BIP39 recovery phrases whose checksum word verifies, WIF and xprv keys (Base58Check) and raw Ethereum private keys.",ignores:"The abandon \u2026 about test phrase, Hardhat's published dev keys, and wallet addresses."}),l(38,"credential","age and WireGuard keys",["age-secret-key","vpn-private-key"],{proof:"structure",catches:"age secret keys (AGE-SECRET-KEY-1\u2026) and the PrivateKey of a WireGuard [Interface].",ignores:"WireGuard peer public keys."}),l(39,"infra",".env files",["env-file"],{proof:"context",catches:"A pasted .env file with real secrets in it, flagged as one file rather than line by line.",ignores:".env files with only settings, ${VAR} references or your_key_here placeholders."}),l(40,"infra","Kubernetes configs",["kubeconfig-credential"],{proof:"structure",catches:"kubeconfig files carrying a client key or a bearer token for a cluster.",ignores:"kubeconfigs that authenticate through an exec plugin, and REDACTED tokens."}),l(41,"infra","Kubernetes Secret manifests",["k8s-secret-manifest"],{proof:"structure",catches:"kind: Secret manifests \u2014 the base64 under data: is decoded and checked, and stringData: is read as is.",ignores:"Secrets that decode to password or admin, and certificates."}),l(42,"infra","Terraform state and variables",["terraform-secret"],{proof:"structure",catches:"Passwords in terraform.tfstate attributes and hard-coded in .tf resources.",ignores:"null attributes and var.db_password references."}),l(43,"infra","Credential files",["credential-file"],{proof:"structure",catches:".netrc logins, Docker config.json auths, .pgpass lines and tokens embedded in git remote URLs.",ignores:"example.com entries, user:password auths and plain clone URLs."}),l(44,"infra","Pre-signed URLs",["presigned-url"],{proof:"structure",catches:"S3 pre-signed and Azure SAS URLs that have not expired yet \u2014 anyone holding one can read the file.",ignores:"Expired links, unsigned URLs and documentation pages."}),l(45,"pii","Payment card numbers",["payment-card-number"],{proof:"checksum",catches:"Visa, Mastercard, Amex, RuPay and other card numbers that pass the Luhn check and sit next to a card label, an expiry or a card network name.",ignores:"Published test cards (4242\u2026, 4111\u2026), order IDs and numbers that fail Luhn."}),l(46,"pii","Aadhaar numbers",["aadhaar-number"],{proof:"checksum",catches:"Aadhaar numbers that pass the Verhoeff check, labelled or in the 4-4-4 grouping.",ignores:"UIDAI's sample numbers, transaction references and numbers that fail Verhoeff."}),l(47,"pii","PAN and GSTIN",["india-tax-id"],{proof:"checksum",catches:"Individual PANs and GSTINs whose check character verifies.",ignores:"Company PANs, unlabelled lookalikes and GSTINs with a wrong check character."}),l(48,"pii","SSN and National Insurance numbers",["national-id-number"],{proof:"structure",catches:"US Social Security numbers and UK National Insurance numbers that follow the issuing rules and are labelled or listed.",ignores:"Numbers never issued (000, 666, 9xx areas), the famous Woolworth card number, and part numbers."}),l(49,"pii","Bank account details",["bank-account-details"],{proof:"checksum",catches:"IBANs that pass mod-97, and account numbers next to a valid ABA routing number or an IFSC code.",ignores:"Published example IBANs, IBANs with a wrong check digit and IFSC codes alone."}),l(50,"pii","Customer data exports",["customer-data-dump"],{proof:"context",catches:"Pasted tables of real people \u2014 rows with names, personal email addresses and phone numbers.",ignores:"example.com addresses, 555 phone numbers, short lists and staff email lists."})],kn=["Placeholders \u2014 <your-key>, ${VAR}, {{ secret }}, xxxx, changeme, your_key_here","Values cut short or masked \u2014 sk_live_\u2026, ****, REDACTED","Anything marked fake, mock, dummy, stub, fixture or sample \u2014 in a comment beside it or in its variable name","Vendors' published example and test keys","Variable names, file paths, URLs, hashes, UUIDs and regex source","Public keys, publishable keys and IDs that are not secret"],Ue=new Map;for(let e of _e)for(let t of e.slugs)Ue.set(t,e);function Sn(e){return Ue.get(e)}function Ut(e){return e===V?"credential":Ue.get(e)?.family??"credential"}function Mn(e){return Ut(e)!=="pii"}function Dn(e){return _t[e]}var Rn=_e.flatMap(e=>e.slugs);function Ht(e){let t=new Set;for(let n of e)if(n?.isActive)for(let o of n.rules??[])for(let a of o?.specificDomains??[]){let s=Ee(a);s&&t.add(s)}return Array.from(t).sort()}function wn(e){return Ht(e).filter(t=>!ge(t))}0&&(module.exports={AIToolCategory,AI_REGISTRY,ANNUAL_MONTHS_FREE,ASSIGNED_SECRET_SLUG,AlertChannel,AlertTrigger,CATEGORISED_SLUGS,COVERAGE_SLUGS,DETECTION_CATEGORIES,DETECTION_FAMILY_BLURBS,DETECTION_FAMILY_NAMES,DETECTION_PROOF_NAMES,DETECTION_UNIVERSAL_IGNORES,DIGEST_VERSION_HMAC_V1,ENTERPRISE_FEATURES,EventAction,EventType,FREE_FEATURES,FREE_SEATS,GENERATED_PASSPHRASE_ENTROPY_BITS,GENERATED_PASSPHRASE_REQUIRED_MESSAGE,INVISIBLE_CHARS_CLASS,KDF_ITERATIONS,KDF_VERSION_V2,MATRIX_TIERS,MAX_ACTIVITY_SESSIONS_PER_BATCH,MAX_SCAN_WINDOWS,MAX_TOTAL_SCAN_CHARS,MIN_SECRET_LENGTH,NORMALIZATION_VERSION_V1,NORMALIZATION_VERSION_V2,OrgPlan,PASSPHRASE_CREDENTIAL_NAME,PASSPHRASE_CREDENTIAL_URL,PASSPHRASE_VERIFY_LABEL,PASTE_CEILING_ALARM_CHARS,PASTE_CEILING_WARN_CHARS,PLAN_DESCRIPTORS,PLAN_FEATURE_MATRIX,PLAN_FEATURE_TIERS,PLAN_LIMITS,PLAN_PRICING,PRIVACY_EMAIL,PROJECT_KDF_LABEL,PRO_BANDS,PRO_ENTRY_BAND,PRO_FEATURES,PRO_TOP_BAND,RiskLevel,SAFE_BLOCK_EVENT_FIELDS,SALES_EMAIL,SCAN_PREFILTER_LABEL,SCAN_PREFILTER_PATTERN,SCAN_PREFILTER_SPACE,SCAN_PREFILTER_WINDOWS_PER_SIGNATURE,SECRET_PROVIDER_NAMES,SECRET_PROVIDER_SLUGS,SECURITY_EMAIL,TRIAL_DAYS,UNRECOGNISED_PROVIDER_SLUG,UserRole,annualBilledNote,appendPasskeyEnvelope,behaviorExplanation,canonicalSecretPlaintextForHmac,categoryOfSlug,computePassphraseVerifyHmac,customPolicyDomains,decodeScanPrefilter,deriveBehaviorRisk,deriveHmacKeyFromPassphrase,deriveProjectKey,deriveScanPrefilterSeed,encodeScanPrefilter,extractAddedLinesFromUnifiedDiff,familyDisplayName,familyOfSlug,findBand,findPasskeyEnvelope,foldUuidHexCase,generateHmacKey,generateOrgPassphrase,generatePrfSalt,getInjectionHostnames,getLimitsForPlan,getPrfSaltBytes,hexToKey,hmacDigestHex,isAIToolDomain,isGeneratedPassphraseFormat,isInjectionScopedHostname,isKnownProviderSlug,isProtectableSlug,isV1PassphraseEnvelope,isV2Envelope,keyToHex,matchDomain,matchPatternsForHostname,maxScannablePasteChars,maxScannablePasteCharsFor,normalizeAndHmacHex,normalizeAndHmacHexCollapsed,normalizeAndHmacHexLower,normalizeDomainInput,normalizeSecretPlaintextCollapsed,normalizeSecretPlaintextForMatch,normalizeSecretPlaintextLower,passphraseCsvText,passphraseSheetText,perMonthOnAnnual,policyNamedDomains,projectedScanCost,providerDisplayName,removePasskeyEnvelope,scanBudgetFor,scanPrefilterFingerprint,scanPrefilterForRawSecret,scanPrefilterParams,scanPrefilterRoller,scanPrefilterUnits,scanSweeps,scanWindowLengths,smallestBandFor,unwrapHmacKeyWithPrf,upgradeEnvelopeToV2,usd,validateGeneratedPassphrase,validateNewPassphrase,validatePassphraseStrength,wrapHmacKeyWithPrf});
5
7
  /*! Bundled license information:
6
8
 
7
9
  @noble/hashes/esm/utils.js: