vibemole 0.1.0
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/dist/index.js +2565 -0
- package/package.json +35 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2565 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var ya=Object.create;var un=Object.defineProperty;var ba=Object.getOwnPropertyDescriptor;var ka=Object.getOwnPropertyNames;var va=Object.getPrototypeOf,wa=Object.prototype.hasOwnProperty;var xa=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Sa=(e,t,o,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ka(t))!wa.call(e,n)&&n!==o&&un(e,n,{get:()=>t[n],enumerable:!(a=ba(t,n))||a.enumerable});return e};var Ea=(e,t,o)=>(o=e!=null?ya(va(e)):{},Sa(t||!e||!e.__esModule?un(o,"default",{value:e,enumerable:!0}):o,e));var mo=xa(q=>{"use strict";function pr(e,t){return e.endsWith(t)?e.length===t.length||e[e.length-t.length-1]===".":!1}function gr(e,t){let o=e.length-t.length-2,a=e.lastIndexOf(".",o);return a===-1?e:e.slice(a+1)}function fr(e,t,o){if(o.validHosts!==null){let n=o.validHosts;for(let i of n)if(pr(t,i))return i}let a=0;if(t.startsWith("."))for(;a<t.length&&t[a]===".";)a+=1;return e.length===t.length-a?null:gr(t,e)}function hr(e,t){return e.slice(0,-t.length-1)}function io(e,t){let o=0,a=e.length,n=!1;if(!t){if(e.startsWith("data:"))return null;for(;o<e.length&&e.charCodeAt(o)<=32;)o+=1;for(;a>o+1&&e.charCodeAt(a-1)<=32;)a-=1;if(e.charCodeAt(o)===47&&e.charCodeAt(o+1)===47)o+=2;else{let l=e.indexOf(":/",o);if(l!==-1){let u=l-o,d=e.charCodeAt(o),m=e.charCodeAt(o+1),p=e.charCodeAt(o+2),f=e.charCodeAt(o+3),E=e.charCodeAt(o+4);if(!(u===5&&d===104&&m===116&&p===116&&f===112&&E===115)){if(!(u===4&&d===104&&m===116&&p===116&&f===112)){if(!(u===3&&d===119&&m===115&&p===115)){if(!(u===2&&d===119&&m===115))for(let x=o;x<l;x+=1){let S=e.charCodeAt(x)|32;if(!(S>=97&&S<=122||S>=48&&S<=57||S===46||S===45||S===43))return null}}}}for(o=l+2;e.charCodeAt(o)===47;)o+=1}}let r=-1,s=-1,c=-1;for(let l=o;l<a;l+=1){let u=e.charCodeAt(l);if(u===35||u===47||u===63){a=l;break}else u===64?r=l:u===93?s=l:u===58?c=l:u>=65&&u<=90&&(n=!0)}if(r!==-1&&r>o&&r<a&&(o=r+1),e.charCodeAt(o)===91)return s!==-1?e.slice(o+1,s).toLowerCase():null;c!==-1&&c>o&&c<a&&(a=c)}for(;a>o+1&&e.charCodeAt(a-1)===46;)a-=1;let i=o!==0||a!==e.length?e.slice(o,a):e;return n?i.toLowerCase():i}function yr(e){if(e.length<7||e.length>15)return!1;let t=0;for(let o=0;o<e.length;o+=1){let a=e.charCodeAt(o);if(a===46)t+=1;else if(a<48||a>57)return!1}return t===3&&e.charCodeAt(0)!==46&&e.charCodeAt(e.length-1)!==46}function br(e){if(e.length<3)return!1;let t=e.startsWith("[")?1:0,o=e.length;if(e[o-1]==="]"&&(o-=1),o-t>39)return!1;let a=!1;for(;t<o;t+=1){let n=e.charCodeAt(t);if(n===58)a=!0;else if(!(n>=48&&n<=57||n>=97&&n<=102||n>=65&&n<=90))return!1}return a}function kr(e){return br(e)||yr(e)}function ro(e){return e>=97&&e<=122||e>=48&&e<=57||e>127}function so(e){if(e.length>255||e.length===0||!ro(e.charCodeAt(0))&&e.charCodeAt(0)!==46&&e.charCodeAt(0)!==95)return!1;let t=-1,o=-1,a=e.length;for(let n=0;n<a;n+=1){let i=e.charCodeAt(n);if(i===46){if(n-t>64||o===46||o===45||o===95)return!1;t=n}else if(!(ro(i)||i===45||i===95))return!1;o=i}return a-t-1<=63&&o!==45}function lo({allowIcannDomains:e=!0,allowPrivateDomains:t=!1,detectIp:o=!0,extractHostname:a=!0,mixedInputs:n=!0,validHosts:i=null,validateHostname:r=!0}){return{allowIcannDomains:e,allowPrivateDomains:t,detectIp:o,extractHostname:a,mixedInputs:n,validHosts:i,validateHostname:r}}var vr=lo({});function wr(e){return e===void 0?vr:lo(e)}function xr(e,t){return t.length===e.length?"":e.slice(0,-t.length-1)}function uo(){return{domain:null,domainWithoutSuffix:null,hostname:null,isIcann:null,isIp:null,isPrivate:null,publicSuffix:null,subdomain:null}}function le(e){e.domain=null,e.domainWithoutSuffix=null,e.hostname=null,e.isIcann=null,e.isIp=null,e.isPrivate=null,e.publicSuffix=null,e.subdomain=null}function W(e,t,o,a,n){let i=wr(a);return typeof e!="string"||(i.extractHostname?i.mixedInputs?n.hostname=io(e,so(e)):n.hostname=io(e,!1):n.hostname=e,i.detectIp&&n.hostname!==null&&(n.isIp=kr(n.hostname),n.isIp))?n:i.validateHostname&&i.extractHostname&&n.hostname!==null&&!so(n.hostname)?(n.hostname=null,n):(t===0||n.hostname===null||(o(n.hostname,i,n),t===2||n.publicSuffix===null)||(n.domain=fr(n.publicSuffix,n.hostname,i),t===3||n.domain===null)||(n.subdomain=xr(n.hostname,n.domain),t===4)||(n.domainWithoutSuffix=hr(n.domain,n.publicSuffix)),n)}function Sr(e,t,o){if(!t.allowPrivateDomains&&e.length>3){let a=e.length-1,n=e.charCodeAt(a),i=e.charCodeAt(a-1),r=e.charCodeAt(a-2),s=e.charCodeAt(a-3);if(n===109&&i===111&&r===99&&s===46)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="com",!0;if(n===103&&i===114&&r===111&&s===46)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="org",!0;if(n===117&&i===100&&r===101&&s===46)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="edu",!0;if(n===118&&i===111&&r===103&&s===46)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="gov",!0;if(n===116&&i===101&&r===110&&s===46)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="net",!0;if(n===101&&i===100&&r===46)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="de",!0}return!1}var Er=(function(){let e=[1,{}],t=[0,{city:e}];return[0,{ck:[0,{www:e}],jp:[0,{kawasaki:t,kitakyushu:t,kobe:t,nagoya:t,sapporo:t,sendai:t,yokohama:t}]}]})(),Cr=(function(){let e=[1,{}],t=[2,{}],o=[1,{com:e,edu:e,gov:e,net:e,org:e}],a=[1,{com:e,edu:e,gov:e,mil:e,net:e,org:e}],n=[0,{"*":t}],i=[2,{s:n}],r=[0,{relay:t}],s=[2,{id:t}],c=[1,{gov:e}],l=[0,{airflow:n,"lambda-url":t,"transfer-webapp":t}],u=[0,{airflow:n,"transfer-webapp":t}],d=[0,{"transfer-webapp":t}],m=[0,{"transfer-webapp":t,"transfer-webapp-fips":t}],p=[0,{notebook:t,studio:t}],f=[0,{labeling:t,notebook:t,studio:t}],E=[0,{notebook:t}],x=[0,{labeling:t,notebook:t,"notebook-fips":t,studio:t}],S=[0,{notebook:t,"notebook-fips":t,studio:t,"studio-fips":t}],h=[0,{shop:t}],k=[0,{"*":e}],P=[1,{co:t}],j=[0,{objects:t}],T=[2,{"eu-west-1":t,"us-east-1":t}],_=[0,{lb:t,s3:t,website:t}],C=[2,{nodes:t}],B=[0,{my:t}],U=[0,{s3:t,"s3-accesspoint":t,"s3-website":t}],he=[0,{s3:t,"s3-accesspoint":t}],ne=[0,{direct:t}],A=[0,{"webview-assets":t}],M=[0,{vfs:t,"webview-assets":t}],y=[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:U,s3:t,"s3-accesspoint":t,"s3-object-lambda":t,"s3-website":t,"aws-cloud9":A,cloud9:M}],z=[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:he,s3:t,"s3-accesspoint":t,"s3-object-lambda":t,"s3-website":t,"aws-cloud9":A,cloud9:M}],R=[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:U,s3:t,"s3-accesspoint":t,"s3-object-lambda":t,"s3-website":t,"analytics-gateway":t,"aws-cloud9":A,cloud9:M}],H=[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:U,s3:t,"s3-accesspoint":t,"s3-object-lambda":t,"s3-website":t}],ye=[0,{s3:t,"s3-accesspoint":t,"s3-accesspoint-fips":t,"s3-fips":t,"s3-website":t}],Kt=[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:ye,s3:t,"s3-accesspoint":t,"s3-accesspoint-fips":t,"s3-fips":t,"s3-object-lambda":t,"s3-website":t,"aws-cloud9":A,cloud9:M}],He=[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:ye,s3:t,"s3-accesspoint":t,"s3-accesspoint-fips":t,"s3-fips":t,"s3-object-lambda":t,"s3-website":t}],Wt=[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:ye,s3:t,"s3-accesspoint":t,"s3-accesspoint-fips":t,"s3-deprecated":t,"s3-fips":t,"s3-object-lambda":t,"s3-website":t,"analytics-gateway":t,"aws-cloud9":A,cloud9:M}],b=[0,{auth:t}],be=[0,{auth:t,"auth-fips":t}],Gt=[0,{"auth-fips":t}],Yt=[0,{apps:t}],Ve=[0,{paas:t}],Xt=[2,{eu:t}],Ke=[0,{app:t}],We=[0,{site:t}],ke=[1,{com:e,edu:e,net:e,org:e}],Ge=[0,{j:t}],Jt=[0,{dyn:t}],Zt=[2,{web:t}],Qt=[1,{co:e,com:e,edu:e,gov:e,net:e,org:e}],en=[0,{p:t}],tn=[0,{user:t}],oe=[0,{cdn:t}],nn=[2,{raw:n}],Ye=[0,{cust:t,reservd:t}],on=[0,{cust:t}],Xe=[0,{s3:t}],an=[1,{biz:e,com:e,edu:e,gov:e,info:e,net:e,org:e}],Je=[0,{ipfs:t}],ve=[1,{framer:t}],rn=[0,{forgot:t}],ha=[0,{blob:t,file:t,web:t}],sn=[0,{core:ha,servicebus:t}],v=[1,{gs:e}],cn=[0,{nes:e}],g=[1,{k12:e,cc:e,lib:e}],ln=[1,{cc:e}],we=[1,{cc:e,lib:e}];return[0,{ac:[1,{com:e,edu:e,gov:e,mil:e,net:e,org:e,drr:t,feedback:t,forms:t}],ad:e,ae:[1,{ac:e,co:e,gov:e,mil:e,net:e,org:e,sch:e}],aero:[1,{airline:e,airport:e,"accident-investigation":e,"accident-prevention":e,aerobatic:e,aeroclub:e,aerodrome:e,agents:e,"air-surveillance":e,"air-traffic-control":e,aircraft:e,airtraffic:e,ambulance:e,association:e,author:e,ballooning:e,broker:e,caa:e,cargo:e,catering:e,certification:e,championship:e,charter:e,civilaviation:e,club:e,conference:e,consultant:e,consulting:e,control:e,council:e,crew:e,design:e,dgca:e,educator:e,emergency:e,engine:e,engineer:e,entertainment:e,equipment:e,exchange:e,express:e,federation:e,flight:e,freight:e,fuel:e,gliding:e,government:e,groundhandling:e,group:e,hanggliding:e,homebuilt:e,insurance:e,journal:e,journalist:e,leasing:e,logistics:e,magazine:e,maintenance:e,marketplace:e,media:e,microlight:e,modelling:e,navigation:e,parachuting:e,paragliding:e,"passenger-association":e,pilot:e,press:e,production:e,recreation:e,repbody:e,res:e,research:e,rotorcraft:e,safety:e,scientist:e,services:e,show:e,skydiving:e,software:e,student:e,taxi:e,trader:e,trading:e,trainer:e,union:e,workinggroup:e,works:e}],af:o,ag:[1,{co:e,com:e,net:e,nom:e,org:e,obj:t}],ai:[1,{com:e,net:e,off:e,org:e,uwu:t,framer:t,kiloapps:t}],al:a,am:[1,{co:e,com:e,commune:e,net:e,org:e,radio:t}],ao:[1,{co:e,ed:e,edu:e,gov:e,gv:e,it:e,og:e,org:e,pb:e}],aq:e,ar:[1,{bet:e,com:e,coop:e,edu:e,gob:e,gov:e,int:e,mil:e,musica:e,mutual:e,net:e,org:e,seg:e,senasa:e,tur:e}],arpa:[1,{e164:e,home:e,"in-addr":e,ip6:e,iris:e,uri:e,urn:e}],as:c,asia:[1,{cloudns:t,daemon:t,dix:t}],at:[1,{4:t,ac:[1,{sth:e}],co:e,gv:e,or:e,funkfeuer:[0,{wien:t}],futurecms:[0,{"*":t,ex:n,in:n}],futurehosting:t,futuremailing:t,ortsinfo:[0,{ex:n,kunden:n}],biz:t,info:t,"123webseite":t,priv:t,my:t,myspreadshop:t,"12hp":t,"2ix":t,"4lima":t,"lima-city":t}],au:[1,{asn:e,com:[1,{cloudlets:[0,{mel:t}],myspreadshop:t}],edu:[1,{act:e,catholic:e,nsw:e,nt:e,qld:e,sa:e,tas:e,vic:e,wa:e}],gov:[1,{qld:e,sa:e,tas:e,vic:e,wa:e}],id:e,net:e,org:e,conf:e,oz:e,act:e,nsw:e,nt:e,qld:e,sa:e,tas:e,vic:e,wa:e,hrsn:[0,{vps:t}]}],aw:[1,{com:e}],ax:e,az:[1,{biz:e,co:e,com:e,edu:e,gov:e,info:e,int:e,mil:e,name:e,net:e,org:e,pp:e,pro:e}],ba:[1,{com:e,edu:e,gov:e,mil:e,net:e,org:e,brendly:h,rs:t}],bb:[1,{biz:e,co:e,com:e,edu:e,gov:e,info:e,net:e,org:e,store:e,tv:e}],bd:[1,{ac:e,ai:e,co:e,com:e,edu:e,gov:e,id:e,info:e,it:e,mil:e,net:e,org:e,sch:e,tv:e}],be:[1,{ac:e,cloudns:t,webhosting:t,interhostsolutions:[0,{cloud:t}],kuleuven:[0,{ezproxy:t}],my:t,"123website":t,myspreadshop:t,transurl:n}],bf:c,bg:[1,{0:e,1:e,2:e,3:e,4:e,5:e,6:e,7:e,8:e,9:e,a:e,b:e,c:e,d:e,e,f:e,g:e,h:e,i:e,j:e,k:e,l:e,m:e,n:e,o:e,p:e,q:e,r:e,s:e,t:e,u:e,v:e,w:e,x:e,y:e,z:e,barsy:t}],bh:o,bi:[1,{co:e,com:e,edu:e,or:e,org:e}],biz:[1,{activetrail:t,"cloud-ip":t,cloudns:t,jozi:t,dyndns:t,"for-better":t,"for-more":t,"for-some":t,"for-the":t,selfip:t,webhop:t,orx:t,mmafan:t,myftp:t,"no-ip":t,dscloud:t}],bj:[1,{africa:e,agro:e,architectes:e,assur:e,avocats:e,co:e,com:e,eco:e,econo:e,edu:e,info:e,loisirs:e,money:e,net:e,org:e,ote:e,restaurant:e,resto:e,tourism:e,univ:e}],bm:o,bn:[1,{com:e,edu:e,gov:e,net:e,org:e,co:t}],bo:[1,{com:e,edu:e,gob:e,int:e,mil:e,net:e,org:e,tv:e,web:e,academia:e,agro:e,arte:e,blog:e,bolivia:e,ciencia:e,cooperativa:e,democracia:e,deporte:e,ecologia:e,economia:e,empresa:e,indigena:e,industria:e,info:e,medicina:e,movimiento:e,musica:e,natural:e,nombre:e,noticias:e,patria:e,plurinacional:e,politica:e,profesional:e,pueblo:e,revista:e,salud:e,tecnologia:e,tksat:e,transporte:e,wiki:e}],br:[1,{"9guacu":e,abc:e,adm:e,adv:e,agr:e,aju:e,am:e,anani:e,aparecida:e,api:e,app:e,arq:e,art:e,ato:e,b:e,barueri:e,belem:e,bet:e,bhz:e,bib:e,bio:e,blog:e,bmd:e,boavista:e,bsb:e,campinagrande:e,campinas:e,caxias:e,cim:e,cng:e,cnt:e,com:[1,{simplesite:t}],contagem:e,coop:e,coz:e,cri:e,cuiaba:e,curitiba:e,def:e,des:e,det:e,dev:e,ecn:e,eco:e,edu:e,emp:e,enf:e,eng:e,esp:e,etc:e,eti:e,far:e,feira:e,flog:e,floripa:e,fm:e,fnd:e,fortal:e,fot:e,foz:e,fst:e,g12:e,geo:e,ggf:e,goiania:e,gov:[1,{ac:e,al:e,am:e,ap:e,ba:e,ce:e,df:e,es:e,go:e,ma:e,mg:e,ms:e,mt:e,pa:e,pb:e,pe:e,pi:e,pr:e,rj:e,rn:e,ro:e,rr:e,rs:e,sc:e,se:e,sp:e,to:e}],gru:e,ia:e,imb:e,ind:e,inf:e,jab:e,jampa:e,jdf:e,joinville:e,jor:e,jus:e,leg:[1,{ac:t,al:t,am:t,ap:t,ba:t,ce:t,df:t,es:t,go:t,ma:t,mg:t,ms:t,mt:t,pa:t,pb:t,pe:t,pi:t,pr:t,rj:t,rn:t,ro:t,rr:t,rs:t,sc:t,se:t,sp:t,to:t}],leilao:e,lel:e,log:e,londrina:e,macapa:e,maceio:e,manaus:e,maringa:e,mat:e,med:e,mil:e,morena:e,mp:e,mus:e,natal:e,net:e,niteroi:e,nom:k,not:e,ntr:e,odo:e,ong:e,org:e,osasco:e,palmas:e,poa:e,ppg:e,pro:e,psc:e,psi:e,pvh:e,qsl:e,radio:e,rec:e,recife:e,rep:e,ribeirao:e,rio:e,riobranco:e,riopreto:e,salvador:e,sampa:e,santamaria:e,santoandre:e,saobernardo:e,saogonca:e,seg:e,sjc:e,slg:e,slz:e,social:e,sorocaba:e,srv:e,taxi:e,tc:e,tec:e,teo:e,the:e,tmp:e,trd:e,tur:e,tv:e,udi:e,vet:e,vix:e,vlog:e,wiki:e,xyz:e,zlg:e,tche:t}],bs:[1,{com:e,edu:e,gov:e,net:e,org:e,we:t}],bt:o,bv:e,bw:[1,{ac:e,co:e,gov:e,net:e,org:e}],by:[1,{gov:e,mil:e,com:e,of:e,mediatech:t}],bz:[1,{co:e,com:e,edu:e,gov:e,net:e,org:e,za:t,mydns:t,gsj:t}],ca:[1,{ab:e,bc:e,mb:e,nb:e,nf:e,nl:e,ns:e,nt:e,nu:e,on:e,pe:e,qc:e,sk:e,yk:e,gc:e,barsy:t,awdev:n,co:t,"no-ip":t,onid:t,myspreadshop:t,box:t}],cat:e,cc:[1,{cleverapps:t,"cloud-ip":t,cloudns:t,ccwu:t,ftpaccess:t,"game-server":t,myphotos:t,scrapping:t,twmail:t,csx:t,fantasyleague:t,spawn:[0,{instances:t}],sryze:t,ec:t,eu:t,gu:t,uk:t,us:t}],cd:[1,{gov:e,cc:t}],cf:e,cg:e,ch:[1,{square7:t,cloudns:t,cloudscale:[0,{cust:t,lpg:j,rma:j}],objectstorage:[0,{lpg:t,rma:t}],flow:[0,{ae:[0,{alp1:t}],appengine:t}],"linkyard-cloud":t,gotdns:t,dnsking:t,"123website":t,myspreadshop:t,firenet:[0,{"*":t,svc:n}],"12hp":t,"2ix":t,"4lima":t,"lima-city":t}],ci:[1,{ac:e,"xn--aroport-bya":e,a\u00E9roport:e,asso:e,co:e,com:e,ed:e,edu:e,go:e,gouv:e,int:e,net:e,or:e,org:e,us:t}],ck:k,cl:[1,{co:e,gob:e,gov:e,mil:e,cloudns:t}],cm:[1,{co:e,com:e,gov:e,net:e}],cn:[1,{ac:e,com:[1,{amazonaws:[0,{"cn-north-1":[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,rds:n,dualstack:U,s3:t,"s3-accesspoint":t,"s3-deprecated":t,"s3-object-lambda":t,"s3-website":t}],"cn-northwest-1":[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,rds:n,dualstack:he,s3:t,"s3-accesspoint":t,"s3-object-lambda":t,"s3-website":t}],compute:n,airflow:[0,{"cn-north-1":n,"cn-northwest-1":n}],eb:[0,{"cn-north-1":t,"cn-northwest-1":t}],elb:n}],amazonwebservices:[0,{on:[0,{"cn-north-1":u,"cn-northwest-1":u}]}],sagemaker:[0,{"cn-north-1":p,"cn-northwest-1":p}]}],edu:e,gov:e,mil:e,net:e,org:e,"xn--55qx5d":e,\u516C\u53F8:e,"xn--od0alg":e,\u7DB2\u7D61:e,"xn--io0a7i":e,\u7F51\u7EDC:e,ah:e,bj:e,cq:e,fj:e,gd:e,gs:e,gx:e,gz:e,ha:e,hb:e,he:e,hi:e,hk:e,hl:e,hn:e,jl:e,js:e,jx:e,ln:e,mo:e,nm:e,nx:e,qh:e,sc:e,sd:e,sh:[1,{as:t}],sn:e,sx:e,tj:e,tw:e,xj:e,xz:e,yn:e,zj:e,"canva-apps":t,canvasite:B,myqnapcloud:t,quickconnect:ne}],co:[1,{com:e,edu:e,gov:e,mil:e,net:e,nom:e,org:e,carrd:t,crd:t,otap:n,hidns:t,leadpages:t,lpages:t,mypi:t,xmit:n,rdpa:[0,{clusters:n,srvrless:n}],firewalledreplit:s,repl:s,supabase:[2,{realtime:t,storage:t}],umso:t}],com:[1,{a2hosted:t,cpserver:t,adobeaemcloud:[2,{dev:n}],africa:t,auiusercontent:n,aivencloud:t,alibabacloudcs:t,kasserver:t,amazonaws:[0,{"af-south-1":y,"ap-east-1":z,"ap-northeast-1":R,"ap-northeast-2":R,"ap-northeast-3":y,"ap-south-1":R,"ap-south-2":H,"ap-southeast-1":R,"ap-southeast-2":R,"ap-southeast-3":H,"ap-southeast-4":H,"ap-southeast-5":[0,{"execute-api":t,dualstack:U,s3:t,"s3-accesspoint":t,"s3-deprecated":t,"s3-object-lambda":t,"s3-website":t}],"ca-central-1":Kt,"ca-west-1":He,"eu-central-1":R,"eu-central-2":H,"eu-north-1":z,"eu-south-1":y,"eu-south-2":H,"eu-west-1":[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:U,s3:t,"s3-accesspoint":t,"s3-deprecated":t,"s3-object-lambda":t,"s3-website":t,"analytics-gateway":t,"aws-cloud9":A,cloud9:M}],"eu-west-2":z,"eu-west-3":y,"il-central-1":[0,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:U,s3:t,"s3-accesspoint":t,"s3-object-lambda":t,"s3-website":t,"aws-cloud9":A,cloud9:[0,{vfs:t}]}],"me-central-1":H,"me-south-1":z,"sa-east-1":y,"us-east-1":[2,{"execute-api":t,"emrappui-prod":t,"emrnotebooks-prod":t,"emrstudio-prod":t,dualstack:ye,s3:t,"s3-accesspoint":t,"s3-accesspoint-fips":t,"s3-deprecated":t,"s3-fips":t,"s3-object-lambda":t,"s3-website":t,"analytics-gateway":t,"aws-cloud9":A,cloud9:M}],"us-east-2":Wt,"us-gov-east-1":He,"us-gov-west-1":He,"us-west-1":Kt,"us-west-2":Wt,compute:n,"compute-1":n,airflow:[0,{"af-south-1":n,"ap-east-1":n,"ap-northeast-1":n,"ap-northeast-2":n,"ap-northeast-3":n,"ap-south-1":n,"ap-south-2":n,"ap-southeast-1":n,"ap-southeast-2":n,"ap-southeast-3":n,"ap-southeast-4":n,"ap-southeast-5":n,"ap-southeast-7":n,"ca-central-1":n,"ca-west-1":n,"eu-central-1":n,"eu-central-2":n,"eu-north-1":n,"eu-south-1":n,"eu-south-2":n,"eu-west-1":n,"eu-west-2":n,"eu-west-3":n,"il-central-1":n,"me-central-1":n,"me-south-1":n,"sa-east-1":n,"us-east-1":n,"us-east-2":n,"us-west-1":n,"us-west-2":n}],rds:[0,{"af-south-1":n,"ap-east-1":n,"ap-east-2":n,"ap-northeast-1":n,"ap-northeast-2":n,"ap-northeast-3":n,"ap-south-1":n,"ap-south-2":n,"ap-southeast-1":n,"ap-southeast-2":n,"ap-southeast-3":n,"ap-southeast-4":n,"ap-southeast-5":n,"ap-southeast-6":n,"ap-southeast-7":n,"ca-central-1":n,"ca-west-1":n,"eu-central-1":n,"eu-central-2":n,"eu-west-1":n,"eu-west-2":n,"eu-west-3":n,"il-central-1":n,"me-central-1":n,"me-south-1":n,"mx-central-1":n,"sa-east-1":n,"us-east-1":n,"us-east-2":n,"us-gov-east-1":n,"us-gov-west-1":n,"us-northeast-1":n,"us-west-1":n,"us-west-2":n}],s3:t,"s3-1":t,"s3-ap-east-1":t,"s3-ap-northeast-1":t,"s3-ap-northeast-2":t,"s3-ap-northeast-3":t,"s3-ap-south-1":t,"s3-ap-southeast-1":t,"s3-ap-southeast-2":t,"s3-ca-central-1":t,"s3-eu-central-1":t,"s3-eu-north-1":t,"s3-eu-west-1":t,"s3-eu-west-2":t,"s3-eu-west-3":t,"s3-external-1":t,"s3-fips-us-gov-east-1":t,"s3-fips-us-gov-west-1":t,"s3-global":[0,{accesspoint:[0,{mrap:t}]}],"s3-me-south-1":t,"s3-sa-east-1":t,"s3-us-east-2":t,"s3-us-gov-east-1":t,"s3-us-gov-west-1":t,"s3-us-west-1":t,"s3-us-west-2":t,"s3-website-ap-northeast-1":t,"s3-website-ap-southeast-1":t,"s3-website-ap-southeast-2":t,"s3-website-eu-west-1":t,"s3-website-sa-east-1":t,"s3-website-us-east-1":t,"s3-website-us-gov-west-1":t,"s3-website-us-west-1":t,"s3-website-us-west-2":t,elb:n}],amazoncognito:[0,{"af-south-1":b,"ap-east-1":b,"ap-northeast-1":b,"ap-northeast-2":b,"ap-northeast-3":b,"ap-south-1":b,"ap-south-2":b,"ap-southeast-1":b,"ap-southeast-2":b,"ap-southeast-3":b,"ap-southeast-4":b,"ap-southeast-5":b,"ap-southeast-7":b,"ca-central-1":b,"ca-west-1":b,"eu-central-1":b,"eu-central-2":b,"eu-north-1":b,"eu-south-1":b,"eu-south-2":b,"eu-west-1":b,"eu-west-2":b,"eu-west-3":b,"il-central-1":b,"me-central-1":b,"me-south-1":b,"mx-central-1":b,"sa-east-1":b,"us-east-1":be,"us-east-2":be,"us-gov-east-1":Gt,"us-gov-west-1":Gt,"us-west-1":be,"us-west-2":be}],amplifyapp:t,awsapprunner:n,awsapps:t,elasticbeanstalk:[2,{"af-south-1":t,"ap-east-1":t,"ap-northeast-1":t,"ap-northeast-2":t,"ap-northeast-3":t,"ap-south-1":t,"ap-southeast-1":t,"ap-southeast-2":t,"ap-southeast-3":t,"ap-southeast-5":t,"ap-southeast-7":t,"ca-central-1":t,"eu-central-1":t,"eu-north-1":t,"eu-south-1":t,"eu-south-2":t,"eu-west-1":t,"eu-west-2":t,"eu-west-3":t,"il-central-1":t,"me-central-1":t,"me-south-1":t,"sa-east-1":t,"us-east-1":t,"us-east-2":t,"us-gov-east-1":t,"us-gov-west-1":t,"us-west-1":t,"us-west-2":t}],awsglobalaccelerator:t,siiites:t,appspacehosted:t,appspaceusercontent:t,"on-aptible":t,myasustor:t,"atlassian-3p":n,"atlassian-3p-us-gov-mod":n,"atlassian-isolated-3p":n,"balena-devices":t,boutir:t,bplaced:t,cafjs:t,"canva-apps":t,"canva-hosted-embed":t,canvacode:t,"rice-labs":t,"cdn77-storage":t,br:t,cn:t,de:t,eu:t,jpn:t,mex:t,ru:t,sa:t,uk:t,us:t,za:t,"clever-cloud":[0,{services:n}],abrdns:t,dnsabr:t,"ip-ddns":t,jdevcloud:t,wpdevcloud:t,"cf-ipfs":t,"cloudflare-ipfs":t,trycloudflare:t,co:t,devinapps:n,builtwithdark:t,datadetect:[0,{demo:t,instance:t}],dattolocal:t,dattorelay:t,dattoweb:t,mydatto:t,deployagent:t,digitaloceanspaces:n,discordsays:t,discordsez:t,drayddns:t,dreamhosters:t,durumis:t,blogdns:t,cechire:t,dnsalias:t,dnsdojo:t,doesntexist:t,dontexist:t,doomdns:t,"dyn-o-saur":t,dynalias:t,"dyndns-at-home":t,"dyndns-at-work":t,"dyndns-blog":t,"dyndns-free":t,"dyndns-home":t,"dyndns-ip":t,"dyndns-mail":t,"dyndns-office":t,"dyndns-pics":t,"dyndns-remote":t,"dyndns-server":t,"dyndns-web":t,"dyndns-wiki":t,"dyndns-work":t,"est-a-la-maison":t,"est-a-la-masion":t,"est-le-patron":t,"est-mon-blogueur":t,"from-ak":t,"from-al":t,"from-ar":t,"from-ca":t,"from-ct":t,"from-dc":t,"from-de":t,"from-fl":t,"from-ga":t,"from-hi":t,"from-ia":t,"from-id":t,"from-il":t,"from-in":t,"from-ks":t,"from-ky":t,"from-ma":t,"from-md":t,"from-mi":t,"from-mn":t,"from-mo":t,"from-ms":t,"from-mt":t,"from-nc":t,"from-nd":t,"from-ne":t,"from-nh":t,"from-nj":t,"from-nm":t,"from-nv":t,"from-oh":t,"from-ok":t,"from-or":t,"from-pa":t,"from-pr":t,"from-ri":t,"from-sc":t,"from-sd":t,"from-tn":t,"from-tx":t,"from-ut":t,"from-va":t,"from-vt":t,"from-wa":t,"from-wi":t,"from-wv":t,"from-wy":t,getmyip:t,gotdns:t,"hobby-site":t,homelinux:t,homeunix:t,iamallama:t,"is-a-anarchist":t,"is-a-blogger":t,"is-a-bookkeeper":t,"is-a-bulls-fan":t,"is-a-caterer":t,"is-a-chef":t,"is-a-conservative":t,"is-a-cpa":t,"is-a-cubicle-slave":t,"is-a-democrat":t,"is-a-designer":t,"is-a-doctor":t,"is-a-financialadvisor":t,"is-a-geek":t,"is-a-green":t,"is-a-guru":t,"is-a-hard-worker":t,"is-a-hunter":t,"is-a-landscaper":t,"is-a-lawyer":t,"is-a-liberal":t,"is-a-libertarian":t,"is-a-llama":t,"is-a-musician":t,"is-a-nascarfan":t,"is-a-nurse":t,"is-a-painter":t,"is-a-personaltrainer":t,"is-a-photographer":t,"is-a-player":t,"is-a-republican":t,"is-a-rockstar":t,"is-a-socialist":t,"is-a-student":t,"is-a-teacher":t,"is-a-techie":t,"is-a-therapist":t,"is-an-accountant":t,"is-an-actor":t,"is-an-actress":t,"is-an-anarchist":t,"is-an-artist":t,"is-an-engineer":t,"is-an-entertainer":t,"is-certified":t,"is-gone":t,"is-into-anime":t,"is-into-cars":t,"is-into-cartoons":t,"is-into-games":t,"is-leet":t,"is-not-certified":t,"is-slick":t,"is-uberleet":t,"is-with-theband":t,"isa-geek":t,"isa-hockeynut":t,issmarterthanyou:t,"likes-pie":t,likescandy:t,"neat-url":t,"saves-the-whales":t,selfip:t,"sells-for-less":t,"sells-for-u":t,servebbs:t,"simple-url":t,"space-to-rent":t,"teaches-yoga":t,writesthisblog:t,"1cooldns":t,bumbleshrimp:t,ddnsfree:t,ddnsgeek:t,ddnsguru:t,dynuddns:t,dynuhosting:t,giize:t,gleeze:t,kozow:t,loseyourip:t,ooguy:t,pivohosting:t,theworkpc:t,wiredbladehosting:t,emergentagent:[0,{preview:t}],mytuleap:t,"tuleap-partners":t,encoreapi:t,evennode:[0,{"eu-1":t,"eu-2":t,"eu-3":t,"eu-4":t,"us-1":t,"us-2":t,"us-3":t,"us-4":t}],onfabrica:t,"fastly-edge":t,"fastly-terrarium":t,"fastvps-server":t,mydobiss:t,firebaseapp:t,fldrv:t,framercanvas:t,"freebox-os":t,freeboxos:t,freemyip:t,aliases121:t,gentapps:t,gentlentapis:t,githubusercontent:t,"0emm":n,appspot:[2,{r:n}],blogspot:t,codespot:t,googleapis:t,googlecode:t,pagespeedmobilizer:t,withgoogle:t,withyoutube:t,grayjayleagues:t,hatenablog:t,hatenadiary:t,"hercules-app":t,"hercules-dev":t,herokuapp:t,gr:t,smushcdn:t,wphostedmail:t,wpmucdn:t,pixolino:t,"apps-1and1":t,"live-website":t,"webspace-host":t,dopaas:t,"hosted-by-previder":Ve,hosteur:[0,{"rag-cloud":t,"rag-cloud-ch":t}],"ik-server":[0,{jcloud:t,"jcloud-ver-jpc":t}],jelastic:[0,{demo:t}],massivegrid:Ve,wafaicloud:[0,{jed:t,ryd:t}],"eu1-plenit":t,"la1-plenit":t,"us1-plenit":t,webadorsite:t,"on-forge":t,"on-vapor":t,lpusercontent:t,linode:[0,{members:t,nodebalancer:n}],linodeobjects:n,linodeusercontent:[0,{ip:t}],localtonet:t,lovableproject:t,barsycenter:t,barsyonline:t,lutrausercontent:n,magicpatternsapp:t,modelscape:t,mwcloudnonprod:t,polyspace:t,miniserver:t,atmeta:t,fbsbx:Yt,metaaiusercontent:n,meteorapp:Xt,routingthecloud:t,"same-app":t,"same-preview":t,mydbserver:t,mochausercontent:t,hostedpi:t,"mythic-beasts":[0,{caracal:t,customer:t,fentiger:t,lynx:t,ocelot:t,oncilla:t,onza:t,sphinx:t,vs:t,x:t,yali:t}],nospamproxy:[0,{cloud:[2,{o365:t}]}],"4u":t,nfshost:t,"3utilities":t,blogsyte:t,ciscofreak:t,damnserver:t,ddnsking:t,ditchyourip:t,dnsiskinky:t,dynns:t,geekgalaxy:t,"health-carereform":t,homesecuritymac:t,homesecuritypc:t,myactivedirectory:t,mysecuritycamera:t,myvnc:t,"net-freaks":t,onthewifi:t,point2this:t,quicksytes:t,securitytactics:t,servebeer:t,servecounterstrike:t,serveexchange:t,serveftp:t,servegame:t,servehalflife:t,servehttp:t,servehumour:t,serveirc:t,servemp3:t,servep2p:t,servepics:t,servequake:t,servesarcasm:t,stufftoread:t,unusualperson:t,workisboring:t,myiphost:t,observableusercontent:[0,{static:t}],simplesite:t,oaiusercontent:n,orsites:t,operaunite:t,"customer-oci":[0,{"*":t,oci:n,ocp:n,ocs:n}],oraclecloudapps:n,oraclegovcloudapps:n,"authgear-staging":t,authgearapps:t,outsystemscloud:t,ownprovider:t,pgfog:t,gotpantheon:t,paywhirl:n,forgeblocks:t,upsunapp:t,"postman-echo":t,prgmr:[0,{xen:t}],"project-study":[0,{dev:t}],pythonanywhere:Xt,qa2:t,"alpha-myqnapcloud":t,"dev-myqnapcloud":t,mycloudnas:t,mynascloud:t,myqnapcloud:t,qualifioapp:t,ladesk:t,qualyhqpartner:n,qualyhqportal:n,qbuser:t,quipelements:n,rackmaze:t,"readthedocs-hosted":t,rhcloud:t,onrender:t,render:Ke,"subsc-pay":t,"180r":t,dojin:t,sakuratan:t,sakuraweb:t,x0:t,code:[0,{builder:n,"dev-builder":n,"stg-builder":n}],salesforce:[0,{platform:[0,{"code-builder-stg":[0,{test:[0,{"001":n}]}]}]}],logoip:t,scrysec:t,"firewall-gateway":t,myshopblocks:t,myshopify:t,shopitsite:t,"1kapp":t,appchizi:t,applinzi:t,sinaapp:t,vipsinaapp:t,streamlitapp:t,"try-snowplow":t,"playstation-cloud":t,myspreadshop:t,"w-corp-staticblitz":t,"w-credentialless-staticblitz":t,"w-staticblitz":t,"stackhero-network":t,stdlib:[0,{api:t}],strapiapp:[2,{media:t}],"streak-link":t,streaklinks:t,streakusercontent:t,"temp-dns":t,dsmynas:t,familyds:t,mytabit:t,taveusercontent:t,"tb-hosting":We,reservd:t,thingdustdata:t,"townnews-staging":t,typeform:[0,{pro:t}],hk:t,it:t,"deus-canvas":t,vivenushop:t,vultrobjects:n,wafflecell:t,hotelwithflight:t,"reserve-online":t,cprapid:t,pleskns:t,remotewd:t,wiardweb:[0,{pages:t}],"drive-platform":t,"base44-sandbox":t,wixsite:t,wixstudio:t,messwithdns:t,"woltlab-demo":t,wpenginepowered:[2,{js:t}],xnbay:[2,{u2:t,"u2-local":t}],xtooldevice:t,yolasite:t}],coop:e,cr:[1,{ac:e,co:e,ed:e,fi:e,go:e,or:e,sa:e}],cu:[1,{com:e,edu:e,gob:e,inf:e,nat:e,net:e,org:e}],cv:[1,{com:e,edu:e,id:e,int:e,net:e,nome:e,org:e,publ:e}],cw:ke,cx:[1,{gov:e,cloudns:t,ath:t,info:t,assessments:t,calculators:t,funnels:t,paynow:t,quizzes:t,researched:t,tests:t}],cy:[1,{ac:e,biz:e,com:[1,{scaleforce:Ge}],ekloges:e,gov:e,ltd:e,mil:e,net:e,org:e,press:e,pro:e,tm:e}],cz:[1,{gov:e,contentproxy9:[0,{rsc:t}],realm:t,e4:t,co:t,metacentrum:[0,{cloud:n,custom:t}],muni:[0,{cloud:[0,{flt:t,usr:t}]}]}],de:[1,{bplaced:t,square7:t,"bwcloud-os-instance":n,com:t,cosidns:Jt,dnsupdater:t,"dynamisches-dns":t,"internet-dns":t,"l-o-g-i-n":t,ddnss:[2,{dyn:t,dyndns:t}],"dyn-ip24":t,dyndns1:t,"home-webserver":[2,{dyn:t}],"myhome-server":t,dnshome:t,fuettertdasnetz:t,isteingeek:t,istmein:t,lebtimnetz:t,leitungsen:t,traeumtgerade:t,frusky:n,goip:t,"xn--gnstigbestellen-zvb":t,g\u00FCnstigbestellen:t,"xn--gnstigliefern-wob":t,g\u00FCnstigliefern:t,"hs-heilbronn":[0,{it:[0,{pages:t,"pages-research":t}]}],"dyn-berlin":t,"in-berlin":t,"in-brb":t,"in-butter":t,"in-dsl":t,"in-vpn":t,iservschule:t,"mein-iserv":t,schuldock:t,schulplattform:t,schulserver:t,"test-iserv":t,keymachine:t,co:t,"git-repos":t,"lcube-server":t,"svn-repos":t,barsy:t,webspaceconfig:t,"123webseite":t,rub:t,"ruhr-uni-bochum":[2,{noc:[0,{io:t}]}],logoip:t,"firewall-gateway":t,"my-gateway":t,"my-router":t,spdns:t,my:t,speedpartner:[0,{customer:t}],myspreadshop:t,"taifun-dns":t,"12hp":t,"2ix":t,"4lima":t,"lima-city":t,"virtual-user":t,virtualuser:t,"community-pro":t,diskussionsbereich:t,xenonconnect:n}],dj:e,dk:[1,{biz:t,co:t,firm:t,reg:t,store:t,"123hjemmeside":t,myspreadshop:t}],dm:Qt,do:[1,{art:e,com:e,edu:e,gob:e,gov:e,mil:e,net:e,org:e,sld:e,web:e}],dz:[1,{art:e,asso:e,com:e,edu:e,gov:e,net:e,org:e,pol:e,soc:e,tm:e}],ec:[1,{abg:e,adm:e,agron:e,arqt:e,art:e,bar:e,chef:e,com:e,cont:e,cpa:e,cue:e,dent:e,dgn:e,disco:e,doc:e,edu:e,eng:e,esm:e,fin:e,fot:e,gal:e,gob:e,gov:e,gye:e,ibr:e,info:e,k12:e,lat:e,loj:e,med:e,mil:e,mktg:e,mon:e,net:e,ntr:e,odont:e,org:e,pro:e,prof:e,psic:e,psiq:e,pub:e,rio:e,rrpp:e,sal:e,tech:e,tul:e,tur:e,uio:e,vet:e,xxx:e,base:t,official:t}],edu:[1,{rit:[0,{"git-pages":t}]}],ee:[1,{aip:e,com:e,edu:e,fie:e,gov:e,lib:e,med:e,org:e,pri:e,riik:e}],eg:[1,{ac:e,com:e,edu:e,eun:e,gov:e,info:e,me:e,mil:e,name:e,net:e,org:e,sci:e,sport:e,tv:e}],er:k,es:[1,{com:e,edu:e,gob:e,nom:e,org:e,"123miweb":t,myspreadshop:t}],et:[1,{biz:e,com:e,edu:e,gov:e,info:e,name:e,net:e,org:e}],eu:[1,{amazonwebservices:[0,{on:[0,{"eusc-de-east-1":[0,{"cognito-idp":b}]}]}],cloudns:t,prvw:t,deuxfleurs:t,dogado:[0,{jelastic:t}],barsy:t,spdns:t,nxa:n,directwp:t,transurl:n}],fi:[1,{aland:e,dy:t,"xn--hkkinen-5wa":t,h\u00E4kkinen:t,iki:t,cloudplatform:[0,{fi:t}],datacenter:[0,{demo:t,paas:t}],kapsi:t,"123kotisivu":t,myspreadshop:t}],fj:[1,{ac:e,biz:e,com:e,edu:e,gov:e,id:e,info:e,mil:e,name:e,net:e,org:e,pro:e}],fk:k,fm:[1,{com:e,edu:e,net:e,org:e,radio:t,user:n}],fo:e,fr:[1,{asso:e,com:e,gouv:e,nom:e,prd:e,tm:e,avoues:e,cci:e,greta:e,"huissier-justice":e,"fbx-os":t,fbxos:t,"freebox-os":t,freeboxos:t,goupile:t,kdns:t,"123siteweb":t,"on-web":t,"chirurgiens-dentistes-en-france":t,dedibox:t,aeroport:t,avocat:t,chambagri:t,"chirurgiens-dentistes":t,"experts-comptables":t,medecin:t,notaires:t,pharmacien:t,port:t,veterinaire:t,myspreadshop:t,ynh:t}],ga:e,gb:e,gd:[1,{edu:e,gov:e}],ge:[1,{com:e,edu:e,gov:e,net:e,org:e,pvt:e,school:e}],gf:e,gg:[1,{co:e,net:e,org:e,ply:[0,{at:n,d6:t}],botdash:t,kaas:t,stackit:t,panel:[2,{daemon:t}]}],gh:[1,{biz:e,com:e,edu:e,gov:e,mil:e,net:e,org:e}],gi:[1,{com:e,edu:e,gov:e,ltd:e,mod:e,org:e}],gl:[1,{co:e,com:e,edu:e,net:e,org:e}],gm:e,gn:[1,{ac:e,com:e,edu:e,gov:e,net:e,org:e}],gov:e,gp:[1,{asso:e,com:e,edu:e,mobi:e,net:e,org:e}],gq:e,gr:[1,{com:e,edu:e,gov:e,net:e,org:e,barsy:t,simplesite:t}],gs:e,gt:[1,{com:e,edu:e,gob:e,ind:e,mil:e,net:e,org:e}],gu:[1,{com:e,edu:e,gov:e,guam:e,info:e,net:e,org:e,web:e}],gw:[1,{nx:t}],gy:Qt,hk:[1,{com:e,edu:e,gov:e,idv:e,net:e,org:e,"xn--ciqpn":e,\u4E2A\u4EBA:e,"xn--gmqw5a":e,\u500B\u4EBA:e,"xn--55qx5d":e,\u516C\u53F8:e,"xn--mxtq1m":e,\u653F\u5E9C:e,"xn--lcvr32d":e,\u654E\u80B2:e,"xn--wcvs22d":e,\u6559\u80B2:e,"xn--gmq050i":e,\u7B87\u4EBA:e,"xn--uc0atv":e,\u7D44\u7E54:e,"xn--uc0ay4a":e,\u7D44\u7EC7:e,"xn--od0alg":e,\u7DB2\u7D61:e,"xn--zf0avx":e,\u7DB2\u7EDC:e,"xn--mk0axi":e,\u7EC4\u7E54:e,"xn--tn0ag":e,\u7EC4\u7EC7:e,"xn--od0aq3b":e,\u7F51\u7D61:e,"xn--io0a7i":e,\u7F51\u7EDC:e,inc:t,ltd:t}],hm:e,hn:[1,{com:e,edu:e,gob:e,mil:e,net:e,org:e}],hr:[1,{com:e,from:e,iz:e,name:e,brendly:h}],ht:[1,{adult:e,art:e,asso:e,com:e,coop:e,edu:e,firm:e,gouv:e,info:e,med:e,net:e,org:e,perso:e,pol:e,pro:e,rel:e,shop:e,rt:t}],hu:[1,{2e3:e,agrar:e,bolt:e,casino:e,city:e,co:e,erotica:e,erotika:e,film:e,forum:e,games:e,hotel:e,info:e,ingatlan:e,jogasz:e,konyvelo:e,lakas:e,media:e,news:e,org:e,priv:e,reklam:e,sex:e,shop:e,sport:e,suli:e,szex:e,tm:e,tozsde:e,utazas:e,video:e}],id:[1,{ac:e,biz:e,co:e,desa:e,go:e,kop:e,mil:e,my:e,net:e,or:e,ponpes:e,sch:e,web:e,"xn--9tfky":e,"\u1B29\u1B2E\u1B36":e,e:t,zone:t}],ie:[1,{gov:e,myspreadshop:t}],il:[1,{ac:e,co:[1,{ravpage:t,mytabit:t,tabitorder:t}],gov:e,idf:e,k12:e,muni:e,net:e,org:e}],"xn--4dbrk0ce":[1,{"xn--4dbgdty6c":e,"xn--5dbhl8d":e,"xn--8dbq2a":e,"xn--hebda8b":e}],\u05D9\u05E9\u05E8\u05D0\u05DC:[1,{\u05D0\u05E7\u05D3\u05DE\u05D9\u05D4:e,\u05D9\u05E9\u05D5\u05D1:e,\u05E6\u05D4\u05DC:e,\u05DE\u05DE\u05E9\u05DC:e}],im:[1,{ac:e,co:[1,{ltd:e,plc:e}],com:e,net:e,org:e,tt:e,tv:e}],in:[1,{"5g":e,"6g":e,ac:e,ai:e,am:e,bank:e,bihar:e,biz:e,business:e,ca:e,cn:e,co:e,com:e,coop:e,cs:e,delhi:e,dr:e,edu:e,er:e,fin:e,firm:e,gen:e,gov:e,gujarat:e,ind:e,info:e,int:e,internet:e,io:e,me:e,mil:e,net:e,nic:e,org:e,pg:e,post:e,pro:e,res:e,travel:e,tv:e,uk:e,up:e,us:e,cloudns:t,barsy:t,web:t,indevs:t,supabase:t}],info:[1,{cloudns:t,"dynamic-dns":t,"barrel-of-knowledge":t,"barrell-of-knowledge":t,dyndns:t,"for-our":t,"groks-the":t,"groks-this":t,"here-for-more":t,knowsitall:t,selfip:t,webhop:t,barsy:t,mayfirst:t,mittwald:t,mittwaldserver:t,typo3server:t,dvrcam:t,ilovecollege:t,"no-ip":t,forumz:t,nsupdate:t,dnsupdate:t,"v-info":t}],int:[1,{eu:e}],io:[1,{2038:t,co:e,com:e,edu:e,gov:e,mil:e,net:e,nom:e,org:e,"on-acorn":n,myaddr:t,apigee:t,"b-data":t,beagleboard:t,bitbucket:t,bluebite:t,boxfuse:t,brave:i,browsersafetymark:t,bubble:oe,bubbleapps:t,bigv:[0,{uk0:t}],cleverapps:t,cloudbeesusercontent:t,dappnode:[0,{dyndns:t}],darklang:t,definima:t,dedyn:t,icp0:nn,icp1:nn,qzz:t,"fh-muenster":t,gitbook:t,github:t,gitlab:t,lolipop:t,"hasura-app":t,hostyhosting:t,hypernode:t,moonscale:n,beebyte:Ve,beebyteapp:[0,{sekd1:t}],jele:t,keenetic:t,kiloapps:t,webthings:t,loginline:t,barsy:t,azurecontainer:n,ngrok:[2,{ap:t,au:t,eu:t,in:t,jp:t,sa:t,us:t}],nodeart:[0,{stage:t}],pantheonsite:t,forgerock:[0,{id:t}],pstmn:[2,{mock:t}],protonet:t,qcx:[2,{sys:n}],qoto:t,vaporcloud:t,myrdbx:t,"rb-hosting":We,"on-k3s":n,"on-rio":n,readthedocs:t,resindevice:t,resinstaging:[0,{devices:t}],hzc:t,sandcats:t,scrypted:[0,{client:t}],"mo-siemens":t,lair:Yt,stolos:n,musician:t,utwente:t,edugit:t,telebit:t,thingdust:[0,{dev:Ye,disrec:Ye,prod:on,testing:Ye}],tickets:t,webflow:t,webflowtest:t,"drive-platform":t,editorx:t,wixstudio:t,basicserver:t,virtualserver:t}],iq:a,ir:[1,{ac:e,co:e,gov:e,id:e,net:e,org:e,sch:e,"xn--mgba3a4f16a":e,\u0627\u06CC\u0631\u0627\u0646:e,"xn--mgba3a4fra":e,\u0627\u064A\u0631\u0627\u0646:e,arvanedge:t,vistablog:t}],is:e,it:[1,{edu:e,gov:e,abr:e,abruzzo:e,"aosta-valley":e,aostavalley:e,bas:e,basilicata:e,cal:e,calabria:e,cam:e,campania:e,"emilia-romagna":e,emiliaromagna:e,emr:e,"friuli-v-giulia":e,"friuli-ve-giulia":e,"friuli-vegiulia":e,"friuli-venezia-giulia":e,"friuli-veneziagiulia":e,"friuli-vgiulia":e,"friuliv-giulia":e,"friulive-giulia":e,friulivegiulia:e,"friulivenezia-giulia":e,friuliveneziagiulia:e,friulivgiulia:e,fvg:e,laz:e,lazio:e,lig:e,liguria:e,lom:e,lombardia:e,lombardy:e,lucania:e,mar:e,marche:e,mol:e,molise:e,piedmont:e,piemonte:e,pmn:e,pug:e,puglia:e,sar:e,sardegna:e,sardinia:e,sic:e,sicilia:e,sicily:e,taa:e,tos:e,toscana:e,"trentin-sud-tirol":e,"xn--trentin-sd-tirol-rzb":e,"trentin-s\xFCd-tirol":e,"trentin-sudtirol":e,"xn--trentin-sdtirol-7vb":e,"trentin-s\xFCdtirol":e,"trentin-sued-tirol":e,"trentin-suedtirol":e,trentino:e,"trentino-a-adige":e,"trentino-aadige":e,"trentino-alto-adige":e,"trentino-altoadige":e,"trentino-s-tirol":e,"trentino-stirol":e,"trentino-sud-tirol":e,"xn--trentino-sd-tirol-c3b":e,"trentino-s\xFCd-tirol":e,"trentino-sudtirol":e,"xn--trentino-sdtirol-szb":e,"trentino-s\xFCdtirol":e,"trentino-sued-tirol":e,"trentino-suedtirol":e,"trentinoa-adige":e,trentinoaadige:e,"trentinoalto-adige":e,trentinoaltoadige:e,"trentinos-tirol":e,trentinostirol:e,"trentinosud-tirol":e,"xn--trentinosd-tirol-rzb":e,"trentinos\xFCd-tirol":e,trentinosudtirol:e,"xn--trentinosdtirol-7vb":e,trentinos\u00FCdtirol:e,"trentinosued-tirol":e,trentinosuedtirol:e,"trentinsud-tirol":e,"xn--trentinsd-tirol-6vb":e,"trentins\xFCd-tirol":e,trentinsudtirol:e,"xn--trentinsdtirol-nsb":e,trentins\u00FCdtirol:e,"trentinsued-tirol":e,trentinsuedtirol:e,tuscany:e,umb:e,umbria:e,"val-d-aosta":e,"val-daosta":e,"vald-aosta":e,valdaosta:e,"valle-aosta":e,"valle-d-aosta":e,"valle-daosta":e,valleaosta:e,"valled-aosta":e,valledaosta:e,"vallee-aoste":e,"xn--valle-aoste-ebb":e,"vall\xE9e-aoste":e,"vallee-d-aoste":e,"xn--valle-d-aoste-ehb":e,"vall\xE9e-d-aoste":e,valleeaoste:e,"xn--valleaoste-e7a":e,vall\u00E9eaoste:e,valleedaoste:e,"xn--valledaoste-ebb":e,vall\u00E9edaoste:e,vao:e,vda:e,ven:e,veneto:e,ag:e,agrigento:e,al:e,alessandria:e,"alto-adige":e,altoadige:e,an:e,ancona:e,"andria-barletta-trani":e,"andria-trani-barletta":e,andriabarlettatrani:e,andriatranibarletta:e,ao:e,aosta:e,aoste:e,ap:e,aq:e,aquila:e,ar:e,arezzo:e,"ascoli-piceno":e,ascolipiceno:e,asti:e,at:e,av:e,avellino:e,ba:e,balsan:e,"balsan-sudtirol":e,"xn--balsan-sdtirol-nsb":e,"balsan-s\xFCdtirol":e,"balsan-suedtirol":e,bari:e,"barletta-trani-andria":e,barlettatraniandria:e,belluno:e,benevento:e,bergamo:e,bg:e,bi:e,biella:e,bl:e,bn:e,bo:e,bologna:e,bolzano:e,"bolzano-altoadige":e,bozen:e,"bozen-sudtirol":e,"xn--bozen-sdtirol-2ob":e,"bozen-s\xFCdtirol":e,"bozen-suedtirol":e,br:e,brescia:e,brindisi:e,bs:e,bt:e,bulsan:e,"bulsan-sudtirol":e,"xn--bulsan-sdtirol-nsb":e,"bulsan-s\xFCdtirol":e,"bulsan-suedtirol":e,bz:e,ca:e,cagliari:e,caltanissetta:e,"campidano-medio":e,campidanomedio:e,campobasso:e,"carbonia-iglesias":e,carboniaiglesias:e,"carrara-massa":e,carraramassa:e,caserta:e,catania:e,catanzaro:e,cb:e,ce:e,"cesena-forli":e,"xn--cesena-forl-mcb":e,"cesena-forl\xEC":e,cesenaforli:e,"xn--cesenaforl-i8a":e,cesenaforl\u00EC:e,ch:e,chieti:e,ci:e,cl:e,cn:e,co:e,como:e,cosenza:e,cr:e,cremona:e,crotone:e,cs:e,ct:e,cuneo:e,cz:e,"dell-ogliastra":e,dellogliastra:e,en:e,enna:e,fc:e,fe:e,fermo:e,ferrara:e,fg:e,fi:e,firenze:e,florence:e,fm:e,foggia:e,"forli-cesena":e,"xn--forl-cesena-fcb":e,"forl\xEC-cesena":e,forlicesena:e,"xn--forlcesena-c8a":e,forl\u00ECcesena:e,fr:e,frosinone:e,ge:e,genoa:e,genova:e,go:e,gorizia:e,gr:e,grosseto:e,"iglesias-carbonia":e,iglesiascarbonia:e,im:e,imperia:e,is:e,isernia:e,kr:e,"la-spezia":e,laquila:e,laspezia:e,latina:e,lc:e,le:e,lecce:e,lecco:e,li:e,livorno:e,lo:e,lodi:e,lt:e,lu:e,lucca:e,macerata:e,mantova:e,"massa-carrara":e,massacarrara:e,matera:e,mb:e,mc:e,me:e,"medio-campidano":e,mediocampidano:e,messina:e,mi:e,milan:e,milano:e,mn:e,mo:e,modena:e,monza:e,"monza-brianza":e,"monza-e-della-brianza":e,monzabrianza:e,monzaebrianza:e,monzaedellabrianza:e,ms:e,mt:e,na:e,naples:e,napoli:e,no:e,novara:e,nu:e,nuoro:e,og:e,ogliastra:e,"olbia-tempio":e,olbiatempio:e,or:e,oristano:e,ot:e,pa:e,padova:e,padua:e,palermo:e,parma:e,pavia:e,pc:e,pd:e,pe:e,perugia:e,"pesaro-urbino":e,pesarourbino:e,pescara:e,pg:e,pi:e,piacenza:e,pisa:e,pistoia:e,pn:e,po:e,pordenone:e,potenza:e,pr:e,prato:e,pt:e,pu:e,pv:e,pz:e,ra:e,ragusa:e,ravenna:e,rc:e,re:e,"reggio-calabria":e,"reggio-emilia":e,reggiocalabria:e,reggioemilia:e,rg:e,ri:e,rieti:e,rimini:e,rm:e,rn:e,ro:e,roma:e,rome:e,rovigo:e,sa:e,salerno:e,sassari:e,savona:e,si:e,siena:e,siracusa:e,so:e,sondrio:e,sp:e,sr:e,ss:e,"xn--sdtirol-n2a":e,s\u00FCdtirol:e,suedtirol:e,sv:e,ta:e,taranto:e,te:e,"tempio-olbia":e,tempioolbia:e,teramo:e,terni:e,tn:e,to:e,torino:e,tp:e,tr:e,"trani-andria-barletta":e,"trani-barletta-andria":e,traniandriabarletta:e,tranibarlettaandria:e,trapani:e,trento:e,treviso:e,trieste:e,ts:e,turin:e,tv:e,ud:e,udine:e,"urbino-pesaro":e,urbinopesaro:e,va:e,varese:e,vb:e,vc:e,ve:e,venezia:e,venice:e,verbania:e,vercelli:e,verona:e,vi:e,"vibo-valentia":e,vibovalentia:e,vicenza:e,viterbo:e,vr:e,vs:e,vt:e,vv:e,ibxos:t,iliadboxos:t,neen:[0,{jc:t}],"123homepage":t,"16-b":t,"32-b":t,"64-b":t,myspreadshop:t,syncloud:t}],je:[1,{co:e,net:e,org:e,of:t}],jm:k,jo:[1,{agri:e,ai:e,com:e,edu:e,eng:e,fm:e,gov:e,mil:e,net:e,org:e,per:e,phd:e,sch:e,tv:e}],jobs:e,jp:[1,{ac:e,ad:e,co:e,ed:e,go:e,gr:e,lg:e,ne:[1,{aseinet:tn,gehirn:t,ivory:t,"mail-box":t,mints:t,mokuren:t,opal:t,sakura:t,sumomo:t,topaz:t}],or:e,aichi:[1,{aisai:e,ama:e,anjo:e,asuke:e,chiryu:e,chita:e,fuso:e,gamagori:e,handa:e,hazu:e,hekinan:e,higashiura:e,ichinomiya:e,inazawa:e,inuyama:e,isshiki:e,iwakura:e,kanie:e,kariya:e,kasugai:e,kira:e,kiyosu:e,komaki:e,konan:e,kota:e,mihama:e,miyoshi:e,nishio:e,nisshin:e,obu:e,oguchi:e,oharu:e,okazaki:e,owariasahi:e,seto:e,shikatsu:e,shinshiro:e,shitara:e,tahara:e,takahama:e,tobishima:e,toei:e,togo:e,tokai:e,tokoname:e,toyoake:e,toyohashi:e,toyokawa:e,toyone:e,toyota:e,tsushima:e,yatomi:e}],akita:[1,{akita:e,daisen:e,fujisato:e,gojome:e,hachirogata:e,happou:e,higashinaruse:e,honjo:e,honjyo:e,ikawa:e,kamikoani:e,kamioka:e,katagami:e,kazuno:e,kitaakita:e,kosaka:e,kyowa:e,misato:e,mitane:e,moriyoshi:e,nikaho:e,noshiro:e,odate:e,oga:e,ogata:e,semboku:e,yokote:e,yurihonjo:e}],aomori:[1,{aomori:e,gonohe:e,hachinohe:e,hashikami:e,hiranai:e,hirosaki:e,itayanagi:e,kuroishi:e,misawa:e,mutsu:e,nakadomari:e,noheji:e,oirase:e,owani:e,rokunohe:e,sannohe:e,shichinohe:e,shingo:e,takko:e,towada:e,tsugaru:e,tsuruta:e}],chiba:[1,{abiko:e,asahi:e,chonan:e,chosei:e,choshi:e,chuo:e,funabashi:e,futtsu:e,hanamigawa:e,ichihara:e,ichikawa:e,ichinomiya:e,inzai:e,isumi:e,kamagaya:e,kamogawa:e,kashiwa:e,katori:e,katsuura:e,kimitsu:e,kisarazu:e,kozaki:e,kujukuri:e,kyonan:e,matsudo:e,midori:e,mihama:e,minamiboso:e,mobara:e,mutsuzawa:e,nagara:e,nagareyama:e,narashino:e,narita:e,noda:e,oamishirasato:e,omigawa:e,onjuku:e,otaki:e,sakae:e,sakura:e,shimofusa:e,shirako:e,shiroi:e,shisui:e,sodegaura:e,sosa:e,tako:e,tateyama:e,togane:e,tohnosho:e,tomisato:e,urayasu:e,yachimata:e,yachiyo:e,yokaichiba:e,yokoshibahikari:e,yotsukaido:e}],ehime:[1,{ainan:e,honai:e,ikata:e,imabari:e,iyo:e,kamijima:e,kihoku:e,kumakogen:e,masaki:e,matsuno:e,matsuyama:e,namikata:e,niihama:e,ozu:e,saijo:e,seiyo:e,shikokuchuo:e,tobe:e,toon:e,uchiko:e,uwajima:e,yawatahama:e}],fukui:[1,{echizen:e,eiheiji:e,fukui:e,ikeda:e,katsuyama:e,mihama:e,minamiechizen:e,obama:e,ohi:e,ono:e,sabae:e,sakai:e,takahama:e,tsuruga:e,wakasa:e}],fukuoka:[1,{ashiya:e,buzen:e,chikugo:e,chikuho:e,chikujo:e,chikushino:e,chikuzen:e,chuo:e,dazaifu:e,fukuchi:e,hakata:e,higashi:e,hirokawa:e,hisayama:e,iizuka:e,inatsuki:e,kaho:e,kasuga:e,kasuya:e,kawara:e,keisen:e,koga:e,kurate:e,kurogi:e,kurume:e,minami:e,miyako:e,miyama:e,miyawaka:e,mizumaki:e,munakata:e,nakagawa:e,nakama:e,nishi:e,nogata:e,ogori:e,okagaki:e,okawa:e,oki:e,omuta:e,onga:e,onojo:e,oto:e,saigawa:e,sasaguri:e,shingu:e,shinyoshitomi:e,shonai:e,soeda:e,sue:e,tachiarai:e,tagawa:e,takata:e,toho:e,toyotsu:e,tsuiki:e,ukiha:e,umi:e,usui:e,yamada:e,yame:e,yanagawa:e,yukuhashi:e}],fukushima:[1,{aizubange:e,aizumisato:e,aizuwakamatsu:e,asakawa:e,bandai:e,date:e,fukushima:e,furudono:e,futaba:e,hanawa:e,higashi:e,hirata:e,hirono:e,iitate:e,inawashiro:e,ishikawa:e,iwaki:e,izumizaki:e,kagamiishi:e,kaneyama:e,kawamata:e,kitakata:e,kitashiobara:e,koori:e,koriyama:e,kunimi:e,miharu:e,mishima:e,namie:e,nango:e,nishiaizu:e,nishigo:e,okuma:e,omotego:e,ono:e,otama:e,samegawa:e,shimogo:e,shirakawa:e,showa:e,soma:e,sukagawa:e,taishin:e,tamakawa:e,tanagura:e,tenei:e,yabuki:e,yamato:e,yamatsuri:e,yanaizu:e,yugawa:e}],gifu:[1,{anpachi:e,ena:e,gifu:e,ginan:e,godo:e,gujo:e,hashima:e,hichiso:e,hida:e,higashishirakawa:e,ibigawa:e,ikeda:e,kakamigahara:e,kani:e,kasahara:e,kasamatsu:e,kawaue:e,kitagata:e,mino:e,minokamo:e,mitake:e,mizunami:e,motosu:e,nakatsugawa:e,ogaki:e,sakahogi:e,seki:e,sekigahara:e,shirakawa:e,tajimi:e,takayama:e,tarui:e,toki:e,tomika:e,wanouchi:e,yamagata:e,yaotsu:e,yoro:e}],gunma:[1,{annaka:e,chiyoda:e,fujioka:e,higashiagatsuma:e,isesaki:e,itakura:e,kanna:e,kanra:e,katashina:e,kawaba:e,kiryu:e,kusatsu:e,maebashi:e,meiwa:e,midori:e,minakami:e,naganohara:e,nakanojo:e,nanmoku:e,numata:e,oizumi:e,ora:e,ota:e,shibukawa:e,shimonita:e,shinto:e,showa:e,takasaki:e,takayama:e,tamamura:e,tatebayashi:e,tomioka:e,tsukiyono:e,tsumagoi:e,ueno:e,yoshioka:e}],hiroshima:[1,{asaminami:e,daiwa:e,etajima:e,fuchu:e,fukuyama:e,hatsukaichi:e,higashihiroshima:e,hongo:e,jinsekikogen:e,kaita:e,kui:e,kumano:e,kure:e,mihara:e,miyoshi:e,naka:e,onomichi:e,osakikamijima:e,otake:e,saka:e,sera:e,seranishi:e,shinichi:e,shobara:e,takehara:e}],hokkaido:[1,{abashiri:e,abira:e,aibetsu:e,akabira:e,akkeshi:e,asahikawa:e,ashibetsu:e,ashoro:e,assabu:e,atsuma:e,bibai:e,biei:e,bifuka:e,bihoro:e,biratori:e,chippubetsu:e,chitose:e,date:e,ebetsu:e,embetsu:e,eniwa:e,erimo:e,esan:e,esashi:e,fukagawa:e,fukushima:e,furano:e,furubira:e,haboro:e,hakodate:e,hamatonbetsu:e,hidaka:e,higashikagura:e,higashikawa:e,hiroo:e,hokuryu:e,hokuto:e,honbetsu:e,horokanai:e,horonobe:e,ikeda:e,imakane:e,ishikari:e,iwamizawa:e,iwanai:e,kamifurano:e,kamikawa:e,kamishihoro:e,kamisunagawa:e,kamoenai:e,kayabe:e,kembuchi:e,kikonai:e,kimobetsu:e,kitahiroshima:e,kitami:e,kiyosato:e,koshimizu:e,kunneppu:e,kuriyama:e,kuromatsunai:e,kushiro:e,kutchan:e,kyowa:e,mashike:e,matsumae:e,mikasa:e,minamifurano:e,mombetsu:e,moseushi:e,mukawa:e,muroran:e,naie:e,nakagawa:e,nakasatsunai:e,nakatombetsu:e,nanae:e,nanporo:e,nayoro:e,nemuro:e,niikappu:e,niki:e,nishiokoppe:e,noboribetsu:e,numata:e,obihiro:e,obira:e,oketo:e,okoppe:e,otaru:e,otobe:e,otofuke:e,otoineppu:e,oumu:e,ozora:e,pippu:e,rankoshi:e,rebun:e,rikubetsu:e,rishiri:e,rishirifuji:e,saroma:e,sarufutsu:e,shakotan:e,shari:e,shibecha:e,shibetsu:e,shikabe:e,shikaoi:e,shimamaki:e,shimizu:e,shimokawa:e,shinshinotsu:e,shintoku:e,shiranuka:e,shiraoi:e,shiriuchi:e,sobetsu:e,sunagawa:e,taiki:e,takasu:e,takikawa:e,takinoue:e,teshikaga:e,tobetsu:e,tohma:e,tomakomai:e,tomari:e,toya:e,toyako:e,toyotomi:e,toyoura:e,tsubetsu:e,tsukigata:e,urakawa:e,urausu:e,uryu:e,utashinai:e,wakkanai:e,wassamu:e,yakumo:e,yoichi:e}],hyogo:[1,{aioi:e,akashi:e,ako:e,amagasaki:e,aogaki:e,asago:e,ashiya:e,awaji:e,fukusaki:e,goshiki:e,harima:e,himeji:e,ichikawa:e,inagawa:e,itami:e,kakogawa:e,kamigori:e,kamikawa:e,kasai:e,kasuga:e,kawanishi:e,miki:e,minamiawaji:e,nishinomiya:e,nishiwaki:e,ono:e,sanda:e,sannan:e,sasayama:e,sayo:e,shingu:e,shinonsen:e,shiso:e,sumoto:e,taishi:e,taka:e,takarazuka:e,takasago:e,takino:e,tamba:e,tatsuno:e,toyooka:e,yabu:e,yashiro:e,yoka:e,yokawa:e}],ibaraki:[1,{ami:e,asahi:e,bando:e,chikusei:e,daigo:e,fujishiro:e,hitachi:e,hitachinaka:e,hitachiomiya:e,hitachiota:e,ibaraki:e,ina:e,inashiki:e,itako:e,iwama:e,joso:e,kamisu:e,kasama:e,kashima:e,kasumigaura:e,koga:e,miho:e,mito:e,moriya:e,naka:e,namegata:e,oarai:e,ogawa:e,omitama:e,ryugasaki:e,sakai:e,sakuragawa:e,shimodate:e,shimotsuma:e,shirosato:e,sowa:e,suifu:e,takahagi:e,tamatsukuri:e,tokai:e,tomobe:e,tone:e,toride:e,tsuchiura:e,tsukuba:e,uchihara:e,ushiku:e,yachiyo:e,yamagata:e,yawara:e,yuki:e}],ishikawa:[1,{anamizu:e,hakui:e,hakusan:e,kaga:e,kahoku:e,kanazawa:e,kawakita:e,komatsu:e,nakanoto:e,nanao:e,nomi:e,nonoichi:e,noto:e,shika:e,suzu:e,tsubata:e,tsurugi:e,uchinada:e,wajima:e}],iwate:[1,{fudai:e,fujisawa:e,hanamaki:e,hiraizumi:e,hirono:e,ichinohe:e,ichinoseki:e,iwaizumi:e,iwate:e,joboji:e,kamaishi:e,kanegasaki:e,karumai:e,kawai:e,kitakami:e,kuji:e,kunohe:e,kuzumaki:e,miyako:e,mizusawa:e,morioka:e,ninohe:e,noda:e,ofunato:e,oshu:e,otsuchi:e,rikuzentakata:e,shiwa:e,shizukuishi:e,sumita:e,tanohata:e,tono:e,yahaba:e,yamada:e}],kagawa:[1,{ayagawa:e,higashikagawa:e,kanonji:e,kotohira:e,manno:e,marugame:e,mitoyo:e,naoshima:e,sanuki:e,tadotsu:e,takamatsu:e,tonosho:e,uchinomi:e,utazu:e,zentsuji:e}],kagoshima:[1,{akune:e,amami:e,hioki:e,isa:e,isen:e,izumi:e,kagoshima:e,kanoya:e,kawanabe:e,kinko:e,kouyama:e,makurazaki:e,matsumoto:e,minamitane:e,nakatane:e,nishinoomote:e,satsumasendai:e,soo:e,tarumizu:e,yusui:e}],kanagawa:[1,{aikawa:e,atsugi:e,ayase:e,chigasaki:e,ebina:e,fujisawa:e,hadano:e,hakone:e,hiratsuka:e,isehara:e,kaisei:e,kamakura:e,kiyokawa:e,matsuda:e,minamiashigara:e,miura:e,nakai:e,ninomiya:e,odawara:e,oi:e,oiso:e,sagamihara:e,samukawa:e,tsukui:e,yamakita:e,yamato:e,yokosuka:e,yugawara:e,zama:e,zushi:e}],kochi:[1,{aki:e,geisei:e,hidaka:e,higashitsuno:e,ino:e,kagami:e,kami:e,kitagawa:e,kochi:e,mihara:e,motoyama:e,muroto:e,nahari:e,nakamura:e,nankoku:e,nishitosa:e,niyodogawa:e,ochi:e,okawa:e,otoyo:e,otsuki:e,sakawa:e,sukumo:e,susaki:e,tosa:e,tosashimizu:e,toyo:e,tsuno:e,umaji:e,yasuda:e,yusuhara:e}],kumamoto:[1,{amakusa:e,arao:e,aso:e,choyo:e,gyokuto:e,kamiamakusa:e,kikuchi:e,kumamoto:e,mashiki:e,mifune:e,minamata:e,minamioguni:e,nagasu:e,nishihara:e,oguni:e,ozu:e,sumoto:e,takamori:e,uki:e,uto:e,yamaga:e,yamato:e,yatsushiro:e}],kyoto:[1,{ayabe:e,fukuchiyama:e,higashiyama:e,ide:e,ine:e,joyo:e,kameoka:e,kamo:e,kita:e,kizu:e,kumiyama:e,kyotamba:e,kyotanabe:e,kyotango:e,maizuru:e,minami:e,minamiyamashiro:e,miyazu:e,muko:e,nagaokakyo:e,nakagyo:e,nantan:e,oyamazaki:e,sakyo:e,seika:e,tanabe:e,uji:e,ujitawara:e,wazuka:e,yamashina:e,yawata:e}],mie:[1,{asahi:e,inabe:e,ise:e,kameyama:e,kawagoe:e,kiho:e,kisosaki:e,kiwa:e,komono:e,kumano:e,kuwana:e,matsusaka:e,meiwa:e,mihama:e,minamiise:e,misugi:e,miyama:e,nabari:e,shima:e,suzuka:e,tado:e,taiki:e,taki:e,tamaki:e,toba:e,tsu:e,udono:e,ureshino:e,watarai:e,yokkaichi:e}],miyagi:[1,{furukawa:e,higashimatsushima:e,ishinomaki:e,iwanuma:e,kakuda:e,kami:e,kawasaki:e,marumori:e,matsushima:e,minamisanriku:e,misato:e,murata:e,natori:e,ogawara:e,ohira:e,onagawa:e,osaki:e,rifu:e,semine:e,shibata:e,shichikashuku:e,shikama:e,shiogama:e,shiroishi:e,tagajo:e,taiwa:e,tome:e,tomiya:e,wakuya:e,watari:e,yamamoto:e,zao:e}],miyazaki:[1,{aya:e,ebino:e,gokase:e,hyuga:e,kadogawa:e,kawaminami:e,kijo:e,kitagawa:e,kitakata:e,kitaura:e,kobayashi:e,kunitomi:e,kushima:e,mimata:e,miyakonojo:e,miyazaki:e,morotsuka:e,nichinan:e,nishimera:e,nobeoka:e,saito:e,shiiba:e,shintomi:e,takaharu:e,takanabe:e,takazaki:e,tsuno:e}],nagano:[1,{achi:e,agematsu:e,anan:e,aoki:e,asahi:e,azumino:e,chikuhoku:e,chikuma:e,chino:e,fujimi:e,hakuba:e,hara:e,hiraya:e,iida:e,iijima:e,iiyama:e,iizuna:e,ikeda:e,ikusaka:e,ina:e,karuizawa:e,kawakami:e,kiso:e,kisofukushima:e,kitaaiki:e,komagane:e,komoro:e,matsukawa:e,matsumoto:e,miasa:e,minamiaiki:e,minamimaki:e,minamiminowa:e,minowa:e,miyada:e,miyota:e,mochizuki:e,nagano:e,nagawa:e,nagiso:e,nakagawa:e,nakano:e,nozawaonsen:e,obuse:e,ogawa:e,okaya:e,omachi:e,omi:e,ookuwa:e,ooshika:e,otaki:e,otari:e,sakae:e,sakaki:e,saku:e,sakuho:e,shimosuwa:e,shinanomachi:e,shiojiri:e,suwa:e,suzaka:e,takagi:e,takamori:e,takayama:e,tateshina:e,tatsuno:e,togakushi:e,togura:e,tomi:e,ueda:e,wada:e,yamagata:e,yamanouchi:e,yasaka:e,yasuoka:e}],nagasaki:[1,{chijiwa:e,futsu:e,goto:e,hasami:e,hirado:e,iki:e,isahaya:e,kawatana:e,kuchinotsu:e,matsuura:e,nagasaki:e,obama:e,omura:e,oseto:e,saikai:e,sasebo:e,seihi:e,shimabara:e,shinkamigoto:e,togitsu:e,tsushima:e,unzen:e}],nara:[1,{ando:e,gose:e,heguri:e,higashiyoshino:e,ikaruga:e,ikoma:e,kamikitayama:e,kanmaki:e,kashiba:e,kashihara:e,katsuragi:e,kawai:e,kawakami:e,kawanishi:e,koryo:e,kurotaki:e,mitsue:e,miyake:e,nara:e,nosegawa:e,oji:e,ouda:e,oyodo:e,sakurai:e,sango:e,shimoichi:e,shimokitayama:e,shinjo:e,soni:e,takatori:e,tawaramoto:e,tenkawa:e,tenri:e,uda:e,yamatokoriyama:e,yamatotakada:e,yamazoe:e,yoshino:e}],niigata:[1,{aga:e,agano:e,gosen:e,itoigawa:e,izumozaki:e,joetsu:e,kamo:e,kariwa:e,kashiwazaki:e,minamiuonuma:e,mitsuke:e,muika:e,murakami:e,myoko:e,nagaoka:e,niigata:e,ojiya:e,omi:e,sado:e,sanjo:e,seiro:e,seirou:e,sekikawa:e,shibata:e,tagami:e,tainai:e,tochio:e,tokamachi:e,tsubame:e,tsunan:e,uonuma:e,yahiko:e,yoita:e,yuzawa:e}],oita:[1,{beppu:e,bungoono:e,bungotakada:e,hasama:e,hiji:e,himeshima:e,hita:e,kamitsue:e,kokonoe:e,kuju:e,kunisaki:e,kusu:e,oita:e,saiki:e,taketa:e,tsukumi:e,usa:e,usuki:e,yufu:e}],okayama:[1,{akaiwa:e,asakuchi:e,bizen:e,hayashima:e,ibara:e,kagamino:e,kasaoka:e,kibichuo:e,kumenan:e,kurashiki:e,maniwa:e,misaki:e,nagi:e,niimi:e,nishiawakura:e,okayama:e,satosho:e,setouchi:e,shinjo:e,shoo:e,soja:e,takahashi:e,tamano:e,tsuyama:e,wake:e,yakage:e}],okinawa:[1,{aguni:e,ginowan:e,ginoza:e,gushikami:e,haebaru:e,higashi:e,hirara:e,iheya:e,ishigaki:e,ishikawa:e,itoman:e,izena:e,kadena:e,kin:e,kitadaito:e,kitanakagusuku:e,kumejima:e,kunigami:e,minamidaito:e,motobu:e,nago:e,naha:e,nakagusuku:e,nakijin:e,nanjo:e,nishihara:e,ogimi:e,okinawa:e,onna:e,shimoji:e,taketomi:e,tarama:e,tokashiki:e,tomigusuku:e,tonaki:e,urasoe:e,uruma:e,yaese:e,yomitan:e,yonabaru:e,yonaguni:e,zamami:e}],osaka:[1,{abeno:e,chihayaakasaka:e,chuo:e,daito:e,fujiidera:e,habikino:e,hannan:e,higashiosaka:e,higashisumiyoshi:e,higashiyodogawa:e,hirakata:e,ibaraki:e,ikeda:e,izumi:e,izumiotsu:e,izumisano:e,kadoma:e,kaizuka:e,kanan:e,kashiwara:e,katano:e,kawachinagano:e,kishiwada:e,kita:e,kumatori:e,matsubara:e,minato:e,minoh:e,misaki:e,moriguchi:e,neyagawa:e,nishi:e,nose:e,osakasayama:e,sakai:e,sayama:e,sennan:e,settsu:e,shijonawate:e,shimamoto:e,suita:e,tadaoka:e,taishi:e,tajiri:e,takaishi:e,takatsuki:e,tondabayashi:e,toyonaka:e,toyono:e,yao:e}],saga:[1,{ariake:e,arita:e,fukudomi:e,genkai:e,hamatama:e,hizen:e,imari:e,kamimine:e,kanzaki:e,karatsu:e,kashima:e,kitagata:e,kitahata:e,kiyama:e,kouhoku:e,kyuragi:e,nishiarita:e,ogi:e,omachi:e,ouchi:e,saga:e,shiroishi:e,taku:e,tara:e,tosu:e,yoshinogari:e}],saitama:[1,{arakawa:e,asaka:e,chichibu:e,fujimi:e,fujimino:e,fukaya:e,hanno:e,hanyu:e,hasuda:e,hatogaya:e,hatoyama:e,hidaka:e,higashichichibu:e,higashimatsuyama:e,honjo:e,ina:e,iruma:e,iwatsuki:e,kamiizumi:e,kamikawa:e,kamisato:e,kasukabe:e,kawagoe:e,kawaguchi:e,kawajima:e,kazo:e,kitamoto:e,koshigaya:e,kounosu:e,kuki:e,kumagaya:e,matsubushi:e,minano:e,misato:e,miyashiro:e,miyoshi:e,moroyama:e,nagatoro:e,namegawa:e,niiza:e,ogano:e,ogawa:e,ogose:e,okegawa:e,omiya:e,otaki:e,ranzan:e,ryokami:e,saitama:e,sakado:e,satte:e,sayama:e,shiki:e,shiraoka:e,soka:e,sugito:e,toda:e,tokigawa:e,tokorozawa:e,tsurugashima:e,urawa:e,warabi:e,yashio:e,yokoze:e,yono:e,yorii:e,yoshida:e,yoshikawa:e,yoshimi:e}],shiga:[1,{aisho:e,gamo:e,higashiomi:e,hikone:e,koka:e,konan:e,kosei:e,koto:e,kusatsu:e,maibara:e,moriyama:e,nagahama:e,nishiazai:e,notogawa:e,omihachiman:e,otsu:e,ritto:e,ryuoh:e,takashima:e,takatsuki:e,torahime:e,toyosato:e,yasu:e}],shimane:[1,{akagi:e,ama:e,gotsu:e,hamada:e,higashiizumo:e,hikawa:e,hikimi:e,izumo:e,kakinoki:e,masuda:e,matsue:e,misato:e,nishinoshima:e,ohda:e,okinoshima:e,okuizumo:e,shimane:e,tamayu:e,tsuwano:e,unnan:e,yakumo:e,yasugi:e,yatsuka:e}],shizuoka:[1,{arai:e,atami:e,fuji:e,fujieda:e,fujikawa:e,fujinomiya:e,fukuroi:e,gotemba:e,haibara:e,hamamatsu:e,higashiizu:e,ito:e,iwata:e,izu:e,izunokuni:e,kakegawa:e,kannami:e,kawanehon:e,kawazu:e,kikugawa:e,kosai:e,makinohara:e,matsuzaki:e,minamiizu:e,mishima:e,morimachi:e,nishiizu:e,numazu:e,omaezaki:e,shimada:e,shimizu:e,shimoda:e,shizuoka:e,susono:e,yaizu:e,yoshida:e}],tochigi:[1,{ashikaga:e,bato:e,haga:e,ichikai:e,iwafune:e,kaminokawa:e,kanuma:e,karasuyama:e,kuroiso:e,mashiko:e,mibu:e,moka:e,motegi:e,nasu:e,nasushiobara:e,nikko:e,nishikata:e,nogi:e,ohira:e,ohtawara:e,oyama:e,sakura:e,sano:e,shimotsuke:e,shioya:e,takanezawa:e,tochigi:e,tsuga:e,ujiie:e,utsunomiya:e,yaita:e}],tokushima:[1,{aizumi:e,anan:e,ichiba:e,itano:e,kainan:e,komatsushima:e,matsushige:e,mima:e,minami:e,miyoshi:e,mugi:e,nakagawa:e,naruto:e,sanagochi:e,shishikui:e,tokushima:e,wajiki:e}],tokyo:[1,{adachi:e,akiruno:e,akishima:e,aogashima:e,arakawa:e,bunkyo:e,chiyoda:e,chofu:e,chuo:e,edogawa:e,fuchu:e,fussa:e,hachijo:e,hachioji:e,hamura:e,higashikurume:e,higashimurayama:e,higashiyamato:e,hino:e,hinode:e,hinohara:e,inagi:e,itabashi:e,katsushika:e,kita:e,kiyose:e,kodaira:e,koganei:e,kokubunji:e,komae:e,koto:e,kouzushima:e,kunitachi:e,machida:e,meguro:e,minato:e,mitaka:e,mizuho:e,musashimurayama:e,musashino:e,nakano:e,nerima:e,ogasawara:e,okutama:e,ome:e,oshima:e,ota:e,setagaya:e,shibuya:e,shinagawa:e,shinjuku:e,suginami:e,sumida:e,tachikawa:e,taito:e,tama:e,toshima:e}],tottori:[1,{chizu:e,hino:e,kawahara:e,koge:e,kotoura:e,misasa:e,nanbu:e,nichinan:e,sakaiminato:e,tottori:e,wakasa:e,yazu:e,yonago:e}],toyama:[1,{asahi:e,fuchu:e,fukumitsu:e,funahashi:e,himi:e,imizu:e,inami:e,johana:e,kamiichi:e,kurobe:e,nakaniikawa:e,namerikawa:e,nanto:e,nyuzen:e,oyabe:e,taira:e,takaoka:e,tateyama:e,toga:e,tonami:e,toyama:e,unazuki:e,uozu:e,yamada:e}],wakayama:[1,{arida:e,aridagawa:e,gobo:e,hashimoto:e,hidaka:e,hirogawa:e,inami:e,iwade:e,kainan:e,kamitonda:e,katsuragi:e,kimino:e,kinokawa:e,kitayama:e,koya:e,koza:e,kozagawa:e,kudoyama:e,kushimoto:e,mihama:e,misato:e,nachikatsuura:e,shingu:e,shirahama:e,taiji:e,tanabe:e,wakayama:e,yuasa:e,yura:e}],yamagata:[1,{asahi:e,funagata:e,higashine:e,iide:e,kahoku:e,kaminoyama:e,kaneyama:e,kawanishi:e,mamurogawa:e,mikawa:e,murayama:e,nagai:e,nakayama:e,nanyo:e,nishikawa:e,obanazawa:e,oe:e,oguni:e,ohkura:e,oishida:e,sagae:e,sakata:e,sakegawa:e,shinjo:e,shirataka:e,shonai:e,takahata:e,tendo:e,tozawa:e,tsuruoka:e,yamagata:e,yamanobe:e,yonezawa:e,yuza:e}],yamaguchi:[1,{abu:e,hagi:e,hikari:e,hofu:e,iwakuni:e,kudamatsu:e,mitou:e,nagato:e,oshima:e,shimonoseki:e,shunan:e,tabuse:e,tokuyama:e,toyota:e,ube:e,yuu:e}],yamanashi:[1,{chuo:e,doshi:e,fuefuki:e,fujikawa:e,fujikawaguchiko:e,fujiyoshida:e,hayakawa:e,hokuto:e,ichikawamisato:e,kai:e,kofu:e,koshu:e,kosuge:e,"minami-alps":e,minobu:e,nakamichi:e,nanbu:e,narusawa:e,nirasaki:e,nishikatsura:e,oshino:e,otsuki:e,showa:e,tabayama:e,tsuru:e,uenohara:e,yamanakako:e,yamanashi:e}],"xn--ehqz56n":e,\u4E09\u91CD:e,"xn--1lqs03n":e,\u4EAC\u90FD:e,"xn--qqqt11m":e,\u4F50\u8CC0:e,"xn--f6qx53a":e,\u5175\u5EAB:e,"xn--djrs72d6uy":e,\u5317\u6D77\u9053:e,"xn--mkru45i":e,\u5343\u8449:e,"xn--0trq7p7nn":e,\u548C\u6B4C\u5C71:e,"xn--5js045d":e,\u57FC\u7389:e,"xn--kbrq7o":e,\u5927\u5206:e,"xn--pssu33l":e,\u5927\u962A:e,"xn--ntsq17g":e,\u5948\u826F:e,"xn--uisz3g":e,\u5BAE\u57CE:e,"xn--6btw5a":e,\u5BAE\u5D0E:e,"xn--1ctwo":e,\u5BCC\u5C71:e,"xn--6orx2r":e,\u5C71\u53E3:e,"xn--rht61e":e,\u5C71\u5F62:e,"xn--rht27z":e,\u5C71\u68A8:e,"xn--nit225k":e,\u5C90\u961C:e,"xn--rht3d":e,\u5CA1\u5C71:e,"xn--djty4k":e,\u5CA9\u624B:e,"xn--klty5x":e,\u5CF6\u6839:e,"xn--kltx9a":e,\u5E83\u5CF6:e,"xn--kltp7d":e,\u5FB3\u5CF6:e,"xn--c3s14m":e,\u611B\u5A9B:e,"xn--vgu402c":e,\u611B\u77E5:e,"xn--efvn9s":e,\u65B0\u6F5F:e,"xn--1lqs71d":e,\u6771\u4EAC:e,"xn--4pvxs":e,\u6803\u6728:e,"xn--uuwu58a":e,\u6C96\u7E04:e,"xn--zbx025d":e,\u6ECB\u8CC0:e,"xn--8pvr4u":e,\u718A\u672C:e,"xn--5rtp49c":e,\u77F3\u5DDD:e,"xn--ntso0iqx3a":e,\u795E\u5948\u5DDD:e,"xn--elqq16h":e,\u798F\u4E95:e,"xn--4it168d":e,\u798F\u5CA1:e,"xn--klt787d":e,\u798F\u5CF6:e,"xn--rny31h":e,\u79CB\u7530:e,"xn--7t0a264c":e,\u7FA4\u99AC:e,"xn--uist22h":e,\u8328\u57CE:e,"xn--8ltr62k":e,\u9577\u5D0E:e,"xn--2m4a15e":e,\u9577\u91CE:e,"xn--32vp30h":e,\u9752\u68EE:e,"xn--4it797k":e,\u9759\u5CA1:e,"xn--5rtq34k":e,\u9999\u5DDD:e,"xn--k7yn95e":e,\u9AD8\u77E5:e,"xn--tor131o":e,\u9CE5\u53D6:e,"xn--d5qv7z876c":e,\u9E7F\u5150\u5CF6:e,kawasaki:k,kitakyushu:k,kobe:k,nagoya:k,sapporo:k,sendai:k,yokohama:k,buyshop:t,fashionstore:t,handcrafted:t,kawaiishop:t,supersale:t,theshop:t,"0am":t,"0g0":t,"0j0":t,"0t0":t,mydns:t,pgw:t,wjg:t,usercontent:t,angry:t,babyblue:t,babymilk:t,backdrop:t,bambina:t,bitter:t,blush:t,boo:t,boy:t,boyfriend:t,but:t,candypop:t,capoo:t,catfood:t,cheap:t,chicappa:t,chillout:t,chips:t,chowder:t,chu:t,ciao:t,cocotte:t,coolblog:t,cranky:t,cutegirl:t,daa:t,deca:t,deci:t,digick:t,egoism:t,fakefur:t,fem:t,flier:t,floppy:t,fool:t,frenchkiss:t,girlfriend:t,girly:t,gloomy:t,gonna:t,greater:t,hacca:t,heavy:t,her:t,hiho:t,hippy:t,holy:t,hungry:t,icurus:t,itigo:t,jellybean:t,kikirara:t,kill:t,kilo:t,kuron:t,littlestar:t,lolipopmc:t,lolitapunk:t,lomo:t,lovepop:t,lovesick:t,main:t,mods:t,mond:t,mongolian:t,moo:t,namaste:t,nikita:t,nobushi:t,noor:t,oops:t,parallel:t,parasite:t,pecori:t,peewee:t,penne:t,pepper:t,perma:t,pigboat:t,pinoko:t,punyu:t,pupu:t,pussycat:t,pya:t,raindrop:t,readymade:t,sadist:t,schoolbus:t,secret:t,staba:t,stripper:t,sub:t,sunnyday:t,thick:t,tonkotsu:t,under:t,upper:t,velvet:t,verse:t,versus:t,vivian:t,watson:t,weblike:t,whitesnow:t,zombie:t,hateblo:t,hatenablog:t,hatenadiary:t,"2-d":t,bona:t,crap:t,daynight:t,eek:t,flop:t,halfmoon:t,jeez:t,matrix:t,mimoza:t,netgamers:t,nyanta:t,o0o0:t,rdy:t,rgr:t,rulez:t,sakurastorage:[0,{isk01:Xe,isk02:Xe}],saloon:t,sblo:t,skr:t,tank:t,"uh-oh":t,undo:t,webaccel:[0,{rs:t,user:t}],websozai:t,xii:t}],ke:[1,{ac:e,co:e,go:e,info:e,me:e,mobi:e,ne:e,or:e,sc:e}],kg:[1,{com:e,edu:e,gov:e,mil:e,net:e,org:e,us:t,xx:t,ae:t}],kh:o,ki:an,km:[1,{ass:e,com:e,edu:e,gov:e,mil:e,nom:e,org:e,prd:e,tm:e,asso:e,coop:e,gouv:e,medecin:e,notaires:e,pharmaciens:e,presse:e,veterinaire:e}],kn:[1,{edu:e,gov:e,net:e,org:e}],kp:[1,{com:e,edu:e,gov:e,org:e,rep:e,tra:e}],kr:[1,{ac:e,ai:e,co:e,es:e,go:e,hs:e,io:e,it:e,kg:e,me:e,mil:e,ms:e,ne:e,or:e,pe:e,re:e,sc:e,busan:e,chungbuk:e,chungnam:e,daegu:e,daejeon:e,gangwon:e,gwangju:e,gyeongbuk:e,gyeonggi:e,gyeongnam:e,incheon:e,jeju:e,jeonbuk:e,jeonnam:e,seoul:e,ulsan:e,c01:t,"eliv-api":t,"eliv-cdn":t,"eliv-dns":t,mmv:t,vki:t}],kw:[1,{com:e,edu:e,emb:e,gov:e,ind:e,net:e,org:e}],ky:ke,kz:[1,{com:e,edu:e,gov:e,mil:e,net:e,org:e,jcloud:t}],la:[1,{com:e,edu:e,gov:e,info:e,int:e,net:e,org:e,per:e,bnr:t}],lb:o,lc:[1,{co:e,com:e,edu:e,gov:e,net:e,org:e,oy:t}],li:e,lk:[1,{ac:e,assn:e,com:e,edu:e,gov:e,grp:e,hotel:e,int:e,ltd:e,net:e,ngo:e,org:e,sch:e,soc:e,web:e}],lr:o,ls:[1,{ac:e,biz:e,co:e,edu:e,gov:e,info:e,net:e,org:e,sc:e}],lt:c,lu:[1,{"123website":t}],lv:[1,{asn:e,com:e,conf:e,edu:e,gov:e,id:e,mil:e,net:e,org:e}],ly:[1,{com:e,edu:e,gov:e,id:e,med:e,net:e,org:e,plc:e,sch:e}],ma:[1,{ac:e,co:e,gov:e,net:e,org:e,press:e}],mc:[1,{asso:e,tm:e}],md:[1,{ir:t}],me:[1,{ac:e,co:e,edu:e,gov:e,its:e,net:e,org:e,priv:e,c66:t,craft:t,edgestack:t,mybox:t,filegear:t,hooc:[0,{seprox:t}],"filegear-sg":t,lohmus:t,barsy:t,mcdir:t,brasilia:t,ddns:t,dnsfor:t,hopto:t,loginto:t,noip:t,webhop:t,soundcast:t,tcp4:t,vp4:t,diskstation:t,dscloud:t,i234:t,myds:t,synology:t,transip:We,nohost:t}],mg:[1,{co:e,com:e,edu:e,gov:e,mil:e,nom:e,org:e,prd:e}],mh:e,mil:e,mk:[1,{com:e,edu:e,gov:e,inf:e,name:e,net:e,org:e}],ml:[1,{ac:e,art:e,asso:e,com:e,edu:e,gouv:e,gov:e,info:e,inst:e,net:e,org:e,pr:e,presse:e}],mm:k,mn:[1,{edu:e,gov:e,org:e,nyc:t}],mo:o,mobi:[1,{barsy:t,dscloud:t}],mp:[1,{ju:t}],mq:e,mr:c,ms:[1,{com:e,edu:e,gov:e,net:e,org:e,minisite:t}],mt:ke,mu:[1,{ac:e,co:e,com:e,gov:e,net:e,or:e,org:e}],museum:e,mv:[1,{aero:e,biz:e,com:e,coop:e,edu:e,gov:e,info:e,int:e,mil:e,museum:e,name:e,net:e,org:e,pro:e}],mw:[1,{ac:e,biz:e,co:e,com:e,coop:e,edu:e,gov:e,int:e,net:e,org:e}],mx:[1,{com:e,edu:e,gob:e,net:e,org:e}],my:[1,{biz:e,com:e,edu:e,gov:e,mil:e,name:e,net:e,org:e}],mz:[1,{ac:e,adv:e,co:e,edu:e,gov:e,mil:e,net:e,org:e}],na:[1,{alt:e,co:e,com:e,gov:e,net:e,org:e}],name:[1,{her:rn,his:rn,ispmanager:t,keenetic:t}],nc:[1,{asso:e,nom:e}],ne:e,net:[1,{adobeaemcloud:t,"adobeio-static":t,adobeioruntime:t,akadns:t,akamai:t,"akamai-staging":t,akamaiedge:t,"akamaiedge-staging":t,akamaihd:t,"akamaihd-staging":t,akamaiorigin:t,"akamaiorigin-staging":t,akamaized:t,"akamaized-staging":t,edgekey:t,"edgekey-staging":t,edgesuite:t,"edgesuite-staging":t,alwaysdata:t,myamaze:t,cloudfront:t,appudo:t,"atlassian-dev":[0,{prod:oe}],myfritz:t,shopselect:t,blackbaudcdn:t,boomla:t,bplaced:t,square7:t,cdn77:[0,{r:t}],"cdn77-ssl":t,gb:t,hu:t,jp:t,se:t,uk:t,clickrising:t,"ddns-ip":t,"dns-cloud":t,"dns-dynamic":t,cloudaccess:t,cloudflare:[2,{cdn:t}],cloudflareanycast:oe,cloudflarecn:oe,cloudflareglobal:oe,ctfcloud:t,"feste-ip":t,"knx-server":t,"static-access":t,cryptonomic:n,dattolocal:t,mydatto:t,debian:t,definima:t,deno:[2,{sandbox:t}],icp:n,de5:t,"at-band-camp":t,blogdns:t,"broke-it":t,buyshouses:t,dnsalias:t,dnsdojo:t,"does-it":t,dontexist:t,dynalias:t,dynathome:t,endofinternet:t,"from-az":t,"from-co":t,"from-la":t,"from-ny":t,"gets-it":t,"ham-radio-op":t,homeftp:t,homeip:t,homelinux:t,homeunix:t,"in-the-band":t,"is-a-chef":t,"is-a-geek":t,"isa-geek":t,"kicks-ass":t,"office-on-the":t,podzone:t,"scrapper-site":t,selfip:t,"sells-it":t,servebbs:t,serveftp:t,thruhere:t,webhop:t,casacam:t,dynu:t,dynuddns:t,mysynology:t,opik:t,spryt:t,dynv6:t,twmail:t,ru:t,channelsdvr:[2,{u:t}],fastly:[0,{freetls:t,map:t,prod:[0,{a:t,global:t}],ssl:[0,{a:t,b:t,global:t}]}],fastlylb:[2,{map:t}],"keyword-on":t,"live-on":t,"server-on":t,"cdn-edges":t,heteml:t,cloudfunctions:t,"grafana-dev":t,iobb:t,moonscale:t,"in-dsl":t,"in-vpn":t,oninferno:t,botdash:t,"apps-1and1":t,ipifony:t,cloudjiffy:[2,{"fra1-de":t,"west1-us":t}],elastx:[0,{"jls-sto1":t,"jls-sto2":t,"jls-sto3":t}],massivegrid:[0,{paas:[0,{"fr-1":t,"lon-1":t,"lon-2":t,"ny-1":t,"ny-2":t,"sg-1":t}]}],saveincloud:[0,{jelastic:t,"nordeste-idc":t}],scaleforce:Ge,kinghost:t,uni5:t,krellian:t,ggff:t,localto:n,barsy:t,luyani:t,memset:t,"azure-api":t,"azure-mobile":t,azureedge:t,azurefd:t,azurestaticapps:[2,{1:t,2:t,3:t,4:t,5:t,6:t,7:t,centralus:t,eastasia:t,eastus2:t,westeurope:t,westus2:t}],azurewebsites:t,cloudapp:t,trafficmanager:t,usgovcloudapi:sn,usgovcloudapp:t,usgovtrafficmanager:t,windows:sn,mynetname:[0,{sn:t}],routingthecloud:t,bounceme:t,ddns:t,"eating-organic":t,mydissent:t,myeffect:t,mymediapc:t,mypsx:t,mysecuritycamera:t,nhlfan:t,"no-ip":t,pgafan:t,privatizehealthinsurance:t,redirectme:t,serveblog:t,serveminecraft:t,sytes:t,dnsup:t,hicam:t,"now-dns":t,ownip:t,vpndns:t,cloudycluster:t,ovh:[0,{hosting:n,webpaas:n}],rackmaze:t,myradweb:t,in:t,"subsc-pay":t,squares:t,schokokeks:t,"firewall-gateway":t,seidat:t,senseering:t,siteleaf:t,mafelo:t,myspreadshop:t,"vps-host":[2,{jelastic:[0,{atl:t,njs:t,ric:t}]}],srcf:[0,{soc:t,user:t}],supabase:t,dsmynas:t,familyds:t,ts:[2,{c:n}],torproject:[2,{pages:t}],tunnelmole:t,vusercontent:t,"reserve-online":t,localcert:t,"community-pro":t,meinforum:t,yandexcloud:[2,{storage:t,website:t}],za:t,zabc:t}],nf:[1,{arts:e,com:e,firm:e,info:e,net:e,other:e,per:e,rec:e,store:e,web:e}],ng:[1,{com:e,edu:e,gov:e,i:e,mil:e,mobi:e,name:e,net:e,org:e,sch:e,biz:[2,{co:t,dl:t,go:t,lg:t,on:t}],col:t,firm:t,gen:t,ltd:t,ngo:t,plc:t}],ni:[1,{ac:e,biz:e,co:e,com:e,edu:e,gob:e,in:e,info:e,int:e,mil:e,net:e,nom:e,org:e,web:e}],nl:[1,{co:t,"hosting-cluster":t,gov:t,khplay:t,"123website":t,myspreadshop:t,transurl:n,cistron:t,demon:t}],no:[1,{fhs:e,folkebibl:e,fylkesbibl:e,idrett:e,museum:e,priv:e,vgs:e,dep:e,herad:e,kommune:e,mil:e,stat:e,aa:v,ah:v,bu:v,fm:v,hl:v,hm:v,"jan-mayen":v,mr:v,nl:v,nt:v,of:v,ol:v,oslo:v,rl:v,sf:v,st:v,svalbard:v,tm:v,tr:v,va:v,vf:v,akrehamn:e,"xn--krehamn-dxa":e,\u00E5krehamn:e,algard:e,"xn--lgrd-poac":e,\u00E5lg\u00E5rd:e,arna:e,bronnoysund:e,"xn--brnnysund-m8ac":e,br\u00F8nn\u00F8ysund:e,brumunddal:e,bryne:e,drobak:e,"xn--drbak-wua":e,dr\u00F8bak:e,egersund:e,fetsund:e,floro:e,"xn--flor-jra":e,flor\u00F8:e,fredrikstad:e,hokksund:e,honefoss:e,"xn--hnefoss-q1a":e,h\u00F8nefoss:e,jessheim:e,jorpeland:e,"xn--jrpeland-54a":e,j\u00F8rpeland:e,kirkenes:e,kopervik:e,krokstadelva:e,langevag:e,"xn--langevg-jxa":e,langev\u00E5g:e,leirvik:e,mjondalen:e,"xn--mjndalen-64a":e,mj\u00F8ndalen:e,"mo-i-rana":e,mosjoen:e,"xn--mosjen-eya":e,mosj\u00F8en:e,nesoddtangen:e,orkanger:e,osoyro:e,"xn--osyro-wua":e,os\u00F8yro:e,raholt:e,"xn--rholt-mra":e,r\u00E5holt:e,sandnessjoen:e,"xn--sandnessjen-ogb":e,sandnessj\u00F8en:e,skedsmokorset:e,slattum:e,spjelkavik:e,stathelle:e,stavern:e,stjordalshalsen:e,"xn--stjrdalshalsen-sqb":e,stj\u00F8rdalshalsen:e,tananger:e,tranby:e,vossevangen:e,aarborte:e,aejrie:e,afjord:e,"xn--fjord-lra":e,\u00E5fjord:e,agdenes:e,akershus:cn,aknoluokta:e,"xn--koluokta-7ya57h":e,\u00E1k\u014Boluokta:e,al:e,"xn--l-1fa":e,\u00E5l:e,alaheadju:e,"xn--laheadju-7ya":e,\u00E1laheadju:e,alesund:e,"xn--lesund-hua":e,\u00E5lesund:e,alstahaug:e,alta:e,"xn--lt-liac":e,\u00E1lt\u00E1:e,alvdal:e,amli:e,"xn--mli-tla":e,\u00E5mli:e,amot:e,"xn--mot-tla":e,\u00E5mot:e,andasuolo:e,andebu:e,andoy:e,"xn--andy-ira":e,and\u00F8y:e,ardal:e,"xn--rdal-poa":e,\u00E5rdal:e,aremark:e,arendal:e,"xn--s-1fa":e,\u00E5s:e,aseral:e,"xn--seral-lra":e,\u00E5seral:e,asker:e,askim:e,askoy:e,"xn--asky-ira":e,ask\u00F8y:e,askvoll:e,asnes:e,"xn--snes-poa":e,\u00E5snes:e,audnedaln:e,aukra:e,aure:e,aurland:e,"aurskog-holand":e,"xn--aurskog-hland-jnb":e,"aurskog-h\xF8land":e,austevoll:e,austrheim:e,averoy:e,"xn--avery-yua":e,aver\u00F8y:e,badaddja:e,"xn--bdddj-mrabd":e,b\u00E5d\u00E5ddj\u00E5:e,"xn--brum-voa":e,b\u00E6rum:e,bahcavuotna:e,"xn--bhcavuotna-s4a":e,b\u00E1hcavuotna:e,bahccavuotna:e,"xn--bhccavuotna-k7a":e,b\u00E1hccavuotna:e,baidar:e,"xn--bidr-5nac":e,b\u00E1id\u00E1r:e,bajddar:e,"xn--bjddar-pta":e,b\u00E1jddar:e,balat:e,"xn--blt-elab":e,b\u00E1l\u00E1t:e,balestrand:e,ballangen:e,balsfjord:e,bamble:e,bardu:e,barum:e,batsfjord:e,"xn--btsfjord-9za":e,b\u00E5tsfjord:e,bearalvahki:e,"xn--bearalvhki-y4a":e,bearalv\u00E1hki:e,beardu:e,beiarn:e,berg:e,bergen:e,berlevag:e,"xn--berlevg-jxa":e,berlev\u00E5g:e,bievat:e,"xn--bievt-0qa":e,biev\u00E1t:e,bindal:e,birkenes:e,bjerkreim:e,bjugn:e,bodo:e,"xn--bod-2na":e,bod\u00F8:e,bokn:e,bomlo:e,"xn--bmlo-gra":e,b\u00F8mlo:e,bremanger:e,bronnoy:e,"xn--brnny-wuac":e,br\u00F8nn\u00F8y:e,budejju:e,buskerud:cn,bygland:e,bykle:e,cahcesuolo:e,"xn--hcesuolo-7ya35b":e,\u010D\u00E1hcesuolo:e,davvenjarga:e,"xn--davvenjrga-y4a":e,davvenj\u00E1rga:e,davvesiida:e,deatnu:e,dielddanuorri:e,divtasvuodna:e,divttasvuotna:e,donna:e,"xn--dnna-gra":e,d\u00F8nna:e,dovre:e,drammen:e,drangedal:e,dyroy:e,"xn--dyry-ira":e,dyr\u00F8y:e,eid:e,eidfjord:e,eidsberg:e,eidskog:e,eidsvoll:e,eigersund:e,elverum:e,enebakk:e,engerdal:e,etne:e,etnedal:e,evenassi:e,"xn--eveni-0qa01ga":e,even\u00E1\u0161\u0161i:e,evenes:e,"evje-og-hornnes":e,farsund:e,fauske:e,fedje:e,fet:e,finnoy:e,"xn--finny-yua":e,finn\u00F8y:e,fitjar:e,fjaler:e,fjell:e,fla:e,"xn--fl-zia":e,fl\u00E5:e,flakstad:e,flatanger:e,flekkefjord:e,flesberg:e,flora:e,folldal:e,forde:e,"xn--frde-gra":e,f\u00F8rde:e,forsand:e,fosnes:e,"xn--frna-woa":e,fr\u00E6na:e,frana:e,frei:e,frogn:e,froland:e,frosta:e,froya:e,"xn--frya-hra":e,fr\u00F8ya:e,fuoisku:e,fuossko:e,fusa:e,fyresdal:e,gaivuotna:e,"xn--givuotna-8ya":e,g\u00E1ivuotna:e,galsa:e,"xn--gls-elac":e,g\u00E1ls\u00E1:e,gamvik:e,gangaviika:e,"xn--ggaviika-8ya47h":e,g\u00E1\u014Bgaviika:e,gaular:e,gausdal:e,giehtavuoatna:e,gildeskal:e,"xn--gildeskl-g0a":e,gildesk\u00E5l:e,giske:e,gjemnes:e,gjerdrum:e,gjerstad:e,gjesdal:e,gjovik:e,"xn--gjvik-wua":e,gj\u00F8vik:e,gloppen:e,gol:e,gran:e,grane:e,granvin:e,gratangen:e,grimstad:e,grong:e,grue:e,gulen:e,guovdageaidnu:e,ha:e,"xn--h-2fa":e,h\u00E5:e,habmer:e,"xn--hbmer-xqa":e,h\u00E1bmer:e,hadsel:e,"xn--hgebostad-g3a":e,h\u00E6gebostad:e,hagebostad:e,halden:e,halsa:e,hamar:e,hamaroy:e,hammarfeasta:e,"xn--hmmrfeasta-s4ac":e,h\u00E1mm\u00E1rfeasta:e,hammerfest:e,hapmir:e,"xn--hpmir-xqa":e,h\u00E1pmir:e,haram:e,hareid:e,harstad:e,hasvik:e,hattfjelldal:e,haugesund:e,hedmark:[0,{os:e,valer:e,"xn--vler-qoa":e,v\u00E5ler:e}],hemne:e,hemnes:e,hemsedal:e,hitra:e,hjartdal:e,hjelmeland:e,hobol:e,"xn--hobl-ira":e,hob\u00F8l:e,hof:e,hol:e,hole:e,holmestrand:e,holtalen:e,"xn--holtlen-hxa":e,holt\u00E5len:e,hordaland:[0,{os:e}],hornindal:e,horten:e,hoyanger:e,"xn--hyanger-q1a":e,h\u00F8yanger:e,hoylandet:e,"xn--hylandet-54a":e,h\u00F8ylandet:e,hurdal:e,hurum:e,hvaler:e,hyllestad:e,ibestad:e,inderoy:e,"xn--indery-fya":e,inder\u00F8y:e,iveland:e,ivgu:e,jevnaker:e,jolster:e,"xn--jlster-bya":e,j\u00F8lster:e,jondal:e,kafjord:e,"xn--kfjord-iua":e,k\u00E5fjord:e,karasjohka:e,"xn--krjohka-hwab49j":e,k\u00E1r\u00E1\u0161johka:e,karasjok:e,karlsoy:e,karmoy:e,"xn--karmy-yua":e,karm\u00F8y:e,kautokeino:e,klabu:e,"xn--klbu-woa":e,kl\u00E6bu:e,klepp:e,kongsberg:e,kongsvinger:e,kraanghke:e,"xn--kranghke-b0a":e,kr\u00E5anghke:e,kragero:e,"xn--krager-gya":e,krager\u00F8:e,kristiansand:e,kristiansund:e,krodsherad:e,"xn--krdsherad-m8a":e,kr\u00F8dsherad:e,"xn--kvfjord-nxa":e,kv\u00E6fjord:e,"xn--kvnangen-k0a":e,kv\u00E6nangen:e,kvafjord:e,kvalsund:e,kvam:e,kvanangen:e,kvinesdal:e,kvinnherad:e,kviteseid:e,kvitsoy:e,"xn--kvitsy-fya":e,kvits\u00F8y:e,laakesvuemie:e,"xn--lrdal-sra":e,l\u00E6rdal:e,lahppi:e,"xn--lhppi-xqa":e,l\u00E1hppi:e,lardal:e,larvik:e,lavagis:e,lavangen:e,leangaviika:e,"xn--leagaviika-52b":e,lea\u014Bgaviika:e,lebesby:e,leikanger:e,leirfjord:e,leka:e,leksvik:e,lenvik:e,lerdal:e,lesja:e,levanger:e,lier:e,lierne:e,lillehammer:e,lillesand:e,lindas:e,"xn--linds-pra":e,lind\u00E5s:e,lindesnes:e,loabat:e,"xn--loabt-0qa":e,loab\u00E1t:e,lodingen:e,"xn--ldingen-q1a":e,l\u00F8dingen:e,lom:e,loppa:e,lorenskog:e,"xn--lrenskog-54a":e,l\u00F8renskog:e,loten:e,"xn--lten-gra":e,l\u00F8ten:e,lund:e,lunner:e,luroy:e,"xn--lury-ira":e,lur\u00F8y:e,luster:e,lyngdal:e,lyngen:e,malatvuopmi:e,"xn--mlatvuopmi-s4a":e,m\u00E1latvuopmi:e,malselv:e,"xn--mlselv-iua":e,m\u00E5lselv:e,malvik:e,mandal:e,marker:e,marnardal:e,masfjorden:e,masoy:e,"xn--msy-ula0h":e,m\u00E5s\u00F8y:e,"matta-varjjat":e,"xn--mtta-vrjjat-k7af":e,"m\xE1tta-v\xE1rjjat":e,meland:e,meldal:e,melhus:e,meloy:e,"xn--mely-ira":e,mel\u00F8y:e,meraker:e,"xn--merker-kua":e,mer\u00E5ker:e,midsund:e,"midtre-gauldal":e,moareke:e,"xn--moreke-jua":e,mo\u00E5reke:e,modalen:e,modum:e,molde:e,"more-og-romsdal":[0,{heroy:e,sande:e}],"xn--mre-og-romsdal-qqb":[0,{"xn--hery-ira":e,sande:e}],"m\xF8re-og-romsdal":[0,{her\u00F8y:e,sande:e}],moskenes:e,moss:e,muosat:e,"xn--muost-0qa":e,muos\u00E1t:e,naamesjevuemie:e,"xn--nmesjevuemie-tcba":e,n\u00E5\u00E5mesjevuemie:e,"xn--nry-yla5g":e,n\u00E6r\u00F8y:e,namdalseid:e,namsos:e,namsskogan:e,nannestad:e,naroy:e,narviika:e,narvik:e,naustdal:e,navuotna:e,"xn--nvuotna-hwa":e,n\u00E1vuotna:e,"nedre-eiker":e,nesna:e,nesodden:e,nesseby:e,nesset:e,nissedal:e,nittedal:e,"nord-aurdal":e,"nord-fron":e,"nord-odal":e,norddal:e,nordkapp:e,nordland:[0,{bo:e,"xn--b-5ga":e,b\u00F8:e,heroy:e,"xn--hery-ira":e,her\u00F8y:e}],"nordre-land":e,nordreisa:e,"nore-og-uvdal":e,notodden:e,notteroy:e,"xn--nttery-byae":e,n\u00F8tter\u00F8y:e,odda:e,oksnes:e,"xn--ksnes-uua":e,\u00F8ksnes:e,omasvuotna:e,oppdal:e,oppegard:e,"xn--oppegrd-ixa":e,oppeg\u00E5rd:e,orkdal:e,orland:e,"xn--rland-uua":e,\u00F8rland:e,orskog:e,"xn--rskog-uua":e,\u00F8rskog:e,orsta:e,"xn--rsta-fra":e,\u00F8rsta:e,osen:e,osteroy:e,"xn--ostery-fya":e,oster\u00F8y:e,ostfold:[0,{valer:e}],"xn--stfold-9xa":[0,{"xn--vler-qoa":e}],\u00F8stfold:[0,{v\u00E5ler:e}],"ostre-toten":e,"xn--stre-toten-zcb":e,"\xF8stre-toten":e,overhalla:e,"ovre-eiker":e,"xn--vre-eiker-k8a":e,"\xF8vre-eiker":e,oyer:e,"xn--yer-zna":e,\u00F8yer:e,oygarden:e,"xn--ygarden-p1a":e,\u00F8ygarden:e,"oystre-slidre":e,"xn--ystre-slidre-ujb":e,"\xF8ystre-slidre":e,porsanger:e,porsangu:e,"xn--porsgu-sta26f":e,pors\u00E1\u014Bgu:e,porsgrunn:e,rade:e,"xn--rde-ula":e,r\u00E5de:e,radoy:e,"xn--rady-ira":e,rad\u00F8y:e,"xn--rlingen-mxa":e,r\u00E6lingen:e,rahkkeravju:e,"xn--rhkkervju-01af":e,r\u00E1hkker\u00E1vju:e,raisa:e,"xn--risa-5na":e,r\u00E1isa:e,rakkestad:e,ralingen:e,rana:e,randaberg:e,rauma:e,rendalen:e,rennebu:e,rennesoy:e,"xn--rennesy-v1a":e,rennes\u00F8y:e,rindal:e,ringebu:e,ringerike:e,ringsaker:e,risor:e,"xn--risr-ira":e,ris\u00F8r:e,rissa:e,roan:e,rodoy:e,"xn--rdy-0nab":e,r\u00F8d\u00F8y:e,rollag:e,romsa:e,romskog:e,"xn--rmskog-bya":e,r\u00F8mskog:e,roros:e,"xn--rros-gra":e,r\u00F8ros:e,rost:e,"xn--rst-0na":e,r\u00F8st:e,royken:e,"xn--ryken-vua":e,r\u00F8yken:e,royrvik:e,"xn--ryrvik-bya":e,r\u00F8yrvik:e,ruovat:e,rygge:e,salangen:e,salat:e,"xn--slat-5na":e,s\u00E1lat:e,"xn--slt-elab":e,s\u00E1l\u00E1t:e,saltdal:e,samnanger:e,sandefjord:e,sandnes:e,sandoy:e,"xn--sandy-yua":e,sand\u00F8y:e,sarpsborg:e,sauda:e,sauherad:e,sel:e,selbu:e,selje:e,seljord:e,siellak:e,sigdal:e,siljan:e,sirdal:e,skanit:e,"xn--sknit-yqa":e,sk\u00E1nit:e,skanland:e,"xn--sknland-fxa":e,sk\u00E5nland:e,skaun:e,skedsmo:e,ski:e,skien:e,skierva:e,"xn--skierv-uta":e,skierv\u00E1:e,skiptvet:e,skjak:e,"xn--skjk-soa":e,skj\u00E5k:e,skjervoy:e,"xn--skjervy-v1a":e,skjerv\u00F8y:e,skodje:e,smola:e,"xn--smla-hra":e,sm\u00F8la:e,snaase:e,"xn--snase-nra":e,sn\u00E5ase:e,snasa:e,"xn--snsa-roa":e,sn\u00E5sa:e,snillfjord:e,snoasa:e,sogndal:e,sogne:e,"xn--sgne-gra":e,s\u00F8gne:e,sokndal:e,sola:e,solund:e,somna:e,"xn--smna-gra":e,s\u00F8mna:e,"sondre-land":e,"xn--sndre-land-0cb":e,"s\xF8ndre-land":e,songdalen:e,"sor-aurdal":e,"xn--sr-aurdal-l8a":e,"s\xF8r-aurdal":e,"sor-fron":e,"xn--sr-fron-q1a":e,"s\xF8r-fron":e,"sor-odal":e,"xn--sr-odal-q1a":e,"s\xF8r-odal":e,"sor-varanger":e,"xn--sr-varanger-ggb":e,"s\xF8r-varanger":e,sorfold:e,"xn--srfold-bya":e,s\u00F8rfold:e,sorreisa:e,"xn--srreisa-q1a":e,s\u00F8rreisa:e,sortland:e,sorum:e,"xn--srum-gra":e,s\u00F8rum:e,spydeberg:e,stange:e,stavanger:e,steigen:e,steinkjer:e,stjordal:e,"xn--stjrdal-s1a":e,stj\u00F8rdal:e,stokke:e,"stor-elvdal":e,stord:e,stordal:e,storfjord:e,strand:e,stranda:e,stryn:e,sula:e,suldal:e,sund:e,sunndal:e,surnadal:e,sveio:e,svelvik:e,sykkylven:e,tana:e,telemark:[0,{bo:e,"xn--b-5ga":e,b\u00F8:e}],time:e,tingvoll:e,tinn:e,tjeldsund:e,tjome:e,"xn--tjme-hra":e,tj\u00F8me:e,tokke:e,tolga:e,tonsberg:e,"xn--tnsberg-q1a":e,t\u00F8nsberg:e,torsken:e,"xn--trna-woa":e,tr\u00E6na:e,trana:e,tranoy:e,"xn--trany-yua":e,tran\u00F8y:e,troandin:e,trogstad:e,"xn--trgstad-r1a":e,tr\u00F8gstad:e,tromsa:e,tromso:e,"xn--troms-zua":e,troms\u00F8:e,trondheim:e,trysil:e,tvedestrand:e,tydal:e,tynset:e,tysfjord:e,tysnes:e,"xn--tysvr-vra":e,tysv\u00E6r:e,tysvar:e,ullensaker:e,ullensvang:e,ulvik:e,unjarga:e,"xn--unjrga-rta":e,unj\u00E1rga:e,utsira:e,vaapste:e,vadso:e,"xn--vads-jra":e,vads\u00F8:e,"xn--vry-yla5g":e,v\u00E6r\u00F8y:e,vaga:e,"xn--vg-yiab":e,v\u00E5g\u00E5:e,vagan:e,"xn--vgan-qoa":e,v\u00E5gan:e,vagsoy:e,"xn--vgsy-qoa0j":e,v\u00E5gs\u00F8y:e,vaksdal:e,valle:e,vang:e,vanylven:e,vardo:e,"xn--vard-jra":e,vard\u00F8:e,varggat:e,"xn--vrggt-xqad":e,v\u00E1rgg\u00E1t:e,varoy:e,vefsn:e,vega:e,vegarshei:e,"xn--vegrshei-c0a":e,veg\u00E5rshei:e,vennesla:e,verdal:e,verran:e,vestby:e,vestfold:[0,{sande:e}],vestnes:e,"vestre-slidre":e,"vestre-toten":e,vestvagoy:e,"xn--vestvgy-ixa6o":e,vestv\u00E5g\u00F8y:e,vevelstad:e,vik:e,vikna:e,vindafjord:e,voagat:e,volda:e,voss:e,co:t,"123hjemmeside":t,myspreadshop:t}],np:k,nr:an,nu:[1,{merseine:t,mine:t,shacknet:t,enterprisecloud:t}],nz:[1,{ac:e,co:e,cri:e,geek:e,gen:e,govt:e,health:e,iwi:e,kiwi:e,maori:e,"xn--mori-qsa":e,m\u0101ori:e,mil:e,net:e,org:e,parliament:e,school:e,cloudns:t}],om:[1,{co:e,com:e,edu:e,gov:e,med:e,museum:e,net:e,org:e,pro:e}],onion:e,org:[1,{altervista:t,pimienta:t,poivron:t,potager:t,sweetpepper:t,cdn77:[0,{c:t,rsc:t}],"cdn77-secure":[0,{origin:[0,{ssl:t}]}],ae:t,cloudns:t,"ip-dynamic":t,ddnss:t,dpdns:t,duckdns:t,tunk:t,blogdns:t,blogsite:t,boldlygoingnowhere:t,dnsalias:t,dnsdojo:t,doesntexist:t,dontexist:t,doomdns:t,dvrdns:t,dynalias:t,dyndns:[2,{go:t,home:t}],endofinternet:t,endoftheinternet:t,"from-me":t,"game-host":t,gotdns:t,"hobby-site":t,homedns:t,homeftp:t,homelinux:t,homeunix:t,"is-a-bruinsfan":t,"is-a-candidate":t,"is-a-celticsfan":t,"is-a-chef":t,"is-a-geek":t,"is-a-knight":t,"is-a-linux-user":t,"is-a-patsfan":t,"is-a-soxfan":t,"is-found":t,"is-lost":t,"is-saved":t,"is-very-bad":t,"is-very-evil":t,"is-very-good":t,"is-very-nice":t,"is-very-sweet":t,"isa-geek":t,"kicks-ass":t,misconfused:t,podzone:t,readmyblog:t,selfip:t,sellsyourhome:t,servebbs:t,serveftp:t,servegame:t,"stuff-4-sale":t,webhop:t,accesscam:t,camdvr:t,freeddns:t,mywire:t,roxa:t,webredirect:t,twmail:t,eu:[2,{al:t,asso:t,at:t,au:t,be:t,bg:t,ca:t,cd:t,ch:t,cn:t,cy:t,cz:t,de:t,dk:t,edu:t,ee:t,es:t,fi:t,fr:t,gr:t,hr:t,hu:t,ie:t,il:t,in:t,int:t,is:t,it:t,jp:t,kr:t,lt:t,lu:t,lv:t,me:t,mk:t,mt:t,my:t,net:t,ng:t,nl:t,no:t,nz:t,pl:t,pt:t,ro:t,ru:t,se:t,si:t,sk:t,tr:t,uk:t,us:t}],fspages:t,fedorainfracloud:t,fedorapeople:t,fedoraproject:[0,{cloud:t,os:Ke,stg:[0,{os:Ke}]}],freedesktop:t,hatenadiary:t,hepforge:t,"in-dsl":t,"in-vpn":t,js:t,barsy:t,mayfirst:t,routingthecloud:t,bmoattachments:t,"cable-modem":t,collegefan:t,couchpotatofries:t,hopto:t,mlbfan:t,myftp:t,mysecuritycamera:t,nflfan:t,"no-ip":t,"read-books":t,ufcfan:t,zapto:t,dynserv:t,"now-dns":t,"is-local":t,httpbin:t,pubtls:t,jpn:t,"my-firewall":t,myfirewall:t,spdns:t,"small-web":t,dsmynas:t,familyds:t,teckids:Xe,tuxfamily:t,hk:t,us:t,toolforge:t,wmcloud:[2,{beta:t}],wmflabs:t,za:t}],pa:[1,{abo:e,ac:e,com:e,edu:e,gob:e,ing:e,med:e,net:e,nom:e,org:e,sld:e}],pe:[1,{com:e,edu:e,gob:e,mil:e,net:e,nom:e,org:e}],pf:[1,{com:e,edu:e,org:e}],pg:k,ph:[1,{com:e,edu:e,gov:e,i:e,mil:e,net:e,ngo:e,org:e,cloudns:t}],pk:[1,{ac:e,biz:e,com:e,edu:e,fam:e,gkp:e,gob:e,gog:e,gok:e,gop:e,gos:e,gov:e,net:e,org:e,web:e}],pl:[1,{com:e,net:e,org:e,agro:e,aid:e,atm:e,auto:e,biz:e,edu:e,gmina:e,gsm:e,info:e,mail:e,media:e,miasta:e,mil:e,nieruchomosci:e,nom:e,pc:e,powiat:e,priv:e,realestate:e,rel:e,sex:e,shop:e,sklep:e,sos:e,szkola:e,targi:e,tm:e,tourism:e,travel:e,turystyka:e,gov:[1,{ap:e,griw:e,ic:e,is:e,kmpsp:e,konsulat:e,kppsp:e,kwp:e,kwpsp:e,mup:e,mw:e,oia:e,oirm:e,oke:e,oow:e,oschr:e,oum:e,pa:e,pinb:e,piw:e,po:e,pr:e,psp:e,psse:e,pup:e,rzgw:e,sa:e,sdn:e,sko:e,so:e,sr:e,starostwo:e,ug:e,ugim:e,um:e,umig:e,upow:e,uppo:e,us:e,uw:e,uzs:e,wif:e,wiih:e,winb:e,wios:e,witd:e,wiw:e,wkz:e,wsa:e,wskr:e,wsse:e,wuoz:e,wzmiuw:e,zp:e,zpisdn:e}],augustow:e,"babia-gora":e,bedzin:e,beskidy:e,bialowieza:e,bialystok:e,bielawa:e,bieszczady:e,boleslawiec:e,bydgoszcz:e,bytom:e,cieszyn:e,czeladz:e,czest:e,dlugoleka:e,elblag:e,elk:e,glogow:e,gniezno:e,gorlice:e,grajewo:e,ilawa:e,jaworzno:e,"jelenia-gora":e,jgora:e,kalisz:e,karpacz:e,kartuzy:e,kaszuby:e,katowice:e,"kazimierz-dolny":e,kepno:e,ketrzyn:e,klodzko:e,kobierzyce:e,kolobrzeg:e,konin:e,konskowola:e,kutno:e,lapy:e,lebork:e,legnica:e,lezajsk:e,limanowa:e,lomza:e,lowicz:e,lubin:e,lukow:e,malbork:e,malopolska:e,mazowsze:e,mazury:e,mielec:e,mielno:e,mragowo:e,naklo:e,nowaruda:e,nysa:e,olawa:e,olecko:e,olkusz:e,olsztyn:e,opoczno:e,opole:e,ostroda:e,ostroleka:e,ostrowiec:e,ostrowwlkp:e,pila:e,pisz:e,podhale:e,podlasie:e,polkowice:e,pomorskie:e,pomorze:e,prochowice:e,pruszkow:e,przeworsk:e,pulawy:e,radom:e,"rawa-maz":e,rybnik:e,rzeszow:e,sanok:e,sejny:e,skoczow:e,slask:e,slupsk:e,sosnowiec:e,"stalowa-wola":e,starachowice:e,stargard:e,suwalki:e,swidnica:e,swiebodzin:e,swinoujscie:e,szczecin:e,szczytno:e,tarnobrzeg:e,tgory:e,turek:e,tychy:e,ustka:e,walbrzych:e,warmia:e,warszawa:e,waw:e,wegrow:e,wielun:e,wlocl:e,wloclawek:e,wodzislaw:e,wolomin:e,wroclaw:e,zachpomor:e,zagan:e,zarow:e,zgora:e,zgorzelec:e,art:t,gliwice:t,krakow:t,poznan:t,wroc:t,zakopane:t,beep:t,"ecommerce-shop":t,cfolks:t,dfirma:t,dkonto:t,you2:t,shoparena:t,homesklep:t,sdscloud:t,unicloud:t,lodz:t,pabianice:t,plock:t,sieradz:t,skierniewice:t,zgierz:t,krasnik:t,leczna:t,lubartow:t,lublin:t,poniatowa:t,swidnik:t,co:t,torun:t,simplesite:t,myspreadshop:t,gda:t,gdansk:t,gdynia:t,med:t,sopot:t,bielsko:t}],pm:[1,{own:t,name:t}],pn:[1,{co:e,edu:e,gov:e,net:e,org:e}],post:e,pr:[1,{biz:e,com:e,edu:e,gov:e,info:e,isla:e,name:e,net:e,org:e,pro:e,ac:e,est:e,prof:e}],pro:[1,{aaa:e,aca:e,acct:e,avocat:e,bar:e,cpa:e,eng:e,jur:e,law:e,med:e,recht:e,cloudns:t,keenetic:t,barsy:t,ngrok:t}],ps:[1,{com:e,edu:e,gov:e,net:e,org:e,plo:e,sec:e}],pt:[1,{com:e,edu:e,gov:e,int:e,net:e,nome:e,org:e,publ:e,"123paginaweb":t}],pw:[1,{gov:e,cloudns:t,x443:t}],py:[1,{com:e,coop:e,edu:e,gov:e,mil:e,net:e,org:e}],qa:[1,{com:e,edu:e,gov:e,mil:e,name:e,net:e,org:e,sch:e}],re:[1,{asso:e,com:e,netlib:t,can:t}],ro:[1,{arts:e,com:e,firm:e,info:e,nom:e,nt:e,org:e,rec:e,store:e,tm:e,www:e,co:t,shop:t,barsy:t}],rs:[1,{ac:e,co:e,edu:e,gov:e,in:e,org:e,brendly:h,barsy:t,ox:t}],ru:[1,{ac:t,edu:t,gov:t,int:t,mil:t,eurodir:t,adygeya:t,bashkiria:t,bir:t,cbg:t,com:t,dagestan:t,grozny:t,kalmykia:t,kustanai:t,marine:t,mordovia:t,msk:t,mytis:t,nalchik:t,nov:t,pyatigorsk:t,spb:t,vladikavkaz:t,vladimir:t,na4u:t,mircloud:t,myjino:[2,{hosting:n,landing:n,spectrum:n,vps:n}],cldmail:[0,{hb:t}],mcdir:[2,{vps:t}],mcpre:t,net:t,org:t,pp:t,ras:t}],rw:[1,{ac:e,co:e,coop:e,gov:e,mil:e,net:e,org:e}],sa:[1,{com:e,edu:e,gov:e,med:e,net:e,org:e,pub:e,sch:e}],sb:o,sc:o,sd:[1,{com:e,edu:e,gov:e,info:e,med:e,net:e,org:e,tv:e}],se:[1,{a:e,ac:e,b:e,bd:e,brand:e,c:e,d:e,e,f:e,fh:e,fhsk:e,fhv:e,g:e,h:e,i:e,k:e,komforb:e,kommunalforbund:e,komvux:e,l:e,lanbib:e,m:e,n:e,naturbruksgymn:e,o:e,org:e,p:e,parti:e,pp:e,press:e,r:e,s:e,t:e,tm:e,u:e,w:e,x:e,y:e,z:e,com:t,iopsys:t,"123minsida":t,itcouldbewor:t,myspreadshop:t}],sg:[1,{com:e,edu:e,gov:e,net:e,org:e,enscaled:t}],sh:[1,{com:e,gov:e,mil:e,net:e,org:e,hashbang:t,botda:t,lovable:t,platform:[0,{ent:t,eu:t,us:t}],teleport:t,now:t}],si:[1,{f5:t,gitapp:t,gitpage:t}],sj:e,sk:[1,{org:e}],sl:o,sm:e,sn:[1,{art:e,com:e,edu:e,gouv:e,org:e,univ:e}],so:[1,{com:e,edu:e,gov:e,me:e,net:e,org:e,surveys:t}],sr:e,ss:[1,{biz:e,co:e,com:e,edu:e,gov:e,me:e,net:e,org:e,sch:e}],st:[1,{co:e,com:e,consulado:e,edu:e,embaixada:e,mil:e,net:e,org:e,principe:e,saotome:e,store:e,helioho:t,cn:n,kirara:t,noho:t}],su:[1,{abkhazia:t,adygeya:t,aktyubinsk:t,arkhangelsk:t,armenia:t,ashgabad:t,azerbaijan:t,balashov:t,bashkiria:t,bryansk:t,bukhara:t,chimkent:t,dagestan:t,"east-kazakhstan":t,exnet:t,georgia:t,grozny:t,ivanovo:t,jambyl:t,kalmykia:t,kaluga:t,karacol:t,karaganda:t,karelia:t,khakassia:t,krasnodar:t,kurgan:t,kustanai:t,lenug:t,mangyshlak:t,mordovia:t,msk:t,murmansk:t,nalchik:t,navoi:t,"north-kazakhstan":t,nov:t,obninsk:t,penza:t,pokrovsk:t,sochi:t,spb:t,tashkent:t,termez:t,togliatti:t,troitsk:t,tselinograd:t,tula:t,tuva:t,vladikavkaz:t,vladimir:t,vologda:t}],sv:[1,{com:e,edu:e,gob:e,org:e,red:e}],sx:c,sy:a,sz:[1,{ac:e,co:e,org:e}],tc:e,td:e,tel:e,tf:[1,{sch:t}],tg:e,th:[1,{ac:e,co:e,go:e,in:e,mi:e,net:e,or:e,online:t,shop:t}],tj:[1,{ac:e,biz:e,co:e,com:e,edu:e,go:e,gov:e,int:e,mil:e,name:e,net:e,nic:e,org:e,test:e,web:e}],tk:e,tl:c,tm:[1,{co:e,com:e,edu:e,gov:e,mil:e,net:e,nom:e,org:e}],tn:[1,{com:e,ens:e,fin:e,gov:e,ind:e,info:e,intl:e,mincom:e,nat:e,net:e,org:e,perso:e,tourism:e,orangecloud:t}],to:[1,{611:t,com:e,edu:e,gov:e,mil:e,net:e,org:e,oya:t,x0:t,quickconnect:ne,vpnplus:t,nett:t}],tr:[1,{av:e,bbs:e,bel:e,biz:e,com:e,dr:e,edu:e,gen:e,gov:e,info:e,k12:e,kep:e,mil:e,name:e,net:e,org:e,pol:e,tel:e,tsk:e,tv:e,web:e,nc:c}],tt:[1,{biz:e,co:e,com:e,edu:e,gov:e,info:e,mil:e,name:e,net:e,org:e,pro:e}],tv:[1,{"better-than":t,dyndns:t,"on-the-web":t,"worse-than":t,from:t,sakura:t}],tw:[1,{club:e,com:[1,{mymailer:t}],ebiz:e,edu:e,game:e,gov:e,idv:e,mil:e,net:e,org:e,url:t,mydns:t}],tz:[1,{ac:e,co:e,go:e,hotel:e,info:e,me:e,mil:e,mobi:e,ne:e,or:e,sc:e,tv:e}],ua:[1,{com:e,edu:e,gov:e,in:e,net:e,org:e,cherkassy:e,cherkasy:e,chernigov:e,chernihiv:e,chernivtsi:e,chernovtsy:e,ck:e,cn:e,cr:e,crimea:e,cv:e,dn:e,dnepropetrovsk:e,dnipropetrovsk:e,donetsk:e,dp:e,if:e,"ivano-frankivsk":e,kh:e,kharkiv:e,kharkov:e,kherson:e,khmelnitskiy:e,khmelnytskyi:e,kiev:e,kirovograd:e,km:e,kr:e,kropyvnytskyi:e,krym:e,ks:e,kv:e,kyiv:e,lg:e,lt:e,lugansk:e,luhansk:e,lutsk:e,lv:e,lviv:e,mk:e,mykolaiv:e,nikolaev:e,od:e,odesa:e,odessa:e,pl:e,poltava:e,rivne:e,rovno:e,rv:e,sb:e,sebastopol:e,sevastopol:e,sm:e,sumy:e,te:e,ternopil:e,uz:e,uzhgorod:e,uzhhorod:e,vinnica:e,vinnytsia:e,vn:e,volyn:e,yalta:e,zakarpattia:e,zaporizhzhe:e,zaporizhzhia:e,zhitomir:e,zhytomyr:e,zp:e,zt:e,cc:t,inf:t,ltd:t,cx:t,biz:t,co:t,pp:t,v:t}],ug:[1,{ac:e,co:e,com:e,edu:e,go:e,gov:e,mil:e,ne:e,or:e,org:e,sc:e,us:e}],uk:[1,{ac:e,co:[1,{bytemark:[0,{dh:t,vm:t}],layershift:Ge,barsy:t,barsyonline:t,retrosnub:on,"nh-serv":t,"no-ip":t,adimo:t,myspreadshop:t}],gov:[1,{api:t,campaign:t,service:t}],ltd:e,me:e,net:e,nhs:e,org:[1,{glug:t,lug:t,lugs:t,affinitylottery:t,raffleentry:t,weeklylottery:t}],plc:e,police:e,sch:k,conn:t,copro:t,hosp:t,"independent-commission":t,"independent-inquest":t,"independent-inquiry":t,"independent-panel":t,"independent-review":t,"public-inquiry":t,"royal-commission":t,pymnt:t,barsy:t,nimsite:t,oraclegovcloudapps:n}],us:[1,{dni:e,isa:e,nsn:e,ak:g,al:g,ar:g,as:g,az:g,ca:g,co:g,ct:g,dc:g,de:ln,fl:g,ga:g,gu:g,hi:we,ia:g,id:g,il:g,in:g,ks:g,ky:g,la:g,ma:[1,{k12:[1,{chtr:e,paroch:e,pvt:e}],cc:e,lib:e}],md:g,me:g,mi:[1,{k12:e,cc:e,lib:e,"ann-arbor":e,cog:e,dst:e,eaton:e,gen:e,mus:e,tec:e,washtenaw:e}],mn:g,mo:g,ms:[1,{k12:e,cc:e}],mt:g,nc:g,nd:we,ne:g,nh:g,nj:g,nm:g,nv:g,ny:g,oh:g,ok:g,or:g,pa:g,pr:g,ri:we,sc:g,sd:we,tn:g,tx:g,ut:g,va:g,vi:g,vt:g,wa:[1,{k12:e,cc:e,lib:e,aberdeen:t,"bainbridge-isl":t,bellevue:t,bremerton:t,centralia:t,chehalis:t,forks:t,"gig-harbor":t,hoquiam:t,keyport:t,kingston:t,olympia:t,"port-angeles":t,"port-ludlow":t,"port-orchard":t,"port-townsend":t,poulsbo:t,redmond:t,renton:t,sea:t,seattle:t,sequim:t,shelton:t,silverdale:t,"yarrow-point":t}],wi:g,wv:ln,wy:g,cloudns:t,"is-by":t,"land-4-sale":t,"stuff-4-sale":t,heliohost:t,enscaled:[0,{phx:t}],mircloud:t,"azure-api":t,azurewebsites:t,ngo:t,golffan:t,noip:t,pointto:t,freeddns:t,srv:[2,{gh:t,gl:t}],servername:t}],uy:[1,{com:e,edu:e,gub:e,mil:e,net:e,org:e,gv:t}],uz:[1,{co:e,com:e,net:e,org:e}],va:e,vc:[1,{com:e,edu:e,gov:e,mil:e,net:e,org:e,gv:[2,{d:t}],"0e":n,mydns:t}],ve:[1,{arts:e,bib:e,co:e,com:e,e12:e,edu:e,emprende:e,firm:e,gob:e,gov:e,ia:e,info:e,int:e,mil:e,net:e,nom:e,org:e,rar:e,rec:e,store:e,tec:e,web:e}],vg:[1,{edu:e}],vi:[1,{co:e,com:e,k12:e,net:e,org:e}],vn:[1,{ac:e,ai:e,biz:e,com:e,edu:e,gov:e,health:e,id:e,info:e,int:e,io:e,name:e,net:e,org:e,pro:e,angiang:e,bacgiang:e,backan:e,baclieu:e,bacninh:e,"baria-vungtau":e,bentre:e,binhdinh:e,binhduong:e,binhphuoc:e,binhthuan:e,camau:e,cantho:e,caobang:e,daklak:e,daknong:e,danang:e,dienbien:e,dongnai:e,dongthap:e,gialai:e,hagiang:e,haiduong:e,haiphong:e,hanam:e,hanoi:e,hatinh:e,haugiang:e,hoabinh:e,hue:e,hungyen:e,khanhhoa:e,kiengiang:e,kontum:e,laichau:e,lamdong:e,langson:e,laocai:e,longan:e,namdinh:e,nghean:e,ninhbinh:e,ninhthuan:e,phutho:e,phuyen:e,quangbinh:e,quangnam:e,quangngai:e,quangninh:e,quangtri:e,soctrang:e,sonla:e,tayninh:e,thaibinh:e,thainguyen:e,thanhhoa:e,thanhphohochiminh:e,thuathienhue:e,tiengiang:e,travinh:e,tuyenquang:e,vinhlong:e,vinhphuc:e,yenbai:e}],vu:ke,wf:[1,{biz:t,sch:t}],ws:[1,{com:e,edu:e,gov:e,net:e,org:e,advisor:n,cloud66:t,dyndns:t,mypets:t}],yt:[1,{org:t}],"xn--mgbaam7a8h":e,\u0627\u0645\u0627\u0631\u0627\u062A:e,"xn--y9a3aq":e,\u0570\u0561\u0575:e,"xn--54b7fta0cc":e,\u09AC\u09BE\u0982\u09B2\u09BE:e,"xn--90ae":e,\u0431\u0433:e,"xn--mgbcpq6gpa1a":e,\u0627\u0644\u0628\u062D\u0631\u064A\u0646:e,"xn--90ais":e,\u0431\u0435\u043B:e,"xn--fiqs8s":e,\u4E2D\u56FD:e,"xn--fiqz9s":e,\u4E2D\u570B:e,"xn--lgbbat1ad8j":e,\u0627\u0644\u062C\u0632\u0627\u0626\u0631:e,"xn--wgbh1c":e,\u0645\u0635\u0631:e,"xn--e1a4c":e,\u0435\u044E:e,"xn--qxa6a":e,\u03B5\u03C5:e,"xn--mgbah1a3hjkrd":e,\u0645\u0648\u0631\u064A\u062A\u0627\u0646\u064A\u0627:e,"xn--node":e,\u10D2\u10D4:e,"xn--qxam":e,\u03B5\u03BB:e,"xn--j6w193g":[1,{"xn--gmqw5a":e,"xn--55qx5d":e,"xn--mxtq1m":e,"xn--wcvs22d":e,"xn--uc0atv":e,"xn--od0alg":e}],\u9999\u6E2F:[1,{\u500B\u4EBA:e,\u516C\u53F8:e,\u653F\u5E9C:e,\u6559\u80B2:e,\u7D44\u7E54:e,\u7DB2\u7D61:e}],"xn--2scrj9c":e,\u0CAD\u0CBE\u0CB0\u0CA4:e,"xn--3hcrj9c":e,\u0B2D\u0B3E\u0B30\u0B24:e,"xn--45br5cyl":e,\u09AD\u09BE\u09F0\u09A4:e,"xn--h2breg3eve":e,\u092D\u093E\u0930\u0924\u092E\u094D:e,"xn--h2brj9c8c":e,\u092D\u093E\u0930\u094B\u0924:e,"xn--mgbgu82a":e,\u0680\u0627\u0631\u062A:e,"xn--rvc1e0am3e":e,\u0D2D\u0D3E\u0D30\u0D24\u0D02:e,"xn--h2brj9c":e,\u092D\u093E\u0930\u0924:e,"xn--mgbbh1a":e,\u0628\u0627\u0631\u062A:e,"xn--mgbbh1a71e":e,\u0628\u06BE\u0627\u0631\u062A:e,"xn--fpcrj9c3d":e,\u0C2D\u0C3E\u0C30\u0C24\u0C4D:e,"xn--gecrj9c":e,\u0AAD\u0ABE\u0AB0\u0AA4:e,"xn--s9brj9c":e,\u0A2D\u0A3E\u0A30\u0A24:e,"xn--45brj9c":e,\u09AD\u09BE\u09B0\u09A4:e,"xn--xkc2dl3a5ee0h":e,\u0B87\u0BA8\u0BCD\u0BA4\u0BBF\u0BAF\u0BBE:e,"xn--mgba3a4f16a":e,\u0627\u06CC\u0631\u0627\u0646:e,"xn--mgba3a4fra":e,\u0627\u064A\u0631\u0627\u0646:e,"xn--mgbtx2b":e,\u0639\u0631\u0627\u0642:e,"xn--mgbayh7gpa":e,\u0627\u0644\u0627\u0631\u062F\u0646:e,"xn--3e0b707e":e,\uD55C\uAD6D:e,"xn--80ao21a":e,\u049B\u0430\u0437:e,"xn--q7ce6a":e,\u0EA5\u0EB2\u0EA7:e,"xn--fzc2c9e2c":e,\u0DBD\u0D82\u0D9A\u0DCF:e,"xn--xkc2al3hye2a":e,\u0B87\u0BB2\u0B99\u0BCD\u0B95\u0BC8:e,"xn--mgbc0a9azcg":e,\u0627\u0644\u0645\u063A\u0631\u0628:e,"xn--d1alf":e,\u043C\u043A\u0434:e,"xn--l1acc":e,\u043C\u043E\u043D:e,"xn--mix891f":e,\u6FB3\u9580:e,"xn--mix082f":e,\u6FB3\u95E8:e,"xn--mgbx4cd0ab":e,\u0645\u0644\u064A\u0633\u064A\u0627:e,"xn--mgb9awbf":e,\u0639\u0645\u0627\u0646:e,"xn--mgbai9azgqp6j":e,\u067E\u0627\u06A9\u0633\u062A\u0627\u0646:e,"xn--mgbai9a5eva00b":e,\u067E\u0627\u0643\u0633\u062A\u0627\u0646:e,"xn--ygbi2ammx":e,\u0641\u0644\u0633\u0637\u064A\u0646:e,"xn--90a3ac":[1,{"xn--80au":e,"xn--90azh":e,"xn--d1at":e,"xn--c1avg":e,"xn--o1ac":e,"xn--o1ach":e}],\u0441\u0440\u0431:[1,{\u0430\u043A:e,\u043E\u0431\u0440:e,\u043E\u0434:e,\u043E\u0440\u0433:e,\u043F\u0440:e,\u0443\u043F\u0440:e}],"xn--p1ai":e,\u0440\u0444:e,"xn--wgbl6a":e,\u0642\u0637\u0631:e,"xn--mgberp4a5d4ar":e,\u0627\u0644\u0633\u0639\u0648\u062F\u064A\u0629:e,"xn--mgberp4a5d4a87g":e,\u0627\u0644\u0633\u0639\u0648\u062F\u06CC\u0629:e,"xn--mgbqly7c0a67fbc":e,\u0627\u0644\u0633\u0639\u0648\u062F\u06CC\u06C3:e,"xn--mgbqly7cvafr":e,\u0627\u0644\u0633\u0639\u0648\u062F\u064A\u0647:e,"xn--mgbpl2fh":e,\u0633\u0648\u062F\u0627\u0646:e,"xn--yfro4i67o":e,\u65B0\u52A0\u5761:e,"xn--clchc0ea0b2g2a9gcd":e,\u0B9A\u0BBF\u0B99\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0BC2\u0BB0\u0BCD:e,"xn--ogbpf8fl":e,\u0633\u0648\u0631\u064A\u0629:e,"xn--mgbtf8fl":e,\u0633\u0648\u0631\u064A\u0627:e,"xn--o3cw4h":[1,{"xn--o3cyx2a":e,"xn--12co0c3b4eva":e,"xn--m3ch0j3a":e,"xn--h3cuzk1di":e,"xn--12c1fe0br":e,"xn--12cfi8ixb8l":e}],\u0E44\u0E17\u0E22:[1,{\u0E17\u0E2B\u0E32\u0E23:e,\u0E18\u0E38\u0E23\u0E01\u0E34\u0E08:e,\u0E40\u0E19\u0E47\u0E15:e,\u0E23\u0E31\u0E10\u0E1A\u0E32\u0E25:e,\u0E28\u0E36\u0E01\u0E29\u0E32:e,\u0E2D\u0E07\u0E04\u0E4C\u0E01\u0E23:e}],"xn--pgbs0dh":e,\u062A\u0648\u0646\u0633:e,"xn--kpry57d":e,\u53F0\u7063:e,"xn--kprw13d":e,\u53F0\u6E7E:e,"xn--nnx388a":e,\u81FA\u7063:e,"xn--j1amh":e,\u0443\u043A\u0440:e,"xn--mgb2ddes":e,\u0627\u0644\u064A\u0645\u0646:e,xxx:e,ye:a,za:[0,{ac:e,agric:e,alt:e,co:e,edu:e,gov:e,grondar:e,law:e,mil:e,net:e,ngo:e,nic:e,nis:e,nom:e,org:e,school:e,tm:e,web:e}],zm:[1,{ac:e,biz:e,co:e,com:e,edu:e,gov:e,info:e,mil:e,net:e,org:e,sch:e}],zw:[1,{ac:e,co:e,gov:e,mil:e,org:e}],aaa:e,aarp:e,abb:e,abbott:e,abbvie:e,abc:e,able:e,abogado:e,abudhabi:e,academy:[1,{official:t}],accenture:e,accountant:e,accountants:e,aco:e,actor:e,ads:e,adult:e,aeg:e,aetna:e,afl:e,africa:e,agakhan:e,agency:e,aig:e,airbus:e,airforce:e,airtel:e,akdn:e,alibaba:e,alipay:e,allfinanz:e,allstate:e,ally:e,alsace:e,alstom:e,amazon:e,americanexpress:e,americanfamily:e,amex:e,amfam:e,amica:e,amsterdam:e,analytics:e,android:e,anquan:e,anz:e,aol:e,apartments:e,app:[1,{adaptable:t,aiven:t,claude:t,beget:n,brave:i,clerk:t,clerkstage:t,cloudflare:t,wnext:t,csb:[2,{preview:t}],convex:t,corespeed:t,deta:t,ondigitalocean:t,easypanel:t,encr:[2,{frontend:t}],evervault:r,expo:[2,{on:t,staging:[2,{on:t}]}],edgecompute:t,"on-fleek":t,flutterflow:t,sprites:t,e2b:t,framer:t,gadget:t,github:t,hosted:n,run:[0,{"*":t,mtls:n}],web:t,hackclub:t,hasura:t,onhercules:t,botdash:t,shiptoday:t,leapcell:t,loginline:t,lovable:t,luyani:t,magicpatterns:t,medusajs:t,messerli:t,miren:t,mocha:t,netlify:t,ngrok:t,"ngrok-free":t,developer:n,noop:t,northflank:n,pplx:t,upsun:n,railway:[0,{up:t}],replit:s,nyat:t,snowflake:[0,{"*":t,privatelink:n}],streamlit:t,spawnbase:t,telebit:t,typedream:t,vercel:t,wal:t,wasmer:t,bookonline:t,windsurf:t,base44:t,zeabur:t,zerops:n}],apple:[1,{int:[2,{cloud:[0,{"*":t,r:[0,{"*":t,"ap-north-1":n,"ap-south-1":n,"ap-south-2":n,"eu-central-1":n,"eu-north-1":n,"us-central-1":n,"us-central-2":n,"us-east-1":n,"us-east-2":n,"us-west-1":n,"us-west-2":n,"us-west-3":n}]}]}]}],aquarelle:e,arab:e,aramco:e,archi:e,army:e,art:e,arte:e,asda:e,associates:e,athleta:e,attorney:e,auction:e,audi:e,audible:e,audio:e,auspost:e,author:e,auto:e,autos:e,aws:[1,{on:[0,{"af-south-1":l,"ap-east-1":l,"ap-northeast-1":l,"ap-northeast-2":l,"ap-northeast-3":l,"ap-south-1":l,"ap-south-2":u,"ap-southeast-1":l,"ap-southeast-2":l,"ap-southeast-3":l,"ap-southeast-4":u,"ap-southeast-5":u,"ca-central-1":l,"ca-west-1":u,"eu-central-1":l,"eu-central-2":u,"eu-north-1":l,"eu-south-1":l,"eu-south-2":u,"eu-west-1":l,"eu-west-2":l,"eu-west-3":l,"il-central-1":u,"me-central-1":u,"me-south-1":l,"sa-east-1":l,"us-east-1":l,"us-east-2":l,"us-west-1":l,"us-west-2":l,"ap-southeast-7":d,"mx-central-1":d,"us-gov-east-1":m,"us-gov-west-1":m}],sagemaker:[0,{"ap-northeast-1":f,"ap-northeast-2":f,"ap-south-1":f,"ap-southeast-1":f,"ap-southeast-2":f,"ca-central-1":x,"eu-central-1":f,"eu-west-1":f,"eu-west-2":f,"us-east-1":x,"us-east-2":x,"us-west-2":x,"af-south-1":p,"ap-east-1":p,"ap-northeast-3":p,"ap-south-2":E,"ap-southeast-3":p,"ap-southeast-4":E,"ca-west-1":[0,{notebook:t,"notebook-fips":t}],"eu-central-2":p,"eu-north-1":p,"eu-south-1":p,"eu-south-2":p,"eu-west-3":p,"il-central-1":p,"me-central-1":p,"me-south-1":p,"sa-east-1":p,"us-gov-east-1":S,"us-gov-west-1":S,"us-west-1":[0,{notebook:t,"notebook-fips":t,studio:t}],experiments:n}],repost:[0,{private:n}]}],axa:e,azure:e,baby:e,baidu:e,banamex:e,band:e,bank:e,bar:e,barcelona:e,barclaycard:e,barclays:e,barefoot:e,bargains:e,baseball:e,basketball:[1,{aus:t,nz:t}],bauhaus:e,bayern:e,bbc:e,bbt:e,bbva:e,bcg:e,bcn:e,beats:e,beauty:e,beer:e,berlin:e,best:e,bestbuy:e,bet:e,bharti:e,bible:e,bid:e,bike:e,bing:e,bingo:e,bio:e,black:e,blackfriday:e,blockbuster:e,blog:e,bloomberg:e,blue:e,bms:e,bmw:e,bnpparibas:e,boats:e,boehringer:e,bofa:e,bom:e,bond:e,boo:e,book:e,booking:e,bosch:e,bostik:e,boston:e,bot:e,boutique:e,box:e,bradesco:e,bridgestone:e,broadway:e,broker:e,brother:e,brussels:e,build:[1,{shiptoday:t,v0:t,windsurf:t}],builders:[1,{cloudsite:t}],business:P,buy:e,buzz:e,bzh:e,cab:e,cafe:e,cal:e,call:e,calvinklein:e,cam:e,camera:e,camp:[1,{emf:[0,{at:t}]}],canon:e,capetown:e,capital:e,capitalone:e,car:e,caravan:e,cards:e,care:e,career:e,careers:e,cars:e,casa:[1,{nabu:[0,{ui:t}]}],case:[1,{sav:t}],cash:e,casino:e,catering:e,catholic:e,cba:e,cbn:e,cbre:e,center:e,ceo:e,cern:e,cfa:e,cfd:e,chanel:e,channel:e,charity:e,chase:e,chat:e,cheap:e,chintai:e,christmas:e,chrome:e,church:e,cipriani:e,circle:e,cisco:e,citadel:e,citi:e,citic:e,city:e,claims:e,cleaning:e,click:e,clinic:e,clinique:e,clothing:e,cloud:[1,{antagonist:t,begetcdn:n,convex:T,elementor:t,emergent:t,encoway:[0,{eu:t}],statics:n,ravendb:t,axarnet:[0,{"es-1":t}],diadem:t,jelastic:[0,{vip:t}],jele:t,"jenv-aruba":[0,{aruba:[0,{eur:[0,{it1:t}]}],it1:t}],keliweb:[2,{cs:t}],oxa:[2,{tn:t,uk:t}],primetel:[2,{uk:t}],reclaim:[0,{ca:t,uk:t,us:t}],trendhosting:[0,{ch:t,de:t}],jote:t,jotelulu:t,k2:[0,{elastic:t,"ru-msk":_,"ru-spb":_,s3:t,website:t}],kuleuven:t,laravel:t,linkyard:t,magentosite:n,matlab:t,observablehq:t,perspecta:t,vapor:t,"on-rancher":n,scw:[0,{baremetal:[0,{"fr-par-1":t,"fr-par-2":t,"nl-ams-1":t}],"fr-par":[0,{cockpit:t,ddl:t,dtwh:t,fnc:[2,{functions:t}],ifr:t,k8s:C,kafk:t,mgdb:t,rdb:t,s3:t,"s3-website":t,scbl:t,whm:t}],instances:[0,{priv:t,pub:t}],k8s:t,"nl-ams":[0,{cockpit:t,ddl:t,dtwh:t,ifr:t,k8s:C,kafk:t,mgdb:t,rdb:t,s3:t,"s3-website":t,scbl:t,whm:t}],"pl-waw":[0,{cockpit:t,ddl:t,dtwh:t,ifr:t,k8s:C,kafk:t,mgdb:t,rdb:t,s3:t,"s3-website":t,scbl:t}],scalebook:t,smartlabeling:t}],servebolt:t,onstackit:[0,{runs:t}],trafficplex:t,"unison-services":t,urown:t,voorloper:t,zap:t}],club:[1,{cloudns:t,jele:t,barsy:t}],clubmed:e,coach:e,codes:[1,{owo:n}],coffee:e,college:e,cologne:e,commbank:e,community:[1,{nog:t,ravendb:t,myforum:t}],company:[1,{mybox:t}],compare:e,computer:e,comsec:e,condos:e,construction:e,consulting:e,contact:e,contractors:e,cooking:e,cool:[1,{elementor:t,de:t}],corsica:e,country:e,coupon:e,coupons:e,courses:e,cpa:e,credit:e,creditcard:e,creditunion:e,cricket:e,crown:e,crs:e,cruise:e,cruises:e,cuisinella:e,cymru:e,cyou:e,dad:e,dance:e,data:e,date:e,dating:e,datsun:e,day:e,dclk:e,dds:e,deal:e,dealer:e,deals:e,degree:e,delivery:e,dell:e,deloitte:e,delta:e,democrat:e,dental:e,dentist:e,desi:e,design:[1,{graphic:t,bss:t}],dev:[1,{myaddr:t,panel:t,bearblog:t,brave:i,lcl:n,lclstage:n,stg:n,stgstage:n,pages:t,r2:t,workers:t,deno:t,"deno-staging":t,deta:t,lp:[2,{api:t,objects:t}],evervault:r,payload:t,fly:t,githubpreview:t,gateway:n,grebedoc:t,botdash:t,inbrowser:n,"is-a-good":t,iserv:t,leapcell:t,runcontainers:t,localcert:[0,{user:n}],loginline:t,barsy:t,mediatech:t,"mocha-sandbox":t,modx:t,ngrok:t,"ngrok-free":t,"is-a-fullstack":t,"is-cool":t,"is-not-a":t,localplayer:t,xmit:t,"platter-app":t,replit:[2,{archer:t,bones:t,canary:t,global:t,hacker:t,id:t,janeway:t,kim:t,kira:t,kirk:t,odo:t,paris:t,picard:t,pike:t,prerelease:t,reed:t,riker:t,sisko:t,spock:t,staging:t,sulu:t,tarpit:t,teams:t,tucker:t,wesley:t,worf:t}],crm:[0,{aa:n,ab:n,ac:n,ad:n,ae:n,af:n,ci:n,d:n,pa:n,pb:n,pc:n,pd:n,pe:n,pf:n,w:n,wa:n,wb:n,wc:n,wd:n,we:n,wf:n}],erp:Zt,vercel:t,vivenushop:t,webhare:n,hrsn:t,"is-a":t}],dhl:e,diamonds:e,diet:e,digital:e,direct:[1,{libp2p:t}],directory:e,discount:e,discover:e,dish:e,diy:[1,{discourse:t,imagine:t}],dnp:e,docs:e,doctor:e,dog:e,domains:e,dot:e,download:e,drive:e,dtv:e,dubai:e,dupont:e,durban:e,dvag:e,dvr:e,earth:e,eat:e,eco:e,edeka:e,education:P,email:[1,{crisp:[0,{on:t}],intouch:t,tawk:en,tawkto:en}],emerck:e,energy:e,engineer:e,engineering:e,enterprises:e,epson:e,equipment:e,ericsson:e,erni:e,esq:e,estate:[1,{compute:n}],eurovision:e,eus:[1,{party:tn}],events:[1,{koobin:t,co:t}],exchange:e,expert:e,exposed:e,express:e,extraspace:e,fage:e,fail:e,fairwinds:e,faith:e,family:e,fan:e,fans:e,farm:[1,{storj:t}],farmers:e,fashion:e,fast:e,fedex:e,feedback:e,ferrari:e,ferrero:e,fidelity:e,fido:e,film:e,final:e,finance:e,financial:P,fire:e,firestone:e,firmdale:e,fish:e,fishing:e,fit:e,fitness:e,flickr:e,flights:e,flir:e,florist:e,flowers:e,fly:e,foo:e,food:e,football:e,ford:e,forex:e,forsale:e,forum:e,foundation:e,fox:e,free:e,fresenius:e,frl:e,frogans:e,frontier:e,ftr:e,fujitsu:e,fun:[1,{ms:t,vicp:t,yicp:t,zicp:t}],fund:e,furniture:e,futbol:e,fyi:e,gal:e,gallery:e,gallo:e,gallup:e,game:e,games:[1,{pley:t,sheezy:t}],gap:e,garden:e,gay:[1,{pages:t}],gbiz:e,gdn:[1,{cnpy:t}],gea:e,gent:e,genting:e,george:e,ggee:e,gift:e,gifts:e,gives:e,giving:e,glass:e,gle:e,global:[1,{appwrite:t}],globo:e,gmail:e,gmbh:e,gmo:e,gmx:e,godaddy:e,gold:e,goldpoint:e,golf:e,goodyear:e,goog:[1,{cloud:t,translate:t,usercontent:n}],google:e,gop:e,got:e,grainger:e,graphics:e,gratis:e,green:e,gripe:e,grocery:e,group:[1,{discourse:t}],gucci:e,guge:e,guide:e,guitars:e,guru:e,hair:e,hamburg:e,hangout:e,haus:e,hbo:e,hdfc:e,hdfcbank:e,health:[1,{hra:t}],healthcare:e,help:e,helsinki:e,here:e,hermes:e,hiphop:e,hisamitsu:e,hitachi:e,hiv:e,hkt:e,hockey:e,holdings:e,holiday:e,homedepot:e,homegoods:e,homes:e,homesense:e,honda:e,horse:e,hospital:e,host:[1,{cloudaccess:t,freesite:t,easypanel:t,emergent:t,fastvps:t,myfast:t,gadget:t,tempurl:t,wpmudev:t,iserv:t,jele:t,mircloud:t,bolt:t,wp2:t,half:t}],hosting:[1,{opencraft:t}],hot:e,hotel:e,hotels:e,hotmail:e,house:e,how:e,hsbc:e,hughes:e,hyatt:e,hyundai:e,ibm:e,icbc:e,ice:e,icu:e,ieee:e,ifm:e,ikano:e,imamat:e,imdb:e,immo:e,immobilien:e,inc:e,industries:e,infiniti:e,ing:e,ink:e,institute:e,insurance:e,insure:e,international:e,intuit:e,investments:e,ipiranga:e,irish:e,ismaili:e,ist:e,istanbul:e,itau:e,itv:e,jaguar:e,java:e,jcb:e,jeep:e,jetzt:e,jewelry:e,jio:e,jll:e,jmp:e,jnj:e,joburg:e,jot:e,joy:e,jpmorgan:e,jprs:e,juegos:e,juniper:e,kaufen:e,kddi:e,kerryhotels:e,kerryproperties:e,kfh:e,kia:e,kids:e,kim:e,kindle:e,kitchen:e,kiwi:e,koeln:e,komatsu:e,kosher:e,kpmg:e,kpn:e,krd:[1,{co:t,edu:t}],kred:e,kuokgroup:e,kyoto:e,lacaixa:e,lamborghini:e,lamer:e,land:e,landrover:e,lanxess:e,lasalle:e,lat:e,latino:e,latrobe:e,law:e,lawyer:e,lds:e,lease:e,leclerc:e,lefrak:e,legal:e,lego:e,lexus:e,lgbt:e,lidl:e,life:e,lifeinsurance:e,lifestyle:e,lighting:e,like:e,lilly:e,limited:e,limo:e,lincoln:e,link:[1,{myfritz:t,cyon:t,joinmc:t,dweb:n,inbrowser:n,keenetic:t,nftstorage:Je,mypep:t,storacha:Je,w3s:Je}],live:[1,{aem:t,hlx:t,ewp:n}],living:e,llc:e,llp:e,loan:e,loans:e,locker:e,locus:e,lol:[1,{omg:t}],london:e,lotte:e,lotto:e,love:e,lpl:e,lplfinancial:e,ltd:e,ltda:e,lundbeck:e,luxe:e,luxury:e,madrid:e,maif:e,maison:e,makeup:e,man:e,management:e,mango:e,map:e,market:e,marketing:e,markets:e,marriott:e,marshalls:e,mattel:e,mba:e,mckinsey:e,med:e,media:ve,meet:e,melbourne:e,meme:e,memorial:e,men:e,menu:[1,{barsy:t,barsyonline:t}],merck:e,merckmsd:e,miami:e,microsoft:e,mini:e,mint:e,mit:e,mitsubishi:e,mlb:e,mls:e,mma:e,mobile:e,moda:e,moe:e,moi:e,mom:e,monash:e,money:e,monster:e,mormon:e,mortgage:e,moscow:e,moto:e,motorcycles:e,mov:e,movie:e,msd:e,mtn:e,mtr:e,music:e,nab:e,nagoya:e,navy:e,nba:e,nec:e,netbank:e,netflix:e,network:[1,{aem:t,alces:n,appwrite:t,co:t,arvo:t,azimuth:t,tlon:t}],neustar:e,new:e,news:[1,{noticeable:t}],next:e,nextdirect:e,nexus:e,nfl:e,ngo:e,nhk:e,nico:e,nike:e,nikon:e,ninja:e,nissan:e,nissay:e,nokia:e,norton:e,now:e,nowruz:e,nowtv:e,nra:e,nrw:e,ntt:e,nyc:e,obi:e,observer:e,office:e,okinawa:e,olayan:e,olayangroup:e,ollo:e,omega:e,one:[1,{kin:n,service:t,website:t}],ong:e,onl:e,online:[1,{eero:t,"eero-stage":t,websitebuilder:t,leapcell:t,barsy:t}],ooo:e,open:e,oracle:e,orange:[1,{tech:t}],organic:e,origins:e,osaka:e,otsuka:e,ott:e,ovh:[1,{nerdpol:t}],page:[1,{aem:t,hlx:t,codeberg:t,deuxfleurs:t,mybox:t,heyflow:t,prvcy:t,rocky:t,statichost:t,pdns:t,plesk:t}],panasonic:e,paris:e,pars:e,partners:e,parts:e,party:e,pay:e,pccw:e,pet:e,pfizer:e,pharmacy:e,phd:e,philips:e,phone:e,photo:e,photography:e,photos:ve,physio:e,pics:e,pictet:e,pictures:[1,{1337:t}],pid:e,pin:e,ping:e,pink:e,pioneer:e,pizza:[1,{ngrok:t}],place:P,play:e,playstation:e,plumbing:e,plus:[1,{playit:[2,{at:n,with:t}]}],pnc:e,pohl:e,poker:e,politie:e,porn:e,praxi:e,press:e,prime:e,prod:e,productions:e,prof:e,progressive:e,promo:e,properties:e,property:e,protection:e,pru:e,prudential:e,pub:[1,{id:n,kin:n,barsy:t}],pwc:e,qpon:e,quebec:e,quest:e,racing:e,radio:e,read:e,realestate:e,realtor:e,realty:e,recipes:e,red:e,redumbrella:e,rehab:e,reise:e,reisen:e,reit:e,reliance:e,ren:e,rent:e,rentals:e,repair:e,report:e,republican:e,rest:e,restaurant:e,review:e,reviews:[1,{aem:t}],rexroth:e,rich:e,richardli:e,ricoh:e,ril:e,rio:e,rip:[1,{clan:t}],rocks:[1,{myddns:t,stackit:t,"lima-city":t,webspace:t}],rodeo:e,rogers:e,room:e,rsvp:e,rugby:e,ruhr:e,run:[1,{appwrite:n,canva:t,development:t,ravendb:t,liara:[2,{iran:t}],lovable:t,needle:t,build:n,code:n,database:n,migration:n,onporter:t,repl:t,stackit:t,val:Zt,vercel:t,wix:t}],rwe:e,ryukyu:e,saarland:e,safe:e,safety:e,sakura:e,sale:e,salon:e,samsclub:e,samsung:e,sandvik:e,sandvikcoromant:e,sanofi:e,sap:e,sarl:e,sas:e,save:e,saxo:e,sbi:e,sbs:e,scb:e,schaeffler:e,schmidt:e,scholarships:e,school:e,schule:e,schwarz:e,science:e,scot:[1,{co:t,me:t,org:t,gov:[2,{service:t}]}],search:e,seat:e,secure:e,security:e,seek:e,select:e,sener:e,services:[1,{loginline:t}],seven:e,sew:e,sex:e,sexy:e,sfr:e,shangrila:e,sharp:e,shell:e,shia:e,shiksha:e,shoes:e,shop:[1,{base:t,hoplix:t,barsy:t,barsyonline:t,shopware:t}],shopping:e,shouji:e,show:[1,{ms:t}],silk:e,sina:e,singles:e,site:[1,{square:t,canva:B,cloudera:n,convex:T,cyon:t,piebox:t,caffeine:t,fastvps:t,figma:t,"figma-gov":t,preview:t,heyflow:t,jele:t,jouwweb:t,loginline:t,barsy:t,co:t,notion:t,omniwe:t,opensocial:t,madethis:t,support:t,platformsh:n,tst:n,byen:t,sol:t,srht:t,novecore:t,cpanel:t,wpsquared:t,sourcecraft:t}],ski:e,skin:e,sky:e,skype:e,sling:e,smart:e,smile:e,sncf:e,soccer:e,social:e,softbank:e,software:e,sohu:e,solar:e,solutions:e,song:e,sony:e,soy:e,spa:e,space:[1,{deployagent:t,myfast:t,heiyu:t,hf:[2,{static:t}],"app-ionos":t,project:t,uber:t,xs4all:t}],sport:e,spot:e,srl:e,stada:e,staples:e,star:e,statebank:e,statefarm:e,stc:e,stcgroup:e,stockholm:e,storage:e,store:[1,{barsy:t,sellfy:t,shopware:t,storebase:t}],stream:e,studio:e,study:e,style:e,sucks:e,supplies:e,supply:e,support:[1,{barsy:t}],surf:e,surgery:e,suzuki:e,swatch:e,swiss:e,sydney:e,systems:[1,{knightpoint:t,miren:t}],tab:e,taipei:e,talk:e,taobao:e,target:e,tatamotors:e,tatar:e,tattoo:e,tax:e,taxi:e,tci:e,tdk:e,team:[1,{discourse:t,jelastic:t}],tech:[1,{cleverapps:t}],technology:P,temasek:e,tennis:e,teva:e,thd:e,theater:e,theatre:e,tiaa:e,tickets:e,tienda:e,tips:e,tires:e,tirol:e,tjmaxx:e,tjx:e,tkmaxx:e,tmall:e,today:[1,{prequalifyme:t}],tokyo:e,tools:[1,{addr:Jt,myaddr:t}],top:[1,{ntdll:t,wadl:n}],toray:e,toshiba:e,total:e,tours:e,town:e,toyota:e,toys:e,trade:e,trading:e,training:e,travel:e,travelers:e,travelersinsurance:e,trust:e,trv:e,tube:e,tui:e,tunes:e,tushu:e,tvs:e,ubank:e,ubs:e,unicom:e,university:e,uno:e,uol:e,ups:e,vacations:e,vana:e,vanguard:e,vegas:e,ventures:e,verisign:e,versicherung:e,vet:e,viajes:e,video:e,vig:e,viking:e,villas:e,vin:e,vip:[1,{hidns:t}],virgin:e,visa:e,vision:e,viva:e,vivo:e,vlaanderen:e,vodka:e,volvo:e,vote:e,voting:e,voto:e,voyage:e,wales:e,walmart:e,walter:e,wang:e,wanggou:e,watch:e,watches:e,weather:e,weatherchannel:e,webcam:e,weber:e,website:ve,wed:e,wedding:e,weibo:e,weir:e,whoswho:e,wien:e,wiki:ve,williamhill:e,win:e,windows:e,wine:e,winners:e,wme:e,woodside:e,work:[1,{"imagine-proxy":t}],works:e,world:e,wow:e,wtc:e,wtf:e,xbox:e,xerox:e,xihuan:e,xin:e,"xn--11b4c3d":e,\u0915\u0949\u092E:e,"xn--1ck2e1b":e,\u30BB\u30FC\u30EB:e,"xn--1qqw23a":e,\u4F5B\u5C71:e,"xn--30rr7y":e,\u6148\u5584:e,"xn--3bst00m":e,\u96C6\u56E2:e,"xn--3ds443g":e,\u5728\u7EBF:e,"xn--3pxu8k":e,\u70B9\u770B:e,"xn--42c2d9a":e,\u0E04\u0E2D\u0E21:e,"xn--45q11c":e,\u516B\u5366:e,"xn--4gbrim":e,\u0645\u0648\u0642\u0639:e,"xn--55qw42g":e,\u516C\u76CA:e,"xn--55qx5d":e,\u516C\u53F8:e,"xn--5su34j936bgsg":e,\u9999\u683C\u91CC\u62C9:e,"xn--5tzm5g":e,\u7F51\u7AD9:e,"xn--6frz82g":e,\u79FB\u52A8:e,"xn--6qq986b3xl":e,\u6211\u7231\u4F60:e,"xn--80adxhks":e,\u043C\u043E\u0441\u043A\u0432\u0430:e,"xn--80aqecdr1a":e,\u043A\u0430\u0442\u043E\u043B\u0438\u043A:e,"xn--80asehdb":e,\u043E\u043D\u043B\u0430\u0439\u043D:e,"xn--80aswg":e,\u0441\u0430\u0439\u0442:e,"xn--8y0a063a":e,\u8054\u901A:e,"xn--9dbq2a":e,\u05E7\u05D5\u05DD:e,"xn--9et52u":e,\u65F6\u5C1A:e,"xn--9krt00a":e,\u5FAE\u535A:e,"xn--b4w605ferd":e,\u6DE1\u9A6C\u9521:e,"xn--bck1b9a5dre4c":e,\u30D5\u30A1\u30C3\u30B7\u30E7\u30F3:e,"xn--c1avg":e,\u043E\u0440\u0433:e,"xn--c2br7g":e,\u0928\u0947\u091F:e,"xn--cck2b3b":e,\u30B9\u30C8\u30A2:e,"xn--cckwcxetd":e,\u30A2\u30DE\u30BE\u30F3:e,"xn--cg4bki":e,\uC0BC\uC131:e,"xn--czr694b":e,\u5546\u6807:e,"xn--czrs0t":e,\u5546\u5E97:e,"xn--czru2d":e,\u5546\u57CE:e,"xn--d1acj3b":e,\u0434\u0435\u0442\u0438:e,"xn--eckvdtc9d":e,\u30DD\u30A4\u30F3\u30C8:e,"xn--efvy88h":e,\u65B0\u95FB:e,"xn--fct429k":e,\u5BB6\u96FB:e,"xn--fhbei":e,\u0643\u0648\u0645:e,"xn--fiq228c5hs":e,\u4E2D\u6587\u7F51:e,"xn--fiq64b":e,\u4E2D\u4FE1:e,"xn--fjq720a":e,\u5A31\u4E50:e,"xn--flw351e":e,\u8C37\u6B4C:e,"xn--fzys8d69uvgm":e,\u96FB\u8A0A\u76C8\u79D1:e,"xn--g2xx48c":e,\u8D2D\u7269:e,"xn--gckr3f0f":e,\u30AF\u30E9\u30A6\u30C9:e,"xn--gk3at1e":e,\u901A\u8CA9:e,"xn--hxt814e":e,\u7F51\u5E97:e,"xn--i1b6b1a6a2e":e,\u0938\u0902\u0917\u0920\u0928:e,"xn--imr513n":e,\u9910\u5385:e,"xn--io0a7i":e,\u7F51\u7EDC:e,"xn--j1aef":e,\u043A\u043E\u043C:e,"xn--jlq480n2rg":e,\u4E9A\u9A6C\u900A:e,"xn--jvr189m":e,\u98DF\u54C1:e,"xn--kcrx77d1x4a":e,\u98DE\u5229\u6D66:e,"xn--kput3i":e,\u624B\u673A:e,"xn--mgba3a3ejt":e,\u0627\u0631\u0627\u0645\u0643\u0648:e,"xn--mgba7c0bbn0a":e,\u0627\u0644\u0639\u0644\u064A\u0627\u0646:e,"xn--mgbab2bd":e,\u0628\u0627\u0632\u0627\u0631:e,"xn--mgbca7dzdo":e,\u0627\u0628\u0648\u0638\u0628\u064A:e,"xn--mgbi4ecexp":e,\u0643\u0627\u062B\u0648\u0644\u064A\u0643:e,"xn--mgbt3dhd":e,\u0647\u0645\u0631\u0627\u0647:e,"xn--mk1bu44c":e,\uB2F7\uCEF4:e,"xn--mxtq1m":e,\u653F\u5E9C:e,"xn--ngbc5azd":e,\u0634\u0628\u0643\u0629:e,"xn--ngbe9e0a":e,\u0628\u064A\u062A\u0643:e,"xn--ngbrx":e,\u0639\u0631\u0628:e,"xn--nqv7f":e,\u673A\u6784:e,"xn--nqv7fs00ema":e,\u7EC4\u7EC7\u673A\u6784:e,"xn--nyqy26a":e,\u5065\u5EB7:e,"xn--otu796d":e,\u62DB\u8058:e,"xn--p1acf":[1,{"xn--90amc":t,"xn--j1aef":t,"xn--j1ael8b":t,"xn--h1ahn":t,"xn--j1adp":t,"xn--c1avg":t,"xn--80aaa0cvac":t,"xn--h1aliz":t,"xn--90a1af":t,"xn--41a":t}],\u0440\u0443\u0441:[1,{\u0431\u0438\u0437:t,\u043A\u043E\u043C:t,\u043A\u0440\u044B\u043C:t,\u043C\u0438\u0440:t,\u043C\u0441\u043A:t,\u043E\u0440\u0433:t,\u0441\u0430\u043C\u0430\u0440\u0430:t,\u0441\u043E\u0447\u0438:t,\u0441\u043F\u0431:t,\u044F:t}],"xn--pssy2u":e,\u5927\u62FF:e,"xn--q9jyb4c":e,\u307F\u3093\u306A:e,"xn--qcka1pmc":e,\u30B0\u30FC\u30B0\u30EB:e,"xn--rhqv96g":e,\u4E16\u754C:e,"xn--rovu88b":e,\u66F8\u7C4D:e,"xn--ses554g":e,\u7F51\u5740:e,"xn--t60b56a":e,\uB2F7\uB137:e,"xn--tckwe":e,\u30B3\u30E0:e,"xn--tiq49xqyj":e,\u5929\u4E3B\u6559:e,"xn--unup4y":e,\u6E38\u620F:e,"xn--vermgensberater-ctb":e,verm\u00F6gensberater:e,"xn--vermgensberatung-pwb":e,verm\u00F6gensberatung:e,"xn--vhquv":e,\u4F01\u4E1A:e,"xn--vuq861b":e,\u4FE1\u606F:e,"xn--w4r85el8fhu5dnra":e,\u5609\u91CC\u5927\u9152\u5E97:e,"xn--w4rs40l":e,\u5609\u91CC:e,"xn--xhq521b":e,\u5E7F\u4E1C:e,"xn--zfr164b":e,\u653F\u52A1:e,xyz:[1,{opentunnel:t,caffeine:t,exe:t,botdash:t,telebit:n}],yachts:e,yahoo:e,yamaxun:e,yandex:e,yodobashi:e,yoga:e,yokohama:e,you:e,youtube:e,yun:e,zappos:e,zara:e,zero:e,zip:e,zone:[1,{stackit:t,lima:t,triton:n}],zuerich:e}]})();function co(e,t,o,a){let n=null,i=t;for(;i!==void 0&&((i[0]&a)!==0&&(n={index:o+1,isIcann:(i[0]&1)!==0,isPrivate:(i[0]&2)!==0}),o!==-1);){let r=i[1];i=Object.prototype.hasOwnProperty.call(r,e[o])?r[e[o]]:r["*"],o-=1}return n}function G(e,t,o){var a;if(Sr(e,t,o))return;let n=e.split("."),i=(t.allowPrivateDomains?2:0)|(t.allowIcannDomains?1:0),r=co(n,Er,n.length-1,i);if(r!==null){o.isIcann=r.isIcann,o.isPrivate=r.isPrivate,o.publicSuffix=n.slice(r.index+1).join(".");return}let s=co(n,Cr,n.length-1,i);if(s!==null){o.isIcann=s.isIcann,o.isPrivate=s.isPrivate,o.publicSuffix=n.slice(s.index).join(".");return}o.isIcann=!1,o.isPrivate=!1,o.publicSuffix=(a=n[n.length-1])!==null&&a!==void 0?a:null}var L=uo();function _r(e,t={}){return W(e,5,G,t,uo())}function Rr(e,t={}){return le(L),W(e,0,G,t,L).hostname}function Pr(e,t={}){return le(L),W(e,2,G,t,L).publicSuffix}function Tr(e,t={}){return le(L),W(e,3,G,t,L).domain}function Ar(e,t={}){return le(L),W(e,4,G,t,L).subdomain}function jr(e,t={}){return le(L),W(e,5,G,t,L).domainWithoutSuffix}q.getDomain=Tr;q.getDomainWithoutSuffix=jr;q.getHostname=Rr;q.getPublicSuffix=Pr;q.getSubdomain=Ar;q.parse=_r});import Xs from"node:os";import fa from"node:path";import O from"node:process";import{fileURLToPath as Js}from"node:url";function Ca(e){if(e==="cache"||e==="browser"||e==="credentials")return e;throw new Error(`--login-method must be cache, browser, or credentials (got: ${e})`)}function _a(e){if(e==="en"||e==="ru")return e;throw new Error(`--locale must be en or ru (got: ${e})`)}function xe(e){return e==="ru"?"ru-RU,ru;q=0.9,en;q=0.5":"en-US,en;q=0.9"}function Ra(e){let t;try{t=new URL(e)}catch{return!1}return(t.protocol==="http:"||t.protocol==="https:")&&(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="[::1]"||t.hostname==="::1")}function Ze(e){if(!Ra(e))throw new Error("Only local URLs are supported in this version.")}function Pa(){return process.env.VIBEMOLE_WEB_URL?.trim()||"http://localhost:3000"}function Ta(e){let t;try{t=new URL(e)}catch{throw new Error(`--web-url must be a valid URL (got: ${e})`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`--web-url must use http or https (got: ${e})`);return t.origin}function dn(e,t){let o=Number(t);if(!Number.isInteger(o)||o<=0)throw new Error(`${e} must be a positive integer (got: ${t})`);return o}function mn(e){let t={command:"help",url:null,webUrl:Pa(),webUrlExplicit:!1,locale:"en",runtimeRouteCap:10,runtimePagesPerLevel:2,noRuntime:!1,noLogin:!1,loginRequired:!1,loginMethod:null,loginRefresh:!1,json:!1,noUpload:!1,uploadUrl:null,verbose:!1,security:!1},[o,...a]=e;if(!o||o==="help"||o==="--help"||o==="-h")return t;if(o==="login"||o==="logout"||o==="whoami"||o==="scan")t.command=o,o==="scan"&&(t.security=!0);else throw new Error(`Unknown command: ${o}`);for(let n=0;n<a.length;n+=1){let i=a[n];if(i){if(i==="--web-url"){let r=a[n+1];if(!r)throw new Error("--web-url requires a value");t.webUrl=Ta(r),t.webUrlExplicit=!0,n+=1;continue}if(t.command!=="scan"){if(i.startsWith("--"))throw new Error(`Unknown option: ${i}`);continue}if(i==="--url"){let r=a[n+1];if(!r)throw new Error("--url requires a value");Ze(r),t.url=r,n+=1;continue}if(i==="--locale"){let r=a[n+1];if(!r)throw new Error("--locale requires a value");t.locale=_a(r),n+=1;continue}if(i==="--no-runtime"){t.noRuntime=!0;continue}if(i==="--runtime-route-cap"){let r=a[n+1];if(!r)throw new Error("--runtime-route-cap requires a value");if(t.runtimeRouteCap=dn("--runtime-route-cap",r),t.runtimeRouteCap>15)throw new Error(`--runtime-route-cap must be <= 15 (got: ${r})`);n+=1;continue}if(i==="--runtime-pages-per-level"){let r=a[n+1];if(!r)throw new Error("--runtime-pages-per-level requires a value");t.runtimePagesPerLevel=dn("--runtime-pages-per-level",r),n+=1;continue}if(i==="--no-login"){t.noLogin=!0;continue}if(i==="--login-required"){t.loginRequired=!0;continue}if(i==="--login-method"){let r=a[n+1];if(!r)throw new Error("--login-method requires a value");t.loginMethod=Ca(r),n+=1;continue}if(i==="--login-refresh"){t.loginRefresh=!0;continue}if(i==="--json"){t.json=!0;continue}if(i==="--no-upload"){t.noUpload=!0;continue}if(i==="--upload-url"){let r=a[n+1];if(!r)throw new Error("--upload-url requires a value");Ze(r),t.uploadUrl=r,n+=1;continue}if(i==="--verbose"){t.verbose=!0;continue}if(i==="--no-security"){t.security=!1;continue}if(i==="--security"){t.security=!0;continue}if(i.startsWith("--"))throw new Error(`Unknown option: ${i}`);if(t.url)throw new Error(`Unexpected positional argument: ${i}`);Ze(i),t.url=i}}return t}function Qe(){return["Usage:"," vibemole login [--web-url <url>]"," vibemole whoami [--web-url <url>]"," vibemole logout [--web-url <url>]"," vibemole scan [url] [options]","","Options:"," --web-url <url> VibeMole web app URL (default: VIBEMOLE_WEB_URL || http://localhost:3000)"," --url <url> Local app URL for scan runtime, e.g. http://localhost:3000"," --locale <en|ru> Preferred policy/report locale (default: en)"," --no-runtime Skip browser runtime checks"," --runtime-route-cap <n> Max runtime routes to collect (default: 10, max: 15)"," --runtime-pages-per-level <n> Deprecated compatibility flag (no-op)"," --no-login Do not attempt authenticated runtime checks"," --login-required Require login for protected pages (non-interactive)"," --login-method <m> cache | browser | credentials (with --login-required)"," --login-refresh Recreate cached login state"," --json Print redacted JSON"," --security Collect SecurityMole evidence (default for scan)"," --no-security Skip SecurityMole evidence collection"," --no-upload Skip VibeMole account login and evidence upload"," --upload-url <url> Override evidence upload endpoint"," --verbose Print diagnostic details"].join(`
|
|
3
|
+
`)}import{createHash as Ma}from"node:crypto";import{mkdir as Ia,readFile as Da,writeFile as yn}from"node:fs/promises";import re from"node:path";import{fileURLToPath as Oa}from"node:url";import{spawn as Aa}from"node:child_process";import{accessSync as ja}from"node:fs";import{createRequire as za}from"node:module";import ae from"node:path";function La(e){try{return ja(e),e}catch{return null}}function Ua(e){for(let t of e){let o=La(ae.join(t,"node_modules","playwright","cli.js"));if(o)return o}return null}function pn(e){for(let t of e)try{return za(ae.join(t,"package.json"))("playwright")}catch{}return null}function et(e,t){return[t,ae.join(e,"apps","cli"),ae.join(e,"apps","worker"),ae.join(e,"apps","web")]}async function gn(e){let t=Ua(et(e.repoRoot,e.cwd)),o=t?process.execPath:"npm",n=Aa(o,t?[t,"install","chromium"]:["exec","--yes","playwright@1.58.2","--","install","chromium"],{stdio:"inherit",shell:!1});return await new Promise(r=>n.on("exit",r))===0}import tt from"node:readline/promises";import{stdin as Se,stdout as N}from"node:process";async function ie(e,t=!0){let o=t?" [Y/n] ":" [y/N] ",a=tt.createInterface({input:Se,output:N});try{let n=(await a.question(`${e}${o}`)).trim().toLowerCase();return n?n==="y"||n==="yes":t}finally{a.close()}}async function fn(e,t){N.write(`${e}
|
|
4
|
+
`),t.forEach((a,n)=>N.write(` ${n+1}. ${a}
|
|
5
|
+
`));let o=tt.createInterface({input:Se,output:N});try{let a=Number((await o.question("Choose: ")).trim());return!Number.isInteger(a)||a<1||a>t.length?0:a-1}finally{o.close()}}async function nt(e){let t=tt.createInterface({input:Se,output:N});try{return(await t.question(e)).trim()}finally{t.close()}}async function hn(e){N.write(e);let t=Se,o=t.isRaw;return t.isTTY&&t.setRawMode(!0),await new Promise(a=>{let n="",i=r=>{let s=r.toString("utf8");if(s==="\r"||s===`
|
|
6
|
+
`){t.off("data",i),t.isTTY&&t.setRawMode(o),N.write(`
|
|
7
|
+
`),a(n);return}if(s===""&&process.exit(130),s==="\b"||s==="\x7F"){n=n.slice(0,-1);return}n+=s,N.write("*")};t.on("data",i)})}function Na(e){let t=new URL(e).origin;return Ma("sha256").update(t).digest("hex").slice(0,16)}function kn(e,t){let o=re.join(e,".vibemole","auth"),a=Na(t);return{dir:o,state:re.join(o,`${a}.storage-state.json`),meta:re.join(o,`${a}.meta.json`)}}async function vn(e,t){let o=kn(e,t),a=await Da(o.state,"utf8").catch(()=>null);return a?JSON.parse(a):null}async function wn(e,t,o){let a=kn(e,t);await Ia(a.dir,{recursive:!0}),await yn(a.state,JSON.stringify(o,null,2)),await yn(a.meta,JSON.stringify({origin:new URL(t).origin,savedAt:new Date().toISOString()},null,2))}var $a=re.resolve(re.dirname(Oa(import.meta.url)),"../../..");async function xn(e){return pn(et($a,e))}async function bn(e,t){let o=[],a=[];await vn(e,t)&&(o.push("Use cached login state"),a.push("cache")),o.push("Open browser for login","Enter credentials in terminal"),a.push("browser","credentials");let i=await fn("How should VibeMole authenticate?",o);return a[i]??"browser"}async function Ba(e,t,o,a){if(o==="cache"){if(a)return{authenticated:!1,storageState:void 0,reason:"login refresh requested; cached state not reused"};let n=await vn(e,t);return n?{authenticated:!0,storageState:n,reason:"cached storageState"}:{authenticated:!1,storageState:void 0,reason:"no cached login state"}}return o==="browser"?qa(e,t):Fa(e,t)}async function Sn(e){if(e.noLogin)return{authenticated:!1,storageState:void 0,reason:"login disabled"};let t=e.loginRequired,o=e.loginMethod;if(e.interactive&&!e.loginRequired&&!e.loginMethod){if(!await ie("Does this app require login to scan protected pages?",!1))return{authenticated:!1,storageState:void 0,reason:"login not required"};t=!0,o=await bn(e.root,e.targetUrl)}else if(!e.interactive){if(!t)return{authenticated:!1,storageState:void 0,reason:"login not required (non-interactive default)"};if(!o)throw new Error("Login is required but no --login-method was provided. Use --login-method cache|browser|credentials or omit --login-required to scan unauthenticated.")}if(!t)return{authenticated:!1,storageState:void 0,reason:"login not required"};if(!o)if(e.interactive)o=await bn(e.root,e.targetUrl);else throw new Error("Login is required but no --login-method was provided.");return Ba(e.root,e.targetUrl,o,e.loginRefresh)}async function qa(e,t){let o=await xn(e);if(!o)return{authenticated:!1,storageState:void 0,reason:"playwright package is not available"};let a=await o.chromium.launch({headless:!1});try{let n=await a.newContext();if(await(await n.newPage()).goto(t,{waitUntil:"load",timeout:3e4}).catch(()=>{}),!await ie("Log in in the opened browser, then return here. Save this browser state?",!0))return{authenticated:!1,storageState:void 0,reason:"browser login declined"};let s=await n.storageState();return await wn(e,t,s),{authenticated:!0,storageState:s,reason:"browser login storageState"}}finally{await a.close().catch(()=>{})}}async function Fa(e,t){let o=await xn(e);if(!o)return{authenticated:!1,storageState:void 0,reason:"playwright package is not available"};let a=await nt(`Login URL [${t}]: `)||t,n=await nt("Username/email: "),i=await hn("Password: "),r=await o.chromium.launch({headless:!0});try{let s=await r.newContext(),c=await s.newPage();await c.goto(a,{waitUntil:"load",timeout:3e4});let l=c.locator("input[type='email'], input[name*='email' i], input[name*='user' i], input[type='text']").first(),u=c.locator("input[type='password']").first();if(await l.count()===0||await u.count()===0)return{authenticated:!1,storageState:void 0,reason:"login form could not be identified"};await l.fill(n),await u.fill(i),await Promise.allSettled([c.waitForLoadState("networkidle",{timeout:1e4}),c.locator("button[type='submit'], input[type='submit'], button").first().click()]);let d=await s.storageState();return await wn(e,t,d),{authenticated:!0,storageState:d,reason:"terminal credential storageState"}}catch(s){return{authenticated:!1,storageState:void 0,reason:s instanceof Error?s.message:String(s)}}finally{i.replace(/./g,""),await r.close().catch(()=>{})}}import{createHash as Ja,randomBytes as Tn}from"node:crypto";import{execFile as Za}from"node:child_process";import{promisify as Qa}from"node:util";import{mkdir as Ha,readFile as Va,unlink as Ka,writeFile as Wa}from"node:fs/promises";import Ga from"node:os";import En from"node:path";var Ya="session.json";function at(){let e=process.env.VIBEMOLE_CLI_AUTH_PATH?.trim();return e||En.join(Ga.homedir(),".config","vibemole",Ya)}function Cn(e){return new URL("/api/evidence/local-scan",e).toString()}function ot(e){return new URL(e).origin}function se(e,t=new Date){return e.expiresAt?Date.parse(e.expiresAt)<=t.getTime():!1}function Ee(e,t){return e?t.webUrlExplicit?ot(t.webUrl)!==ot(e.webUrl)?{error:`CLI session is bound to ${e.webUrl}. Omit --web-url or use the same web origin.`}:{webUrl:e.webUrl}:{webUrl:e.webUrl}:{error:"Not logged in. Run: vibemole login"}}function _n(e,t){let o=new URL(e).origin,a=ot(t);if(o!==a)throw new Error(`--upload-url origin (${o}) must match the CLI session web origin (${a}).`)}async function Xa(e,t){await Ha(En.dirname(e),{recursive:!0,mode:448}),await Wa(e,t,{encoding:"utf8",mode:384})}async function V(){let e=at(),t=await Va(e,"utf8").catch(()=>null);if(!t)return null;try{let o=JSON.parse(t);return typeof o.webUrl!="string"||typeof o.token!="string"||typeof o.tokenPrefix!="string"||typeof o.userId!="string"||typeof o.createdAt!="string"?null:o}catch{return null}}async function Rn(e){let t=at();return await Xa(t,JSON.stringify(e,null,2)),t}async function Pn(){let e=at();await Ka(e).catch(()=>{})}var it=Qa(Za),ei="vm_cli_";function ti(e,t){let o;if(t.trim())try{let n=JSON.parse(t);typeof n.error=="string"&&n.error.trim()&&(o=n.error.trim())}catch{}return`Could not create a CLI approval link, so no browser was opened.
|
|
8
|
+
${o??`CLI auth start failed (${e}).`}`}function An(e){return Ja("sha256").update(e).digest("hex")}function ni(){let e=`${ei}${Tn(24).toString("base64url")}`;return{token:e,tokenPrefix:e.slice(0,16),tokenHash:An(e)}}function oi(){let e=Tn(32).toString("base64url");return{secret:e,secretHash:An(e)}}function Ce(e,t){return new URL(t,e).toString()}async function ai(e){await new Promise(t=>setTimeout(t,e))}async function ii(e){let t=process.platform;try{if(t==="darwin"){await it("open",[e]);return}if(t==="win32"){await it("cmd",["/c","start","",e]);return}await it("xdg-open",[e])}catch{console.error(`Open this URL to approve the CLI: ${e}`)}}async function ri(e,t){let o=ni(),a=oi(),n=await fetch(Ce(e,"/api/cli-auth/start"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({clientSecretHash:a.secretHash,uploadTokenHash:o.tokenHash,tokenPrefix:o.tokenPrefix,deviceLabel:t})});if(!n.ok){let r=await n.text().catch(()=>"");throw new Error(ti(n.status,r))}return{start:await n.json(),uploadToken:o.token,clientSecretHash:a.secretHash}}async function si(e,t,o){let a=o?.maxAttempts??120,n=2e3;for(let i=0;i<a;i+=1){let r=await fetch(Ce(e,"/api/cli-auth/poll"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});if(!r.ok){let c=await r.text().catch(()=>"");throw new Error(`CLI auth poll failed (${r.status})${c?`: ${c.slice(0,240)}`:""}`)}let s=await r.json();if(s.status==="approved"){if(!s.userId)throw new Error("Approved CLI link did not return userId.");return s}if(s.status==="denied")throw new Error("CLI authorization was denied in the browser.");if(s.status==="expired")throw new Error("CLI authorization link expired before approval.");await ai(n),n=Math.min(n+500,5e3)}throw new Error("Timed out waiting for CLI authorization approval.")}async function jn(e,t){let o=await fetch(Ce(e,"/api/cli-auth/whoami"),{headers:{authorization:`Bearer ${t}`}});if(!o.ok)throw new Error(`CLI whoami failed (${o.status}).`);return await o.json()}async function ci(e,t){let o=await fetch(Ce(e,"/api/cli-auth/revoke"),{method:"POST",headers:{authorization:`Bearer ${t}`}});if(!o.ok&&o.status!==404)throw new Error(`CLI revoke failed (${o.status}).`)}async function _e(e,t){let{start:o,uploadToken:a,clientSecretHash:n}=await ri(e,t);console.error(`User code: ${o.userCode}`),console.error(`Approve at: ${o.approveUrl}`),await ii(o.approveUrl);let i=await si(e,{linkId:o.linkId,clientSecretHash:n}),r={webUrl:e,token:a,tokenPrefix:a.slice(0,16),userId:i.userId,expiresAt:i.expiresAt??o.expiresAt,createdAt:new Date().toISOString()},s=await Rn(r);return console.error(`CLI session saved to ${s}`),r}async function zn(){let e=await V();e&&await ci(e.webUrl,e.token).catch(()=>{}),await Pn()}import{spawn as zi}from"node:child_process";import{access as li,readFile as rt,readdir as st}from"node:fs/promises";import w from"node:path";var ui=["next.config.js","next.config.mjs","next.config.ts","vite.config.js","vite.config.ts","nuxt.config.ts","svelte.config.js","astro.config.mjs"],di=["app","pages","src/app","src/pages"],Un=[".ts",".tsx",".js",".jsx",".mdx"],mi=["app","pages","src","components","lib"],pi=new Set([".ts",".tsx",".js",".jsx",".md",".mdx",".html"]),gi=new Set(["node_modules",".next","dist","build","coverage","out","output","test","tests","__tests__","__mocks__","__snapshots__","fixtures","fixture","mocks","mock","snapshots","snapshot","examples","example"]),fi=/(?:^|[.\-/])(?:test|spec|fixture|mock|snapshot|stories?)\.[cm]?(?:t|j)sx?$|\.snap$/i;function hi(e){let t=e.toLowerCase(),o=t.split(/[@/._-]+/).filter(Boolean);return t==="next"||t==="vite"||t==="vue"||t==="nuxt"||t.startsWith("@vue/")||t.startsWith("@nuxt/")||t.includes("react")||t.includes("svelte")||t.includes("astro")?"framework":t.includes("supabase")?"database":t==="stripe"||t.includes("@stripe/")?"payments":t.includes("posthog")||t.includes("analytics")||t.includes("gtag")||t.includes("segment")?"analytics":t==="openai"||t==="ai"||t==="@ai-sdk/openai"||t.startsWith("@ai-sdk/")||t.includes("anthropic")||t.includes("langchain")||t.includes("llamaindex")||t.includes("mistral")||t.includes("cohere")||t.includes("groq")||t.includes("perplexity")||t.includes("google-genai")||t.includes("generative-ai")||o.includes("ai")?"ai":t.includes("cookie")||t.includes("consent")||o.includes("cmp")?"consent":t.includes("axe")||t.includes("accessibility")?"accessibility":"other"}async function K(e){try{return await li(e),!0}catch{return!1}}async function Mn(e){let t=await rt(w.join(e,"package.json"),"utf8").catch(()=>"{}");return JSON.parse(t)}function yi(e){let t={...e.dependencies,...e.devDependencies,...e.optionalDependencies};return Object.entries(t).map(([o,a])=>({name:o,version:a,category:hi(o)})).filter(o=>o.category!=="other")}function bi(e){let t=new Set;for(let o of e)o.name==="next"&&t.add("next"),o.name==="vite"&&t.add("vite"),o.name.includes("react")&&t.add("react"),(o.name==="vue"||o.name.startsWith("@vue/"))&&t.add("vue"),(o.name==="nuxt"||o.name.startsWith("@nuxt/"))&&t.add("nuxt"),o.name.includes("svelte")&&t.add("svelte"),o.name.includes("astro")&&t.add("astro");return[...t].sort()}function Ln(e){let t=e.toLowerCase();return/\bcookie|cookies\b/.test(t)?"cookie":/\bprivacy|personal data|data protection\b/.test(t)?"privacy":/\bterms|terms of service|terms and conditions\b/.test(t)?"terms":"unknown"}function ki(e){let t=e.trim();if(!t||/^(https?:|mailto:|tel:|#)/i.test(t))return null;let o=t.split(/[?#]/)[0]??"";return!o.startsWith("/")||!/(privacy|cookie|terms|legal)/i.test(o)||o==="/"?null:o.replace(/\/$/,"")}function ct(e){return e.split(w.sep).join("/")}function In(e){return`/${e.filter(Boolean).join("/")}`.replace(/\/+/g,"/").replace(/\/$/,"")||"/"}var vi=/\[[^\]]+\]/;function wi(e){return!vi.test(e)}function lt(e){return e.startsWith(".")||e.startsWith("_")||gi.has(e.toLowerCase())}function ut(e){return fi.test(e)}function xi(e){let o=e.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);return o.includes("privacy")||o.includes("data")&&o.includes("protection")?"privacy":o.includes("cookie")||o.includes("cookies")?"cookie":o.includes("terms")||o.includes("tos")||o.includes("terms")&&o.includes("service")?"terms":"unknown"}function Si(e){return!(lt(e)||e.startsWith("(")&&!e.endsWith(")"))}function Ei(e){return e.startsWith("@")||e.startsWith("(")&&e.endsWith(")")?null:e}async function Dn(e,t,o,a){let n=w.join(e,t),i=await st(n,{withFileTypes:!0}).catch(()=>[]);for(let r of i){let s=w.join(t,r.name);if(r.isDirectory()){if(!Si(r.name))continue;let l=Ei(r.name);await Dn(e,s,l?[...o,l]:o,a);continue}if(!r.isFile()||ut(r.name))continue;let c=w.extname(r.name);!Un.includes(c)||w.basename(r.name,c)!=="page"||a.push({path:In(o),sourceFile:ct(s),kind:"next-app-page"})}}async function On(e,t,o,a){let n=w.join(e,t),i=await st(n,{withFileTypes:!0}).catch(()=>[]);for(let r of i){let s=w.join(t,r.name);if(r.isDirectory()){if(lt(r.name)||r.name==="api")continue;await On(e,s,[...o,r.name],a);continue}if(!r.isFile()||r.name.startsWith("_")||ut(r.name))continue;let c=w.extname(r.name);if(!Un.includes(c))continue;let l=w.basename(r.name,c),u=l==="index"?o:[...o,l];a.push({path:In(u),sourceFile:ct(s),kind:"next-pages-page"})}}async function Ci(e){let t=[];for(let a of di)await K(w.join(e,a))&&(a.endsWith("app")?await Dn(e,a,[],t):await On(e,a,[],t));let o=new Set;return t.filter(a=>{let n=`${a.kind}:${a.path}:${a.sourceFile}`;return o.has(n)?!1:(o.add(n),!0)})}function ce(e,t){return e.some(o=>{let a=o.path.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);return t.some(n=>{let i=n.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);return i.length>0&&i.every(r=>a.includes(r))})})}function _i(e){let t=[],o=new Set;for(let a of e){let n=xi(a.path);n==="unknown"||o.has(a.path)||(o.add(a.path),t.push({path:a.path,typeGuess:n,provenance:"project-route",sourceFile:a.sourceFile}))}return t}async function Nn(e,t,o,a=300){if(o.length>=a)return;let n=w.join(e,t),i=await st(n,{withFileTypes:!0}).catch(()=>[]);for(let r of i){if(o.length>=a)return;if(lt(r.name))continue;let s=w.join(t,r.name);if(r.isDirectory()){await Nn(e,s,o,a);continue}r.isFile()&&pi.has(w.extname(r.name))&&!ut(r.name)&&o.push(ct(s))}}async function Ri(e){let t=[];for(let n of mi)await Nn(e,n,t);let o=[],a=new Set;for(let n of t){let i=await rt(w.join(e,n),"utf8").catch(()=>"");if(!/(privacy|cookie|terms|data protection|personal data)/i.test(i))continue;let r=i.matchAll(/(?:href|to)\s*=\s*["'`]([^"'`]+)["'`]/gi);for(let s of r){let c=ki(s[1]??"");if(!c||a.has(c))continue;a.add(c);let l=Ln(c);o.push({path:c,typeGuess:l==="unknown"?Ln(i.slice(Math.max(0,(s.index??0)-80),(s.index??0)+160)):l,provenance:"project-trace",sourceFile:n,textSnippet:i.slice(Math.max(0,(s.index??0)-60),(s.index??0)+120).replace(/\s+/g," ").trim()})}}return o}async function Pi(e,t){let o=new Set(t.map(r=>r.path)),a=(await Ri(e)).filter(r=>o.has(r.path)),n=[..._i(t),...a],i=new Set;return n.filter(r=>{let s=`${r.provenance}:${r.path}:${r.sourceFile??""}`;return i.has(s)?!1:(i.add(s),!0)})}async function Ti(e){let t=new Set;for(let o of[".env",".env.local",".env.development",".env.production"]){let a=await rt(w.join(e,o),"utf8").catch(()=>"");for(let n of a.split(/\r?\n/)){let i=n.match(/^\s*(?:export\s+)?([A-Z0-9_]+)\s*=/);i?.[1]&&t.add(i[1])}}return[...t].sort()}async function Ai(e){let t=[];for(let o of ui)await K(w.join(e,o))&&t.push(o);return t}function ji(e,t){let o=[];return e.some(a=>a.name.includes("posthog"))&&o.push({severity:"risk",title:"PostHog dependency detected",detail:"Runtime scan required to verify analytics consent gating."}),e.some(a=>a.category==="payments")&&o.push({severity:"risk",title:"Payment dependency detected",detail:"Privacy and terms pages should disclose payment processing."}),e.some(a=>a.category==="ai")&&o.push({severity:"risk",title:"AI provider dependency detected",detail:"Check whether user input is sent to an AI provider and disclosed."}),t.some(a=>a.includes("POSTHOG")||a.includes("GA_")||a.includes("GTAG"))&&o.push({severity:"risk",title:"Analytics environment names detected",detail:"Runtime scan should verify analytics requests are consent-gated."}),e.some(a=>a.category==="consent")||o.push({severity:"risk",title:"No consent package detected",detail:"This is a package-level hint only; runtime scan should verify whether consent UI exists."}),o}async function $n(e){return(await Mn(e)).scripts??{}}async function Bn(e){let t=await Mn(e),o=yi(t),a=await Ti(e),n=await Ci(e),i=await Pi(e,n);return{root:e,packageManager:await K(w.join(e,"pnpm-lock.yaml"))?"pnpm":await K(w.join(e,"yarn.lock"))?"yarn":await K(w.join(e,"bun.lockb"))?"bun":await K(w.join(e,"package-lock.json"))?"npm":"unknown",frameworks:bi(o),dependencies:o,routes:{privacy:ce(n,["privacy","privacy-policy","data-protection"]),terms:ce(n,["terms","terms-of-service","terms-and-conditions"]),dashboard:ce(n,["dashboard","app/dashboard"]),account:ce(n,["account","profile","settings"]),billing:ce(n,["billing","checkout","pricing"])},policyCandidates:i,runtimeRouteCandidates:[...new Set(n.map(r=>r.path))].filter(wi).sort(),envNames:a,configFiles:await Ai(e),findings:ji(o,a)}}function Li(e){for(let t of["dev","start","preview"]){let o=e[t];if(o)return{name:t,command:o}}return null}function Ui(e){return e.match(/https?:\/\/(?:localhost|127\.0\.0\.1|\[::1\])(?::\d+)?(?:\/[^\s'"]*)?/i)?.[0]??null}async function qn(e){let t=await $n(e.root),o=Li(t);if(!o)return{targetUrl:null,process:null,script:null};let a=zi("npm",["run",o.name],{cwd:e.root,env:process.env,shell:!1});return await new Promise(n=>{let i=!1,r=setTimeout(()=>{i||(i=!0,n({targetUrl:null,process:a,script:o}))},e.timeoutMs??2e4),s=c=>{let l=c.toString("utf8");e.onOutput?.(l);let u=Ui(l);!u||i||(i=!0,clearTimeout(r),n({targetUrl:u,process:a,script:o}))};a.stdout.on("data",s),a.stderr.on("data",s),a.on("exit",()=>{i||(i=!0,clearTimeout(r),n({targetUrl:null,process:a,script:o}))})})}import{randomUUID as Qi}from"node:crypto";import{mkdir as er,writeFile as tr}from"node:fs/promises";import Qn from"node:path";var Re="securitymole.evidence.v1";var Fn="vibemole.evidence.v1";var Mi=[{pattern:/posthog|whatsup\.paradaq\.com|\/array\/phc_/i,vendors:["PostHog"]},{pattern:/@supabase\/|supabase-js|supabase-ssr/i,vendors:["Supabase"]},{pattern:/^openai$|@openai\//i,vendors:["OpenAI"]},{pattern:/stripe/i,vendors:["Stripe"]}];function Ii(e,t=120){return e.replace(/\s+/g," ").trim().slice(0,t)}function Di(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Vn(e){let t=e.toLowerCase();return/\bcookie|cookies\b/.test(t)?"cookie":/\bprivacy|personal data|data protection\b/.test(t)?"privacy":/\bterms|terms of service|terms and conditions\b/.test(t)?"terms":"unknown"}function Oi(e){let t=new Set;for(let o of e){let a=o.trim();if(a){t.add(a);for(let n of Mi)if(n.pattern.test(a))for(let i of n.vendors)t.add(i)}}return[...t].sort()}var Hn=new Set(["PostHog","Supabase","OpenAI","Stripe"]);function Ni(e){let t=e.trim();return t?t==="PostHog"||/^(__ph_|ph_|posthog)/i.test(t)||/posthog-js/i.test(t)||/\/array\/phc_/i.test(t)||/posthog\.com/i.test(t)||/whatsup\.paradaq\.com/i.test(t):!1}function $i(e){return/whatsup\.paradaq\.com/i.test(e)||/\/array\/phc_/i.test(e)}function Bi(e){return/^[a-z0-9.-]+\.[a-z]{2,}(:\d+)?$/i.test(e)||/^https?:\/\//i.test(e)}function pt(e){let t=Oi(e),o=t.some(n=>Ni(n)),a=new Set;for(let n of t){let i=Xi(n);if($i(n)){o&&a.add("PostHog");continue}if(Bi(n)){Hn.has(i)&&a.add(i);continue}if(Hn.has(i)&&i!==n){a.add(i);continue}a.add(i)}return[...a].sort()}function gt(e){let t=e.url;try{let o=new URL(e.url);o.pathname.length>1&&o.pathname.endsWith("/")&&(o.pathname=o.pathname.slice(0,-1)),t=o.toString()}catch{t=e.url}return[e.typeGuess,t].join("|")}function ft(e){let t=new Set,o=[];for(let a of e){let n=gt(a);t.has(n)||(t.add(n),o.push(a))}return o}function Kn(e,t){try{let o=new URL(e,t),a=new URL(t);return o.origin!==a.origin?null:o.toString()}catch{return null}}function qi(e){let t=new URL(e),o=t.hash?t.hash.slice(1):null;return t.hash="",{fetchUrl:t.toString(),fragment:o}}function Wn(e){let t=new Set,o=[];for(let a of e.links){let n=Vn(`${a.text} ${a.href}`);if(n==="unknown")continue;let i=Kn(a.href,e.sourceRouteUrl);if(!i)continue;let r=`${n}|${i}`;t.has(r)||(t.add(r),o.push({url:i,typeGuess:n,provenance:"rendered-link",sourceRouteUrl:e.sourceRouteUrl,...a.selector?{selector:a.selector}:{},linkTextSnippet:Ii(a.text)}))}return o}function Fi(e){return e.replace(/ /gi," ").replace(/&/gi,"&").replace(/</gi,"<").replace(/>/gi,">").replace(/"/gi,'"').replace(/'/gi,"'")}function Hi(e){return e.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi," ").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi," ").replace(/<noscript\b[^>]*>[\s\S]*?<\/noscript>/gi," ")}function mt(e,t=4e3){let o=Hi(e);o=o.replace(/<\/(h[1-6]|p|li|tr|td|th|div|section|article|blockquote|pre)\b[^>]*>/gi,`</$1>
|
|
9
|
+
`),o=o.replace(/<(br|hr)\b[^>]*\/?>/gi,`
|
|
10
|
+
`);let a=o.replace(/<[^>]*>/g," ");return Fi(a).replace(/[ \t]+/g," ").replace(/\n[ \t]+/g,`
|
|
11
|
+
`).replace(/\n{3,}/g,`
|
|
12
|
+
|
|
13
|
+
`).trim().slice(0,t)}function Vi(e,t=4e3){return(e.includes("<")?mt(e,t):e).replace(/\s+/g," ").trim().slice(0,t)}function Ki(e,t,o){if(t){let a=e.match(new RegExp(`<([a-z0-9]+)[^>]*\\sid=["']${Di(t)}["'][^>]*>([\\s\\S]*?)(?=<h[1-6]\\b|<section\\b|</body)`,"i"));if(a?.[2])return a[2]}if(o==="cookie"){let a=e.match(/<h[1-6][^>]*>[^<]*\bcookies?\b[^<]*<\/h[1-6]>([\s\S]*?)(?=<h[1-6]\b|$)/i);if(a?.[1])return a[1]}return null}function Wi(e,t,o,a=4e3){let n=Ki(e,t,o);if(n){let i=mt(n,a);if(i.length>(o==="cookie"?40:80))return i}return mt(e,a)}function Gi(e,t){let o=e.toLowerCase(),a=/(privacy policy|cookie policy|cookie notice|terms of service|terms and conditions|data protection|политика конфиденциальности|условия использования|политика cookie)/i.test(e),n=/(personal data|cookies?|analytics|tracking|processor|provider|third party|retention|legal basis|privacy|персональные данные|контролер данных|поставщик|область действия|куки|файлы cookie)/i.test(e);return/(sign in|log in|login|email password|forgot password|create account|войти|авториза)/i.test(e)&&!a?!1:t==="privacy"?a||/политика конфиденциальности|персональные данные|контролер данных/i.test(e)||o.includes("privacy")&&n:t==="cookie"?a||/куки|файлы cookie/i.test(e)||(o.includes("cookie")||o.includes("cookies"))&&n:t==="terms"?a||/условия|поставщик|область действия/i.test(e)||o.includes("terms"):a&&n}function Yi(e,t){if(!t)return!1;let o=new URL(t),a=new URL(e);return o.pathname===a.pathname&&!o.searchParams.has("next")?!1:/(login|signin|sign-in|auth)/i.test(o.pathname)||o.searchParams.has("next")||o.searchParams.has("redirect")}function Xi(e){return/posthog/i.test(e)?"PostHog":/supabase/i.test(e)?"Supabase":/^openai$|@openai/i.test(e)?"OpenAI":/stripe/i.test(e)?"Stripe":e}function dt(e,t){let o=pt(t),a=e.toLowerCase(),n={},i=o.includes("PostHog");for(let r of o){if(r==="PostHog"&&i){n[r]=a.includes("posthog")||/analytics|product analytics|usage analytics|tracking|cookies?/i.test(a);continue}n[r]=a.includes(r.toLowerCase())}return n}async function Gn(e,t){let o=e,a=t.typeGuess??Vn(e),{fetchUrl:n,fragment:i}=qi(e),r=Kn(n,t.baseUrl);if(!r)return{url:o,status:null,finalUrl:null,fetched:!1,extractionSucceeded:!1,normalizedTextExcerpt:"",mentions:dt("",t.observedTerms??[]),contentLooksLikePolicy:!1,error:"policy URL is not same-origin"};try{let s=t.fetchImpl??fetch,c=t.textCap??4e3,l={};t.acceptLanguage&&(l["Accept-Language"]=t.acceptLanguage);let u=await s(r,Object.keys(l).length>0?{headers:l}:void 0),d=await u.text(),m=u.url||r,p=Yi(o,m),f=Wi(d,i,a,c),E=Vi(f,c),x=!p&&Gi(E,a),S=E.length>0&&x;return{url:o,status:u.status,finalUrl:m,fetched:!0,extractionSucceeded:S,plainTextExcerpt:f,normalizedTextExcerpt:E,mentions:dt(E,t.observedTerms??[]),contentLooksLikePolicy:x,...p?{redirectedFromCandidate:!0}:{},...S?{}:{error:p?"redirected to login or protected page; policy text not accessible":E.length===0?"no policy text extracted":"fetched content does not look like policy text"}}}catch(s){return{url:o,status:null,finalUrl:null,fetched:!1,extractionSucceeded:!1,normalizedTextExcerpt:"",mentions:dt("",t.observedTerms??[]),contentLooksLikePolicy:!1,error:s instanceof Error?s.message:String(s)}}}function Ji(e){return{...e,cookies:e.cookies.map(({name:t,domain:o,path:a,expiry:n,isSession:i,secure:r,httpOnly:s,sameSite:c})=>{let l={name:t,domain:o,path:a};return n!==void 0&&(l.expiry=n),i!==void 0&&(l.isSession=i),r!==void 0&&(l.secure=r),s!==void 0&&(l.httpOnly=s),c!==void 0&&(l.sameSite=c),l}),storage:e.storage.map(({type:t,key:o})=>({type:t,key:o}))}}function Zi(e){let t=0,o={};for(let[a,n]of Object.entries(e))/authorization|cookie|set-cookie|token|secret|api[-_]?key/i.test(a)&&n?(o[a]=null,t+=1):o[a]=n;return{headers:o,stripped:t}}function Yn(e,t={}){let o=t.policyTextCap??e.redactionSummary.policyTextCappedToChars??4e3,a=0,n=0,i=0,r=e.runtimeProfiles.map(s=>{a+=s.evidence.cookies.filter(f=>f.value!==void 0).length,n+=s.evidence.storage.filter(f=>f.value!==void 0).length;let c=Ji(s.evidence),l=Zi(s.evidence.securityHeaders);i+=l.stripped;let{loadedScriptUrls:u,resourceUrls:d,pageSiteSignals:m,...p}=c;return{...s,evidence:{...p,...u?{loadedScriptUrls:u}:{},...d?{resourceUrls:d}:{},...m?{pageSiteSignals:m}:{},securityHeaders:l.headers}}});return{...e,runtimeProfiles:r,...e.runtimeConsentDiffs?{runtimeConsentDiffs:e.runtimeConsentDiffs}:{},policyEvidence:{candidates:e.policyEvidence.candidates.map(s=>({...s,linkTextSnippet:s.linkTextSnippet?.slice(0,160)})),fetched:e.policyEvidence.fetched.map(s=>({...s,normalizedTextExcerpt:s.normalizedTextExcerpt.slice(0,o),...s.plainTextExcerpt?{plainTextExcerpt:s.plainTextExcerpt.slice(0,o)}:{}}))},redactionSummary:{...e.redactionSummary,cookieValuesStripped:e.redactionSummary.cookieValuesStripped+a,storageValuesStripped:e.redactionSummary.storageValuesStripped+n,authTokensStripped:e.redactionSummary.authTokensStripped+i,rawHtmlStripped:!0,inlineScriptsStripped:!0,policyTextCappedToChars:o}}}function ht(e){return{name:e.name,domain:e.domain,path:e.path}}function yt(e){return{type:e.type,key:e.key}}function Xn(e){return`${e.name}|${e.domain}|${e.path}`}function Jn(e){return`${e.type}|${e.key}`}function $(e,t,o){let a=new Map(e.map(c=>[o(c),c])),n=new Map(t.map(c=>[o(c),c])),i=t.filter(c=>!a.has(o(c))),r=e.filter(c=>!n.has(o(c))),s=e.filter(c=>n.has(o(c)));return{added:i,removed:r,unchanged:s}}function Zn(e){let t=new Map;for(let a of e){let n=`${a.routeUrl}::${a.authenticated?"auth":"anon"}`,i=t.get(n)??[];i.push(a),t.set(n,i)}let o=[];for(let a of t.values()){let n=a[0]?.routeUrl,i=a[0]?.authenticated??!1;if(!n)continue;let r=a.find(m=>m.consentMode==="none");if(!r?.evidence.consent.bannerFound)continue;let s=a.find(m=>m.consentMode==="accepted"),c=a.find(m=>m.consentMode==="declined"),l=[],u=r&&r.evidence.navigationSucceeded?{cookies:r.evidence.cookies.map(ht),storage:r.evidence.storage.map(yt)}:void 0;u||l.push("beforeConsent: baseline none profile missing or navigation failed"),s?s.consentInteraction.succeeded||l.push(`afterAccept: consent interaction incomplete (${s.consentInteraction.error??"no accept control"})`):l.push("afterAccept: accepted profile was not collected"),c?c.consentInteraction.succeeded||l.push(`afterDecline: consent interaction incomplete (${c.consentInteraction.error??"no reject control"})`):l.push("afterDecline: declined profile was not collected");let d={routeUrl:n,authenticated:i,availablePhases:{beforeConsent:!!u,afterAccept:!!s?.consentInteraction.succeeded,afterDecline:!!c?.consentInteraction.succeeded},...u?{beforeConsent:u}:{},...l.length>0?{missingPhaseReasons:l}:{}};u&&s?.consentInteraction.succeeded&&(d.afterAccept={cookies:$(u.cookies,s.evidence.cookies.map(ht),Xn),storage:$(u.storage,s.evidence.storage.map(yt),Jn),requestDomains:$(r.evidence.requestDomains,s.evidence.requestDomains,m=>m),trackerDomains:$(r.evidence.trackerDomains,s.evidence.trackerDomains,m=>m)}),u&&c?.consentInteraction.succeeded&&(d.afterDecline={cookies:$(u.cookies,c.evidence.cookies.map(ht),Xn),storage:$(u.storage,c.evidence.storage.map(yt),Jn),requestDomains:$(r.evidence.requestDomains,c.evidence.requestDomains,m=>m),trackerDomains:$(r.evidence.trackerDomains,c.evidence.trackerDomains,m=>m)}),(u||s||c)&&o.push(d)}return o}var Pe={privacy:24e3,cookie:8e3,terms:8e3,unknown:8e3},eo={"project-route":0,"rendered-link":1,"project-trace":2,"route-scan":3,"sitemap-like-route":4};function bt(e,t){return new URL(t,e).toString()}function nr(e){return Pe[e.typeGuess]??Pe.unknown}function or(e){try{let t=new URL(e).pathname.toLowerCase();return t==="/ru"||t.startsWith("/ru/")?"ru":t==="/en"||t.startsWith("/en/")?"en":/^\/[a-z]{2}(\/|$)/.test(t)?"unknown":"en"}catch{return"unknown"}}function ar(e){let t=new Map;for(let a of e){let n=t.get(a.typeGuess)??[];n.push(a),t.set(a.typeGuess,n)}let o=[];for(let a of t.values()){let n=a.filter(i=>or(i.url)==="en");o.push(...n.length>0?n:a)}return ft(o)}var ir=/^(@types\/|react$|react-dom$|next$|lucide-react$)/i,rr=/posthog|supabase|stripe|openai|analytics|cookie|tag manager|gtm/i;function sr(e){let t=[];for(let o of e)ir.test(o.name)||(o.category==="analytics"||o.category==="payments"||o.category==="ai"||o.category==="database"||o.category==="consent"||rr.test(o.name))&&t.push(o.name);return t}function cr(e,t){let o=new Set(["analytics","cookies","storage","tracking pixels","tag managers"]);for(let a of sr(e.dependencies))o.add(a);for(let a of t){for(let n of a.evidence.cookies)/^(__ph_|ph_|posthog)/i.test(n.name)&&o.add("PostHog"),/stripe/i.test(n.name)&&o.add("Stripe"),/supabase/i.test(n.name)&&o.add("Supabase");for(let n of a.evidence.storage)/^(__ph_|ph_|posthog)/i.test(n.key)&&o.add("PostHog"),/stripe/i.test(n.key)&&o.add("Stripe"),/supabase/i.test(n.key)&&o.add("Supabase"),/openai/i.test(n.key)&&o.add("OpenAI");for(let n of a.evidence.knownGlobals??[])/^(dataLayer|google_tag_manager|gtag|ga)$/i.test(n)&&o.add("Google Tag Manager"),/^(fbq|ttq|hj|clarity|ym|analytics|amplitude)$/i.test(n)&&o.add(n),/posthog/i.test(n)&&o.add("PostHog");for(let n of a.evidence.trackerDomains)/posthog|whatsup\.paradaq|phc_/i.test(n)?o.add("PostHog"):/stripe/i.test(n)?o.add("Stripe"):/supabase/i.test(n)?o.add("Supabase"):/openai/i.test(n)&&o.add("OpenAI");for(let n of[...a.evidence.requestDomains,...a.evidence.resourceDomains,...a.evidence.scriptDomains])/posthog|whatsup\.paradaq|phc_/i.test(n)?o.add("PostHog"):/stripe/i.test(n)?o.add("Stripe"):/supabase/i.test(n)?o.add("Supabase"):/openai/i.test(n)&&o.add("OpenAI");for(let n of a.evidence.loadedScriptUrls??[])/\/array\/phc_|posthog/i.test(n)&&o.add("PostHog");for(let n of a.evidence.resourceUrls??[])/\/array\/phc_|posthog/i.test(n)&&o.add("PostHog")}return pt([...o])}function lr(e){let t=[],o=new Set,a=i=>{let r=gt(i);o.has(r)||(o.add(r),t.push(i))};if(e.targetUrl){if(e.projectEvidence.policyCandidates?.length)for(let i of e.projectEvidence.policyCandidates)a({url:bt(e.targetUrl,i.path),typeGuess:i.typeGuess,provenance:i.provenance,linkTextSnippet:i.textSnippet});else e.projectEvidence.routes.privacy&&a({url:bt(e.targetUrl,"/privacy"),typeGuess:"privacy",provenance:"project-route"}),e.projectEvidence.routes.terms&&a({url:bt(e.targetUrl,"/terms"),typeGuess:"terms",provenance:"project-route"});for(let i of e.runtimeProfiles)for(let r of Wn({sourceRouteUrl:i.routeUrl,links:i.evidence.renderedLinks??[]}))a(r)}let n=ft(t.sort((i,r)=>{let s=eo[i.provenance]-eo[r.provenance];return s!==0?s:i.url.localeCompare(r.url)}));return ar(n)}function ur(e){return e.some(t=>t.evidence.cookies.length>0||t.evidence.storage.length>0||t.evidence.trackerDomains.length>0)}function dr(e,t,o,a){let n=[...a],i=e.some(c=>c.typeGuess==="privacy"),r=e.some(c=>c.typeGuess==="cookie");!(i||o.some(c=>(c.evidence.renderedLinks??[]).some(l=>/privacy/i.test(`${l.text} ${l.href}`))))&&e.filter(c=>c.typeGuess==="privacy").length===0?n.push("No privacy policy route or rendered link was found."):i||n.push("No privacy policy candidate was discovered from project routes or rendered links."),ur(o)&&!r&&n.push("No cookie policy was found although cookies, storage, or tracking signals were observed.");for(let c of t)if(c.fetched){if(c.redirectedFromCandidate){n.push(`Policy fetch for ${c.url} redirected away from the policy page (login or protected route).`);continue}c.fetched&&!c.extractionSucceeded&&(c.contentLooksLikePolicy===!1?n.push(`Policy candidate ${c.url} was fetched but content did not look like policy text.`):c.error&&n.push(`Policy candidate ${c.url}: ${c.error}`))}return[...new Set(n)]}async function to(e,t){let o=Qn.join(e,".vibemole","evidence");await er(o,{recursive:!0});let a=Qn.join(o,`${t.scanId}.json`);return await tr(a,`${JSON.stringify(t,null,2)}
|
|
14
|
+
`,"utf8"),a}async function no(e){let t=e.generatedAt??new Date().toISOString(),o=e.reportLocale??"en",a=xe(o),n=lr(e),i=cr(e.projectEvidence,e.runtimeProfiles),r=e.fetchPolicy??((d,m)=>Gn(d.url,{baseUrl:m.baseUrl,observedTerms:m.observedTerms,textCap:m.textCap,acceptLanguage:m.acceptLanguage,typeGuess:d.typeGuess})),s=e.targetUrl===null?[]:await Promise.all(n.map(d=>r(d,{baseUrl:e.targetUrl,observedTerms:i,textCap:nr(d),acceptLanguage:a}))),c=dr(n,s,e.runtimeProfiles,e.collectorWarnings??[]),l=Zn(e.runtimeProfiles),u={version:Fn,scanId:e.scanId??Qi(),target:{root:e.root,baseUrl:e.targetUrl,generatedAt:t,reportLocale:o},projectEvidence:e.projectEvidence,runtimeProfiles:e.runtimeProfiles,...l.length>0?{runtimeConsentDiffs:l}:{},policyEvidence:{candidates:n,fetched:s},redactionSummary:{cookieValuesStripped:0,storageValuesStripped:0,authTokensStripped:0,rawHtmlStripped:!1,inlineScriptsStripped:!1,policyTextCappedToChars:Pe.privacy},collectorDiagnostics:{startedAt:t,finishedAt:new Date().toISOString(),routeCap:e.collectorRouteCap??10,warnings:c}};return Yn(u,{policyTextCap:Pe.privacy})}function Te(e){let t=e.policyEvidence.fetched.filter(r=>r.fetched).length,o=e.runtimeProfiles.filter(r=>r.evidence.navigationSucceeded).length,a=[...new Set(e.runtimeProfiles.flatMap(r=>r.evidence.trackerDomains))].sort(),n=e.collectorDiagnostics.warnings.length>0?["","Warnings:",...e.collectorDiagnostics.warnings.map(r=>` - ${r}`)]:[],i=(e.runtimeConsentDiffs??[]).flatMap(r=>{let s=r.beforeConsent?.cookies.length??0,c=r.beforeConsent?.storage.length??0,l=r.afterAccept?.cookies.added.length??0,u=r.afterDecline?.cookies.unchanged.length??0,d=r.afterAccept?.trackerDomains.added.join(", ")||"none";return["",`Consent diff (${r.routeUrl}${r.authenticated?", authenticated":""}):`,` Cookies before consent: ${s}`,` Cookies added after accept: ${l}`,` Cookies unchanged after decline: ${u}`,` Storage keys before consent: ${c}`,` Storage keys added after accept: ${r.afterAccept?.storage.added.length??0}`,` Storage keys unchanged after decline: ${r.afterDecline?.storage.unchanged.length??0}`,` Tracker domains added after accept: ${d}`]});return["VibeMole local evidence package",`Scan ID: ${e.scanId}`,`Target: ${e.target.baseUrl??"not resolved"}`,"Upload package: redacted evidence v1","","Coverage:",` Runtime profiles: ${e.runtimeProfiles.length}`,` Runtime navigations succeeded: ${o}`,` Policy candidates: ${e.policyEvidence.candidates.length}`,` Policy pages fetched: ${t}`,"","Observed signals:",` Tracker domains: ${a.join(", ")||"none observed"}`,` Cookie values stripped: ${e.redactionSummary.cookieValuesStripped}`,` Storage values stripped: ${e.redactionSummary.storageValuesStripped}`,...i,...n].join(`
|
|
15
|
+
`)}var Ae=class{constructor(t,o=!0){this.stream=t;this.enabled=o}stream;enabled;timer=null;frame=0;message="";frames=["|","/","-","\\"];clearLine="\r\x1B[2K";start(t){if(this.enabled){if(this.stop(),this.message=t,!this.stream.isTTY){this.stream.write(`${t}
|
|
16
|
+
`);return}this.render(),this.timer=setInterval(()=>this.render(),120)}}update(t){if(this.enabled){if(this.message=t,!this.stream.isTTY){this.stream.write(`${t}
|
|
17
|
+
`);return}this.render()}}runtimeProgress(t,o,a){if(!this.enabled)return;this.stop();let n=this.formatRuntimeProgress(t,o,a);if(!this.stream.isTTY){this.stream.write(`${n}
|
|
18
|
+
`);return}this.stream.write(`${this.clearLine}${n}`)}success(t){this.enabled&&(this.stop(),this.stream.write(this.stream.isTTY?`${this.clearLine}${t}
|
|
19
|
+
`:`${t}
|
|
20
|
+
`))}stop(){this.timer&&(clearInterval(this.timer),this.timer=null)}render(){let t=this.frames[this.frame%this.frames.length]??"|";this.frame+=1,this.stream.write(`${this.clearLine}${t} ${this.message}`)}formatRuntimeProgress(t,o,a){let i=Math.max(o,1),r=Math.min(1,Math.max(0,t/i)),s=Math.min(10,Math.round(r*10));return`${`[${"=".repeat(s)}${" ".repeat(10-s)}]`} ${t}/${o} ${a}`}};import mr from"node:os";function oo(e){return!e.json&&!e.noUpload}async function ao(e,t={}){let o=t.loadSession??V,a=t.login??_e,n=t.deviceLabel??`${process.env.USER||"user"}@${mr.hostname()}`,i=await o();if(!i||se(i))try{i=await a(e.webUrl,n)}catch(s){return{ok:!1,error:s instanceof Error?s.message:String(s)}}let r=Ee(i,e);if("error"in r)return{ok:!1,error:r.error};if(se(i))return{ok:!1,error:"CLI session expired. Run: vibemole login"};try{let s=e.uploadUrl??Cn(r.webUrl);return e.uploadUrl&&_n(e.uploadUrl,r.webUrl),{ok:!0,uploadUrl:s,session:i}}catch(s){return{ok:!1,error:s instanceof Error?s.message:String(s)}}}var go=Ea(mo(),1);var zr=new Set(["analytics","marketing","tag_manager","ad_remarketing","social_media_pixel","session_replay_heatmap"]),Lr=new Set(["analytics","marketing","tag_manager"]),Ur=new Set(["essential","functional","session_persistence","consent_state","fraud_prevention"]),Mr=new Set(["chat_widget","strictly_necessary","necessary","technical","functional","security","consent_management","essential"]);function kt(e,t){let o=e.trim().toLowerCase(),a=t.trim().toLowerCase();return zr.has(o)||Lr.has(a)?"non_functional":Mr.has(o)||Ur.has(a)?"exempt_functional":"unknown"}var po=/(doubleclick|facebook|fbcdn|tiktok|snap|pixel|analytics|track|adservice|ads\.|metrics\.|mc\.yandex)/i,Ir=new Set(["social_media_pixel","ad_remarketing"]);function St(e){try{return new URL(e)}catch{return null}}function I(e){return e.trim().toLowerCase().replace(/^\.+/,"")}function wt(e){let t=St(e),o=t?t.hostname:e;return(0,go.getDomain)(o,{allowPrivateDomains:!0})?.toLowerCase()??null}function je(e){let t=St(e);return t?.hostname?I(t.hostname):null}function xt(e,t){let o=I(e);if(!o)return!1;let a=St(t);if(!a)return!1;let n=a.hostname.toLowerCase(),i=wt(n),r=wt(o);return i&&r?i!==r:o!==n}function ue(e){return[...new Set(e.map(I).filter(Boolean))].sort((t,o)=>t.localeCompare(o))}function Et(e){let t=new Set;for(let o of e){let a=je(o);a&&t.add(a)}return[...t].sort((o,a)=>o.localeCompare(a))}function Dr(e){let t=new Map;for(let o of e)for(let a of o.thirdPartyDomains){let n=I(a);if(!n)continue;let i=t.get(n);if(!i){t.set(n,{category:o.category,purpose:o.likelyPurpose});continue}i.category==="unknown"&&o.category!=="unknown"&&t.set(n,{category:o.category,purpose:o.likelyPurpose})}return t}function Or(e){let t=new Set;for(let a of e.trackingTechnologies)if(Ir.has(a.category))for(let n of a.thirdPartyDomains){let i=I(n);i&&t.add(i)}let o=ue(e.resourceUrls.filter(a=>/(\/pixel|\/tr(?:\?|\/|$)|\/collect)/i.test(a)).map(a=>je(a)).filter(a=>!!a));for(let a of o)po.test(a)&&t.add(a);for(let a of[...Et(e.loadedScriptUrls),...e.thirdPartyRequestDomains.map(I)])po.test(a)&&t.add(a);return[...t].sort((a,n)=>a.localeCompare(n))}function Nr(e){return e.thirdPartyRequestDomains.length>0?ue(e.thirdPartyRequestDomains):e.requestDomains?.length?ue(e.requestDomains.filter(t=>xt(t,e.targetUrl))):ue([...e.resourceUrls,...e.loadedScriptUrls].map(t=>je(t)).filter(t=>t!==null&&xt(t,e.targetUrl)))}function $r(e){return e.scriptDomains?.length?ue(e.scriptDomains):Et(e.loadedScriptUrls)}function Ct(e,t){return`${e}|${I(t)}`}function vt(e,t,o,a,n,i){let r=I(o);if(!r)return;let s=Ct(t,r),c=i.get(r),l=c?.category??"unknown",u=c?.purpose??"unknown",d=kt(l,u),m=e.get(s);if(!m){e.set(s,{kind:t,domain:r,likelyCategory:l,likelyPurpose:u,classification:d,pages:new Set(a),presentInRuns:[n]});return}for(let p of a)m.pages.add(p);m.presentInRuns.some(p=>p.profileKey===n.profileKey&&p.consentMode===n.consentMode)||m.presentInRuns.push(n),m.likelyCategory==="unknown"&&l!=="unknown"&&(m.likelyCategory=l,m.likelyPurpose=u,m.classification=d)}function _t(e,t){let o=Dr(e.trackingTechnologies),a=e.pageUrls.length>0?e.pageUrls:[e.targetUrl],n=new Map;for(let i of $r(e))vt(n,"script",i,a,t,o);for(let i of Or(e))vt(n,"pixel",i,a,t,o);for(let i of Nr(e))vt(n,"third_party_request",i,a,t,o);return[...n.values()].map(i=>{let r=[...i.pages].sort((s,c)=>s.localeCompare(c)).slice(0,3);return{signalKey:Ct(i.kind,i.domain),kind:i.kind,domain:i.domain,label:i.domain,likelyCategory:i.likelyCategory,likelyPurpose:i.likelyPurpose,classification:i.classification,observedPageCountMax:i.pages.size,samplePages:r,presentInRuns:[...i.presentInRuns].sort((s,c)=>`${s.profileKey}|${s.consentMode}`.localeCompare(`${c.profileKey}|${c.consentMode}`))}}).sort((i,r)=>i.signalKey.localeCompare(r.signalKey))}function Rt(e){let t=new Map;for(let o of e)for(let a of _t(o.observation,o.context)){let n=t.get(a.signalKey);if(!n){t.set(a.signalKey,{...a,presentInRuns:[...a.presentInRuns]});continue}let i=new Set([...n.samplePages,...a.samplePages]);n.observedPageCountMax=Math.max(n.observedPageCountMax,a.observedPageCountMax),n.samplePages=[...i].sort((r,s)=>r.localeCompare(s)).slice(0,3);for(let r of a.presentInRuns)n.presentInRuns.some(s=>s.profileKey===r.profileKey&&s.consentMode===r.consentMode)||n.presentInRuns.push(r);n.likelyCategory==="unknown"&&a.likelyCategory!=="unknown"&&(n.likelyCategory=a.likelyCategory,n.likelyPurpose=a.likelyPurpose,n.classification=a.classification)}return[...t.values()].sort((o,a)=>o.signalKey.localeCompare(a.signalKey))}function ze(e){return[...new Set(e.map(t=>t.trim()).filter(Boolean))].sort((t,o)=>t.localeCompare(o))}function de(e){let t=[];for(let o of e){let a=o.trim();a&&t.push(a.includes("://")?a:`https://${a}/`)}return t}function Pt(e){return ze([...e.loadedScriptUrls??[],...e.resourceUrls??[],...de(e.resourceDomains??[]),...de(e.requestDomains??[]),...de(e.trackerDomains??[]),...de(e.scriptDomains??[])])}function Tt(e){let t=[],o=[],a=[];for(let n of e){t.push({category:n.category,likelyPurpose:n.likelyPurpose,thirdPartyDomains:n.thirdPartyDomains}),a.push(...n.thirdPartyDomains);for(let i of n.evidence??[])(i.evidenceType==="script_url"||i.evidenceType==="tracking_endpoint")&&o.push(i.value),i.evidenceType==="third_party_request_domain"&&a.push(i.value)}return{trackingTechnologies:t,resourceUrls:ze(o),thirdPartyRequestDomains:ze(a)}}function Br(e){let t=e.target.baseUrl?.trim();if(t)return t;let o=e.runtimeProfiles.find(a=>a.evidence.navigationSucceeded);return o?(o.evidence.finalUrl??o.routeUrl).trim():""}function qr(e){let t=[];for(let o of e.evidence.trackerDomains){let a=o.toLowerCase();/facebook|fbcdn|doubleclick|tiktok|snap|pixel|analytics|hotjar|clarity|segment|posthog/i.test(a)&&t.push({category:/pixel|doubleclick|facebook|tiktok|snap/i.test(a)?"social_media_pixel":"analytics",likelyPurpose:/pixel|doubleclick|facebook|tiktok/i.test(a)?"marketing":"analytics",thirdPartyDomains:[o]})}return t}function Fr(e,t){let o=t.evidence.finalUrl??t.routeUrl,a=e||o,n=t.evidence.loadedScriptUrls??[],i=Pt({loadedScriptUrls:n,resourceUrls:t.evidence.resourceUrls,resourceDomains:t.evidence.resourceDomains,scriptDomains:t.evidence.scriptDomains,requestDomains:t.evidence.requestDomains,trackerDomains:t.evidence.trackerDomains}),r=qr(t),s=Tt(r);return{targetUrl:a,pageUrls:[o],loadedScriptUrls:n,resourceUrls:[...new Set([...i,...s.resourceUrls])].sort((c,l)=>c.localeCompare(l)),thirdPartyRequestDomains:s.thirdPartyRequestDomains,trackingTechnologies:s.trackingTechnologies,scriptDomains:t.evidence.scriptDomains,requestDomains:t.evidence.requestDomains}}function Hr(e){let t=Br(e),o=e.runtimeProfiles.filter(a=>a.evidence.navigationSucceeded).map(a=>({context:{profileKey:"chromium_desktop",consentMode:a.consentMode},observation:Fr(t,a)}));return o.length===0?[]:Rt(o)}function At(e,t){let o=e.filter(r=>r.kind===t),a=o.filter(r=>r.classification==="unknown").length,n=o.filter(r=>r.presentInRuns.some(s=>s.consentMode==="none")).length,i=o.filter(r=>r.presentInRuns.some(s=>s.consentMode==="declined")&&r.classification!=="exempt_functional").length;return{total:o.length,unknown:a,seenBeforeConsent:n,remainedAfterDecline:i}}function fo(e){let t=Hr(e),o=At(t,"script"),a=At(t,"pixel"),n=At(t,"third_party_request"),i=(r,s)=>` ${r}: total=${s.total}, unknown=${s.unknown}, before_consent=${s.seenBeforeConsent}, after_decline=${s.remainedAfterDecline}`;return["Domain signals (by hostname):",i("Scripts",o),i("Pixels",a),i("Third-party requests",n)].join(`
|
|
21
|
+
`)}function Y(e,t){return t?{evidencePackage:e,securityEvidence:t}:e}function Le(e){let t=e.policyEvidence.fetched.filter(a=>a.fetched).length,o=e.runtimeProfiles.filter(a=>a.evidence.navigationSucceeded).length;return["Coverage:",` Runtime profiles: ${e.runtimeProfiles.length}`,` Runtime navigations succeeded: ${o}`,` Policy pages fetched: ${t}`,"",fo(e)].join(`
|
|
22
|
+
`)}async function ho(e,t={}){let o=t.fetch??fetch,a=t.sleep??(c=>new Promise(l=>setTimeout(l,c))),n=t.now??(()=>Date.now()),i=e.timeoutMs??6e4,r=n()+i,s=1500;for(;n()<r;){let c=await o(Vr(e.webUrl,e.statusUrl),{headers:{authorization:`Bearer ${e.bearerToken}`}});if(!c.ok){let d=await c.text().catch(()=>"");throw new Error(`Status poll failed with ${c.status}${d?`: ${d.slice(0,240)}`:""}`)}let l=await c.json();if(l.status==="ready")return{outcome:"ready",reportUrl:l.reportUrl??`${e.webUrl}/app/scans/${e.scanId}`};if(l.status==="failed")return{outcome:"failed",error:l.error??"Security grading failed."};let u=r-n();if(u<=0)break;await a(Math.min(s,u)),s=Math.min(s*2,5e3)}return{outcome:"timeout"}}function Vr(e,t){return t.startsWith("http://")||t.startsWith("https://")?t:new URL(t,e).toString()}function yo(e,t){return`Scan uploaded but grading is still in progress. Check ${e}/app/scans/${t} in a moment.`}import{createRequire as Co}from"node:module";import X from"node:path";import{fileURLToPath as Kr}from"node:url";var Ue=["accept all","allow all","agree","accept cookies","allow cookies","i accept","alle akzeptieren","akzeptieren","zustimmen","einverstanden","alle erlauben","\u043F\u0440\u0438\u043D\u044F\u0442\u044C","\u043F\u0440\u0438\u043D\u044F\u0442\u044C \u0432\u0441\u0435","\u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C","\u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C \u0432\u0441\u0435","\u0441\u043E\u0433\u043B\u0430\u0441\u0435\u043D","\u0441\u043E\u0433\u043B\u0430\u0441\u043D\u0430"],Me=["reject all","decline all","deny all","refuse all","reject cookies","decline cookies","alle ablehnen","ablehnen","verweigern","nur notwendige cookies","nur notwendige","\u043E\u0442\u043A\u043B\u043E\u043D\u0438\u0442\u044C","\u043E\u0442\u043A\u043B\u043E\u043D\u0438\u0442\u044C \u0432\u0441\u0435","\u043E\u0442\u043A\u0430\u0437\u0430\u0442\u044C","\u0437\u0430\u043F\u0440\u0435\u0442\u0438\u0442\u044C","\u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u044B\u0435","\u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0443\u0436\u043D\u044B\u0435"],jt=["settings","preferences","preference","customize","customise","manage","manage cookies","cookie settings","more options","configure","options","\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438","\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B","\u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u0438\u0437","\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435","\u043D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C"];var zt=[800,1800],Lt=1500;function F(e){if(e.consentBannerFound!=="yes"||e.consentCaptureQualityClass==="unusable"||e.consentDetectionConfidence==="low")return!1;let{acceptPresent:t,declinePresent:o,settingsPresent:a}=e.consentButtons;return t||o||a}function Ut(e){return`(() => {
|
|
23
|
+
const args = ${JSON.stringify(e)};
|
|
24
|
+
const checkBanner = args.checkBanner;
|
|
25
|
+
const acceptedModeKeywords = args.acceptedModeKeywords;
|
|
26
|
+
const declinedModeKeywords = args.declinedModeKeywords;
|
|
27
|
+
const settingsModeKeywords = args.settingsModeKeywords;
|
|
28
|
+
const interactionMatchedSelector = String(args.interactionMatchedSelector ?? "").trim();
|
|
29
|
+
|
|
30
|
+
const ROOT_PROMOTION_MAX_STEPS = 6;
|
|
31
|
+
|
|
32
|
+
const defaultRich = () => ({
|
|
33
|
+
consentBannerChecked: false,
|
|
34
|
+
consentBannerFound: "not_checked",
|
|
35
|
+
consentDetectionConfidence: "low",
|
|
36
|
+
consentBannerDetectionBasis: null,
|
|
37
|
+
consentUiOnInitialLoad: "not_checked",
|
|
38
|
+
consentButtons: { acceptPresent: false, declinePresent: false, settingsPresent: false },
|
|
39
|
+
consentBannerFullscreen: false,
|
|
40
|
+
consentBannerBlocking: false,
|
|
41
|
+
consentBannerBoundingBox: null,
|
|
42
|
+
consentBannerSelectorForCapture: null,
|
|
43
|
+
consentScreenshotCandidate: null,
|
|
44
|
+
consentCaptureQualityClass: "unusable",
|
|
45
|
+
consentCaptureQualityReasons: ["not_checked"],
|
|
46
|
+
consentUx: null,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (!checkBanner) {
|
|
50
|
+
return defaultRich();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const normalize = (value) => String(value ?? "").trim().toLowerCase().replace(/\\s+/g, " ");
|
|
54
|
+
const CONSENT_CONTAINER_SELECTOR =
|
|
55
|
+
"[id*='cookie'],[class*='cookie'],[id*='consent'],[class*='consent'],[id*='gdpr'],[class*='gdpr'],[role='dialog']";
|
|
56
|
+
const getVisibleText = (element) => {
|
|
57
|
+
const fromInner = element.innerText ?? "";
|
|
58
|
+
const fromAria = element.getAttribute("aria-label") ?? "";
|
|
59
|
+
const fromTitle = element.getAttribute("title") ?? "";
|
|
60
|
+
const fromValue =
|
|
61
|
+
element instanceof HTMLInputElement ||
|
|
62
|
+
element instanceof HTMLButtonElement ||
|
|
63
|
+
element instanceof HTMLOptionElement
|
|
64
|
+
? element.value ?? ""
|
|
65
|
+
: "";
|
|
66
|
+
return normalize([fromInner, fromAria, fromTitle, fromValue].join(" "));
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const isVisible = (element) => {
|
|
70
|
+
if (!(element instanceof HTMLElement)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const style = window.getComputedStyle(element);
|
|
74
|
+
if (style.visibility === "hidden" || style.display === "none" || parseFloat(style.opacity || "1") === 0) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const rect = element.getBoundingClientRect();
|
|
78
|
+
return rect.width > 0 && rect.height > 0;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const isInViewport = (element) => {
|
|
82
|
+
if (!(element instanceof HTMLElement)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const rect = element.getBoundingClientRect();
|
|
86
|
+
const vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
87
|
+
const vw = window.innerWidth || document.documentElement.clientWidth || 0;
|
|
88
|
+
return rect.bottom > 0 && rect.top < vh && rect.right > 0 && rect.left < vw;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const tokenMatchesBounded = (corpus, token) => {
|
|
92
|
+
if (!corpus || !token) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (token === "allow" && /not-allowed|disallowed|without-consent/.test(corpus)) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const escaped = String(token).replace(/[.*+?^\${}()|[\\]\\\\]/g, "\\\\$&");
|
|
99
|
+
return new RegExp("(^|[^a-z0-9_-])" + escaped + "([^a-z0-9_-]|$)", "i").test(corpus);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const hasAttrTokens = (attr, tokens) => tokens.some((token) => tokenMatchesBounded(attr, token));
|
|
103
|
+
|
|
104
|
+
const textMatchesKeyword = (text, keywords) =>
|
|
105
|
+
keywords.some((keyword) => {
|
|
106
|
+
const normalizedKeyword = normalize(keyword);
|
|
107
|
+
if (!normalizedKeyword) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if (text === normalizedKeyword) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return (
|
|
114
|
+
text.includes(" " + normalizedKeyword + " ") ||
|
|
115
|
+
text.startsWith(normalizedKeyword + " ") ||
|
|
116
|
+
text.endsWith(" " + normalizedKeyword)
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const isOffscreenMarketingCta = (element) => {
|
|
121
|
+
if (!(element instanceof HTMLElement) || isInViewport(element)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const text = getVisibleText(element);
|
|
125
|
+
return /(request early access|sign up|get started|join waitlist|learn more|early access)/i.test(text);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const buildAttributeCorpus = (element) => {
|
|
129
|
+
return normalize(
|
|
130
|
+
[
|
|
131
|
+
element.id ?? "",
|
|
132
|
+
element.className ?? "",
|
|
133
|
+
element.getAttribute("name") ?? "",
|
|
134
|
+
element.getAttribute("data-testid") ?? "",
|
|
135
|
+
element.getAttribute("data-test") ?? "",
|
|
136
|
+
element.getAttribute("data-qa") ?? "",
|
|
137
|
+
element.getAttribute("aria-label") ?? "",
|
|
138
|
+
element.getAttribute("role") ?? "",
|
|
139
|
+
].join(" "),
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const describeElementForBasis = (element) => {
|
|
144
|
+
const text = getVisibleText(element);
|
|
145
|
+
if (text) {
|
|
146
|
+
return text.slice(0, 80);
|
|
147
|
+
}
|
|
148
|
+
if (element.id) {
|
|
149
|
+
return "#" + element.id;
|
|
150
|
+
}
|
|
151
|
+
const className = typeof element.className === "string" ? element.className.trim() : "";
|
|
152
|
+
if (className) {
|
|
153
|
+
return className.slice(0, 80);
|
|
154
|
+
}
|
|
155
|
+
return (element.tagName || "element").toLowerCase();
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const strongConsentContextTokens = [
|
|
159
|
+
"cookie",
|
|
160
|
+
"cookies",
|
|
161
|
+
"consent",
|
|
162
|
+
"privacy",
|
|
163
|
+
"gdpr",
|
|
164
|
+
"accept",
|
|
165
|
+
"allow",
|
|
166
|
+
"agree",
|
|
167
|
+
"reject",
|
|
168
|
+
"decline",
|
|
169
|
+
"deny",
|
|
170
|
+
"necessary",
|
|
171
|
+
"essential",
|
|
172
|
+
"\u043F\u0440\u0438\u043D\u044F\u0442\u044C",
|
|
173
|
+
"\u043E\u0442\u043A\u043B\u043E\u043D\u0438\u0442\u044C",
|
|
174
|
+
"\u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C",
|
|
175
|
+
"akzeptieren",
|
|
176
|
+
"ablehnen",
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
const strongConsentPhraseMarkers = [
|
|
180
|
+
"cookie",
|
|
181
|
+
"cookies",
|
|
182
|
+
"consent",
|
|
183
|
+
"privacy",
|
|
184
|
+
"gdpr",
|
|
185
|
+
"\u043A\u0443\u043A\u0438",
|
|
186
|
+
"\u0441\u043E\u0433\u043B\u0430\u0441",
|
|
187
|
+
"einwill",
|
|
188
|
+
];
|
|
189
|
+
const hasStrongConsentPhrase = (phrase) => {
|
|
190
|
+
const normalizedPhrase = normalize(phrase);
|
|
191
|
+
if (!normalizedPhrase) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return strongConsentPhraseMarkers.some((marker) => normalizedPhrase.includes(marker));
|
|
195
|
+
};
|
|
196
|
+
const settingsBannerSeedKeywords = settingsModeKeywords.filter((keyword) =>
|
|
197
|
+
hasStrongConsentPhrase(keyword),
|
|
198
|
+
);
|
|
199
|
+
const keywordBannerTokens = [
|
|
200
|
+
...new Set([
|
|
201
|
+
...acceptedModeKeywords,
|
|
202
|
+
...declinedModeKeywords,
|
|
203
|
+
...settingsBannerSeedKeywords,
|
|
204
|
+
...strongConsentContextTokens,
|
|
205
|
+
]),
|
|
206
|
+
];
|
|
207
|
+
|
|
208
|
+
const hasConsentContext = (element) => {
|
|
209
|
+
const contexts = [element];
|
|
210
|
+
if (element.parentElement) {
|
|
211
|
+
contexts.push(element.parentElement);
|
|
212
|
+
}
|
|
213
|
+
const closestConsentContainer = element.closest(CONSENT_CONTAINER_SELECTOR);
|
|
214
|
+
if (closestConsentContainer) {
|
|
215
|
+
contexts.push(closestConsentContainer);
|
|
216
|
+
}
|
|
217
|
+
for (const ctx of contexts) {
|
|
218
|
+
const contextText = getVisibleText(ctx);
|
|
219
|
+
const contextAttributes = buildAttributeCorpus(ctx);
|
|
220
|
+
if (
|
|
221
|
+
strongConsentContextTokens.some(
|
|
222
|
+
(token) => contextText.includes(token) || contextAttributes.includes(token),
|
|
223
|
+
)
|
|
224
|
+
) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return false;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const hasStrongConsentContext = hasConsentContext;
|
|
232
|
+
|
|
233
|
+
const genericBannerSelectors = [
|
|
234
|
+
"#onetrust-banner-sdk",
|
|
235
|
+
"#onetrust-consent-sdk",
|
|
236
|
+
"#CybotCookiebotDialog",
|
|
237
|
+
"#didomi-host",
|
|
238
|
+
"[id*='cookie-banner']",
|
|
239
|
+
"[class*='cookie-banner']",
|
|
240
|
+
"[id*='cookie-consent']",
|
|
241
|
+
"[class*='cookie-consent']",
|
|
242
|
+
"[id*='consent-banner']",
|
|
243
|
+
"[class*='consent-banner']",
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
const candidates = Array.from(
|
|
247
|
+
document.querySelectorAll(
|
|
248
|
+
"button, [role='button'], input[type='button'], input[type='submit'], a[role='button'], a[href]",
|
|
249
|
+
),
|
|
250
|
+
);
|
|
251
|
+
const actionControlSelector =
|
|
252
|
+
"button, [role='button'], input[type='button'], input[type='submit'], a[role='button'], a[href]";
|
|
253
|
+
|
|
254
|
+
const compactSelector = (element) => {
|
|
255
|
+
if (!(element instanceof Element)) {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
if (element.id) {
|
|
259
|
+
return "#" + element.id;
|
|
260
|
+
}
|
|
261
|
+
const tag = element.tagName.toLowerCase();
|
|
262
|
+
const className =
|
|
263
|
+
typeof element.className === "string"
|
|
264
|
+
? element.className
|
|
265
|
+
.split(/\\s+/)
|
|
266
|
+
.filter(Boolean)
|
|
267
|
+
.slice(0, 2)
|
|
268
|
+
.join(".")
|
|
269
|
+
: "";
|
|
270
|
+
if (className) {
|
|
271
|
+
return tag + "." + className;
|
|
272
|
+
}
|
|
273
|
+
const parent = element.parentElement;
|
|
274
|
+
if (!parent) {
|
|
275
|
+
return tag;
|
|
276
|
+
}
|
|
277
|
+
const siblings = Array.from(parent.children).filter(
|
|
278
|
+
(node) => node.tagName.toLowerCase() === tag,
|
|
279
|
+
);
|
|
280
|
+
if (siblings.length <= 1) {
|
|
281
|
+
return tag;
|
|
282
|
+
}
|
|
283
|
+
const index = siblings.indexOf(element) + 1;
|
|
284
|
+
return tag + ":nth-of-type(" + String(index) + ")";
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const hasValidRootBoundingBox = (root) => {
|
|
288
|
+
if (!(root instanceof HTMLElement)) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
const rect = root.getBoundingClientRect();
|
|
292
|
+
return (
|
|
293
|
+
Number.isFinite(rect.x) &&
|
|
294
|
+
Number.isFinite(rect.y) &&
|
|
295
|
+
Number.isFinite(rect.width) &&
|
|
296
|
+
Number.isFinite(rect.height) &&
|
|
297
|
+
rect.width > 1 &&
|
|
298
|
+
rect.height > 1
|
|
299
|
+
);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const hasActionableControls = (root) => {
|
|
303
|
+
if (!(root instanceof HTMLElement)) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
const actionNodes = Array.from(root.querySelectorAll(actionControlSelector));
|
|
307
|
+
if (
|
|
308
|
+
root.matches("button, [role='button'], input[type='button'], input[type='submit']") &&
|
|
309
|
+
isVisible(root)
|
|
310
|
+
) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
for (const node of actionNodes) {
|
|
314
|
+
if (!(node instanceof HTMLElement) || !isVisible(node)) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (isNavigationalAnchor(node) && node.getAttribute("role") !== "button") {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
return false;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const ROOT_PROMOTION_MIN_SCORE_DELTA = 6;
|
|
326
|
+
const ROOT_PROMOTION_MIN_AREA_MULTIPLIER = 1.6;
|
|
327
|
+
const ROOT_PROMOTION_MIN_ABSOLUTE_AREA = 20000;
|
|
328
|
+
const ROOT_PROMOTION_MAX_BROAD_WIDTH_RATIO = 0.985;
|
|
329
|
+
const ROOT_PROMOTION_MAX_BROAD_HEIGHT_RATIO = 0.82;
|
|
330
|
+
|
|
331
|
+
const countVisibleActionableControls = (root) => {
|
|
332
|
+
if (!(root instanceof HTMLElement)) {
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
let count = 0;
|
|
336
|
+
if (
|
|
337
|
+
root.matches("button, [role='button'], input[type='button'], input[type='submit']") &&
|
|
338
|
+
isVisible(root) &&
|
|
339
|
+
!isNavigationalAnchor(root)
|
|
340
|
+
) {
|
|
341
|
+
count += 1;
|
|
342
|
+
}
|
|
343
|
+
for (const node of root.querySelectorAll(actionControlSelector)) {
|
|
344
|
+
if (!(node instanceof HTMLElement) || !isVisible(node)) {
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (isNavigationalAnchor(node) && node.getAttribute("role") !== "button") {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
count += 1;
|
|
351
|
+
}
|
|
352
|
+
return count;
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const hasConsentActionPair = (root) => {
|
|
356
|
+
if (!(root instanceof HTMLElement)) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
let hasAccept = false;
|
|
360
|
+
let hasDecline = false;
|
|
361
|
+
for (const node of root.querySelectorAll(actionControlSelector)) {
|
|
362
|
+
if (!(node instanceof HTMLElement) || !isVisible(node)) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (isNavigationalAnchor(node) && node.getAttribute("role") !== "button") {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
const text = getVisibleText(node);
|
|
369
|
+
const attr = buildAttributeCorpus(node);
|
|
370
|
+
if (
|
|
371
|
+
textMatchesKeyword(text, acceptedModeKeywords) ||
|
|
372
|
+
hasAttrTokens(attr, ["accept", "agree", "optin", "allow"])
|
|
373
|
+
) {
|
|
374
|
+
hasAccept = true;
|
|
375
|
+
}
|
|
376
|
+
if (
|
|
377
|
+
textMatchesKeyword(text, declinedModeKeywords) ||
|
|
378
|
+
hasAttrTokens(attr, ["reject", "decline", "deny", "disagree", "refuse", "optout", "necessary", "essential"])
|
|
379
|
+
) {
|
|
380
|
+
hasDecline = true;
|
|
381
|
+
}
|
|
382
|
+
if (hasAccept && hasDecline) {
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return false;
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
const findConsentAncestor = (element) => {
|
|
390
|
+
let current = element;
|
|
391
|
+
for (let step = 0; step < ROOT_PROMOTION_MAX_STEPS && current; step += 1) {
|
|
392
|
+
if (!(current instanceof HTMLElement)) {
|
|
393
|
+
current = current.parentElement;
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
const style = window.getComputedStyle(current);
|
|
397
|
+
const rect = current.getBoundingClientRect();
|
|
398
|
+
const anchoredBottom =
|
|
399
|
+
(style.position === "fixed" || style.position === "sticky") &&
|
|
400
|
+
Math.abs(window.innerHeight - (rect.y + rect.height)) <= 24;
|
|
401
|
+
const actionCount = countVisibleActionableControls(current);
|
|
402
|
+
if (anchoredBottom && actionCount >= 2 && isVisible(current)) {
|
|
403
|
+
return current;
|
|
404
|
+
}
|
|
405
|
+
if (current.matches(CONSENT_CONTAINER_SELECTOR) && hasActionableControls(current)) {
|
|
406
|
+
return current;
|
|
407
|
+
}
|
|
408
|
+
current = current.parentElement;
|
|
409
|
+
}
|
|
410
|
+
const container = element.closest(CONSENT_CONTAINER_SELECTOR);
|
|
411
|
+
return container instanceof HTMLElement ? container : element;
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
const isControlLikeRoot = (root) =>
|
|
415
|
+
root.matches("button, [role='button'], input[type='button'], input[type='submit'], a[role='button'], a[href]");
|
|
416
|
+
|
|
417
|
+
const appendBasis = (basis, marker) => {
|
|
418
|
+
if (!marker) {
|
|
419
|
+
return basis;
|
|
420
|
+
}
|
|
421
|
+
if (!basis) {
|
|
422
|
+
return marker;
|
|
423
|
+
}
|
|
424
|
+
if (basis.includes(marker)) {
|
|
425
|
+
return basis;
|
|
426
|
+
}
|
|
427
|
+
return basis + "; " + marker;
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
const evaluateRootCandidate = ({ root, basis, standaloneNavigationalLink }) => {
|
|
431
|
+
const rect = root.getBoundingClientRect();
|
|
432
|
+
const area = Number.isFinite(rect.width) && Number.isFinite(rect.height) ? rect.width * rect.height : 0;
|
|
433
|
+
const actionable = hasActionableControls(root);
|
|
434
|
+
const visible = isVisible(root);
|
|
435
|
+
const widthRatio = window.innerWidth > 0 ? rect.width / window.innerWidth : 0;
|
|
436
|
+
const heightRatio = window.innerHeight > 0 ? rect.height / window.innerHeight : 0;
|
|
437
|
+
let score = 0;
|
|
438
|
+
if (visible) {
|
|
439
|
+
score += 20;
|
|
440
|
+
}
|
|
441
|
+
if (hasValidRootBoundingBox(root)) {
|
|
442
|
+
score += 20;
|
|
443
|
+
}
|
|
444
|
+
if (actionable) {
|
|
445
|
+
score += 40;
|
|
446
|
+
}
|
|
447
|
+
if (hasConsentContext(root)) {
|
|
448
|
+
score += 15;
|
|
449
|
+
}
|
|
450
|
+
if (root.getAttribute("role") === "dialog") {
|
|
451
|
+
score += 20;
|
|
452
|
+
}
|
|
453
|
+
if (standaloneNavigationalLink) {
|
|
454
|
+
score -= 100;
|
|
455
|
+
}
|
|
456
|
+
if (root.tagName.toLowerCase() === "a" && root.getAttribute("role") !== "button") {
|
|
457
|
+
score -= 55;
|
|
458
|
+
}
|
|
459
|
+
if (area >= 2500) {
|
|
460
|
+
score += 5;
|
|
461
|
+
}
|
|
462
|
+
if (area >= 20000) {
|
|
463
|
+
score += 5;
|
|
464
|
+
}
|
|
465
|
+
if (widthRatio >= ROOT_PROMOTION_MAX_BROAD_WIDTH_RATIO && heightRatio >= ROOT_PROMOTION_MAX_BROAD_HEIGHT_RATIO) {
|
|
466
|
+
score -= 20;
|
|
467
|
+
}
|
|
468
|
+
return {
|
|
469
|
+
root,
|
|
470
|
+
basis,
|
|
471
|
+
score,
|
|
472
|
+
area,
|
|
473
|
+
standaloneNavigationalLink,
|
|
474
|
+
hasActionableControls: actionable,
|
|
475
|
+
};
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const rankPromotionCandidate = ({ candidateRoot, originalArea }) => {
|
|
479
|
+
const rect = candidateRoot.getBoundingClientRect();
|
|
480
|
+
if (!(Number.isFinite(rect.width) && Number.isFinite(rect.height) && rect.width > 1 && rect.height > 1)) {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
const area = rect.width * rect.height;
|
|
484
|
+
const widthRatio = window.innerWidth > 0 ? rect.width / window.innerWidth : 0;
|
|
485
|
+
const heightRatio = window.innerHeight > 0 ? rect.height / window.innerHeight : 0;
|
|
486
|
+
const actionCount = countVisibleActionableControls(candidateRoot);
|
|
487
|
+
const hasPair = hasConsentActionPair(candidateRoot);
|
|
488
|
+
const text = getVisibleText(candidateRoot);
|
|
489
|
+
const attr = buildAttributeCorpus(candidateRoot);
|
|
490
|
+
const consentHits = strongConsentContextTokens.filter(
|
|
491
|
+
(token) => text.includes(token) || attr.includes(token),
|
|
492
|
+
).length;
|
|
493
|
+
const areaScale = Math.max(1, area / 10000);
|
|
494
|
+
const actionDensity = actionCount / areaScale;
|
|
495
|
+
const consentDensity = consentHits / areaScale;
|
|
496
|
+
const viewportArea = Math.max(1, window.innerWidth * window.innerHeight);
|
|
497
|
+
const style = window.getComputedStyle(candidateRoot);
|
|
498
|
+
const anchoredBottom =
|
|
499
|
+
(style.position === "fixed" || style.position === "sticky") &&
|
|
500
|
+
Math.abs(window.innerHeight - (rect.y + rect.height)) <= 16;
|
|
501
|
+
const topBroad = rect.y <= window.innerHeight * 0.08 && heightRatio >= 0.6;
|
|
502
|
+
const broadShellLike = widthRatio >= ROOT_PROMOTION_MAX_BROAD_WIDTH_RATIO && heightRatio >= ROOT_PROMOTION_MAX_BROAD_HEIGHT_RATIO;
|
|
503
|
+
|
|
504
|
+
let score = 0;
|
|
505
|
+
score += 24;
|
|
506
|
+
if (hasConsentContext(candidateRoot)) {
|
|
507
|
+
score += 18;
|
|
508
|
+
}
|
|
509
|
+
if (actionCount >= 2) {
|
|
510
|
+
score += 18;
|
|
511
|
+
} else if (actionCount === 1) {
|
|
512
|
+
score += 8;
|
|
513
|
+
}
|
|
514
|
+
if (hasPair) {
|
|
515
|
+
score += 22;
|
|
516
|
+
}
|
|
517
|
+
if (anchoredBottom) {
|
|
518
|
+
score += 12;
|
|
519
|
+
}
|
|
520
|
+
if (area >= 30000 && area <= viewportArea * 0.45) {
|
|
521
|
+
score += 10;
|
|
522
|
+
}
|
|
523
|
+
if (consentHits >= 2) {
|
|
524
|
+
score += 12;
|
|
525
|
+
} else if (consentHits === 1) {
|
|
526
|
+
score += 6;
|
|
527
|
+
}
|
|
528
|
+
if (area < ROOT_PROMOTION_MIN_ABSOLUTE_AREA) {
|
|
529
|
+
score -= 16;
|
|
530
|
+
}
|
|
531
|
+
if (actionCount >= 2 && area < ROOT_PROMOTION_MIN_ABSOLUTE_AREA) {
|
|
532
|
+
score -= 10;
|
|
533
|
+
}
|
|
534
|
+
if (actionDensity < 0.35) {
|
|
535
|
+
score -= 14;
|
|
536
|
+
}
|
|
537
|
+
if (consentDensity < 0.08) {
|
|
538
|
+
score -= 12;
|
|
539
|
+
}
|
|
540
|
+
if (topBroad) {
|
|
541
|
+
score -= 24;
|
|
542
|
+
}
|
|
543
|
+
if (broadShellLike) {
|
|
544
|
+
score -= 24;
|
|
545
|
+
}
|
|
546
|
+
if (candidateRoot === document.body || candidateRoot === document.documentElement) {
|
|
547
|
+
score -= 36;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
const areaMultiplier = area / Math.max(1, originalArea);
|
|
551
|
+
const role = candidateRoot.getAttribute("role");
|
|
552
|
+
const hasModalHint = role === "dialog" || candidateRoot.getAttribute("aria-modal") === "true";
|
|
553
|
+
const rejectOverbroad = broadShellLike && !hasModalHint;
|
|
554
|
+
return {
|
|
555
|
+
node: candidateRoot,
|
|
556
|
+
score,
|
|
557
|
+
area,
|
|
558
|
+
areaMultiplier,
|
|
559
|
+
rejectOverbroad,
|
|
560
|
+
hasModalHint,
|
|
561
|
+
};
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
const promoteRootCandidate = (candidate) => {
|
|
565
|
+
const rect = candidate.root.getBoundingClientRect();
|
|
566
|
+
const originalArea = Number.isFinite(rect.width) && Number.isFinite(rect.height) ? rect.width * rect.height : 0;
|
|
567
|
+
const shouldAttemptPromotion =
|
|
568
|
+
isControlLikeRoot(candidate.root) || originalArea < window.innerWidth * window.innerHeight * 0.12;
|
|
569
|
+
if (!shouldAttemptPromotion) {
|
|
570
|
+
return candidate;
|
|
571
|
+
}
|
|
572
|
+
let best = null;
|
|
573
|
+
let current = candidate.root.parentElement;
|
|
574
|
+
let step = 0;
|
|
575
|
+
while (current && step < ROOT_PROMOTION_MAX_STEPS) {
|
|
576
|
+
const ranked = rankPromotionCandidate({ candidateRoot: current, originalArea });
|
|
577
|
+
if (ranked) {
|
|
578
|
+
if (!best || ranked.score > best.score || (ranked.score === best.score && ranked.area > best.area)) {
|
|
579
|
+
best = ranked;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if (current === document.body) {
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
current = current.parentElement;
|
|
586
|
+
step += 1;
|
|
587
|
+
}
|
|
588
|
+
if (!best) {
|
|
589
|
+
return candidate;
|
|
590
|
+
}
|
|
591
|
+
const basePromotionRank = rankPromotionCandidate({
|
|
592
|
+
candidateRoot: candidate.root,
|
|
593
|
+
originalArea,
|
|
594
|
+
});
|
|
595
|
+
const basePromotionScore = basePromotionRank ? basePromotionRank.score : 0;
|
|
596
|
+
if (best.rejectOverbroad) {
|
|
597
|
+
return candidate;
|
|
598
|
+
}
|
|
599
|
+
if (best.area < ROOT_PROMOTION_MIN_ABSOLUTE_AREA && !best.hasModalHint) {
|
|
600
|
+
return candidate;
|
|
601
|
+
}
|
|
602
|
+
if (best.areaMultiplier < ROOT_PROMOTION_MIN_AREA_MULTIPLIER) {
|
|
603
|
+
return candidate;
|
|
604
|
+
}
|
|
605
|
+
if (best.score - basePromotionScore < ROOT_PROMOTION_MIN_SCORE_DELTA) {
|
|
606
|
+
return candidate;
|
|
607
|
+
}
|
|
608
|
+
return evaluateRootCandidate({
|
|
609
|
+
root: best.node,
|
|
610
|
+
basis: appendBasis(
|
|
611
|
+
appendBasis(candidate.basis, "ancestor_promotion_applied"),
|
|
612
|
+
"ancestor_promotion_target:" + (compactSelector(best.node) || "unknown"),
|
|
613
|
+
),
|
|
614
|
+
standaloneNavigationalLink: false,
|
|
615
|
+
});
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const findBannerRoot = () => {
|
|
619
|
+
if (interactionMatchedSelector) {
|
|
620
|
+
try {
|
|
621
|
+
const interactionTarget = document.querySelector(interactionMatchedSelector);
|
|
622
|
+
if (interactionTarget instanceof HTMLElement) {
|
|
623
|
+
const forcedContainer = interactionTarget.closest(CONSENT_CONTAINER_SELECTOR);
|
|
624
|
+
const forcedRoot =
|
|
625
|
+
forcedContainer instanceof HTMLElement ? forcedContainer : interactionTarget;
|
|
626
|
+
return evaluateRootCandidate({
|
|
627
|
+
root: forcedRoot,
|
|
628
|
+
basis: "interaction target ancestry: " + interactionMatchedSelector,
|
|
629
|
+
standaloneNavigationalLink:
|
|
630
|
+
forcedRoot === interactionTarget && isNavigationalAnchor(interactionTarget),
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
} catch (_e) {}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
for (const selector of genericBannerSelectors) {
|
|
637
|
+
const el = document.querySelector(selector);
|
|
638
|
+
if (el instanceof HTMLElement) {
|
|
639
|
+
return evaluateRootCandidate({
|
|
640
|
+
root: el,
|
|
641
|
+
basis: "matched selector: " + selector,
|
|
642
|
+
standaloneNavigationalLink: false,
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
const dialogs = Array.from(document.querySelectorAll('[role="dialog"]'));
|
|
647
|
+
for (const d of dialogs) {
|
|
648
|
+
if (!(d instanceof HTMLElement) || !isVisible(d)) {
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (!hasConsentContext(d)) {
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
return evaluateRootCandidate({
|
|
655
|
+
root: d,
|
|
656
|
+
basis: "role=dialog consent context",
|
|
657
|
+
standaloneNavigationalLink: false,
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
const ranked = [];
|
|
661
|
+
for (const element of candidates) {
|
|
662
|
+
if (!(element instanceof HTMLElement)) {
|
|
663
|
+
continue;
|
|
664
|
+
}
|
|
665
|
+
const text = getVisibleText(element);
|
|
666
|
+
const attributeCorpus = buildAttributeCorpus(element);
|
|
667
|
+
const matchedToken = keywordBannerTokens.find(
|
|
668
|
+
(token) => tokenMatchesBounded(text, token) || tokenMatchesBounded(attributeCorpus, token),
|
|
669
|
+
);
|
|
670
|
+
if (!matchedToken) {
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
if (isOffscreenMarketingCta(element)) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
const root = findConsentAncestor(element);
|
|
677
|
+
const standaloneNavigationalLink = root === element && isNavigationalAnchor(element);
|
|
678
|
+
if (standaloneNavigationalLink && !isInViewport(element)) {
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
ranked.push(evaluateRootCandidate({
|
|
682
|
+
root,
|
|
683
|
+
basis: "keyword/attribute match: " + describeElementForBasis(element),
|
|
684
|
+
standaloneNavigationalLink,
|
|
685
|
+
}));
|
|
686
|
+
}
|
|
687
|
+
ranked.sort((a, b) => {
|
|
688
|
+
if (a.score !== b.score) {
|
|
689
|
+
return b.score - a.score;
|
|
690
|
+
}
|
|
691
|
+
return b.area - a.area;
|
|
692
|
+
});
|
|
693
|
+
if (ranked.length > 0) {
|
|
694
|
+
return promoteRootCandidate(ranked[0]);
|
|
695
|
+
}
|
|
696
|
+
return null;
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
const isNavigationalAnchor = (element) => {
|
|
700
|
+
if (!(element instanceof HTMLAnchorElement)) {
|
|
701
|
+
return false;
|
|
702
|
+
}
|
|
703
|
+
const href = (element.getAttribute("href") ?? "").trim();
|
|
704
|
+
if (!href) {
|
|
705
|
+
return false;
|
|
706
|
+
}
|
|
707
|
+
const normalizedHref = href.toLowerCase();
|
|
708
|
+
if (
|
|
709
|
+
normalizedHref.startsWith("#") ||
|
|
710
|
+
normalizedHref.startsWith("javascript:") ||
|
|
711
|
+
normalizedHref === "about:blank"
|
|
712
|
+
) {
|
|
713
|
+
return false;
|
|
714
|
+
}
|
|
715
|
+
return true;
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
const acceptAttrTokens = ["accept", "agree", "allow", "consent", "optin"];
|
|
719
|
+
const declineAttrTokens = ["reject", "decline", "deny", "disagree", "refuse", "optout", "necessary", "essential"];
|
|
720
|
+
const settingsAttrTokens = ["setting", "preference", "preferences", "customize", "manage", "configure", "options"];
|
|
721
|
+
|
|
722
|
+
const acceptVendorSelectors = [
|
|
723
|
+
"#onetrust-accept-btn-handler",
|
|
724
|
+
"#didomi-notice-agree-button",
|
|
725
|
+
"#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll",
|
|
726
|
+
".cmplz-accept",
|
|
727
|
+
".iubenda-cs-accept-btn",
|
|
728
|
+
];
|
|
729
|
+
const declineVendorSelectors = [
|
|
730
|
+
"#onetrust-reject-all-handler",
|
|
731
|
+
"#didomi-notice-disagree-button",
|
|
732
|
+
"#CybotCookiebotDialogBodyButtonDecline",
|
|
733
|
+
".cmplz-deny",
|
|
734
|
+
".cmplz-decline",
|
|
735
|
+
".iubenda-cs-reject-btn",
|
|
736
|
+
];
|
|
737
|
+
|
|
738
|
+
const wallPhrases = [
|
|
739
|
+
"cookie wall",
|
|
740
|
+
"must accept all cookies",
|
|
741
|
+
"cannot use this website without",
|
|
742
|
+
"cannot access this website without",
|
|
743
|
+
"access denied until",
|
|
744
|
+
"you must agree to",
|
|
745
|
+
"\u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C \u0431\u0435\u0437",
|
|
746
|
+
"\u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u044F \u043D\u0430 \u0432\u0441\u0435",
|
|
747
|
+
"ohne akzeptieren",
|
|
748
|
+
"ohne zustimmung",
|
|
749
|
+
"nur nach zustimmung",
|
|
750
|
+
"m\xFCssen sie alle cookies akzeptieren",
|
|
751
|
+
];
|
|
752
|
+
|
|
753
|
+
const dismissTokens = [
|
|
754
|
+
"close",
|
|
755
|
+
"dismiss",
|
|
756
|
+
"skip",
|
|
757
|
+
"continue without accepting",
|
|
758
|
+
"only necessary",
|
|
759
|
+
"essential only",
|
|
760
|
+
"\u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u044B\u0435",
|
|
761
|
+
"\u0437\u0430\u043A\u0440\u044B\u0442\u044C",
|
|
762
|
+
"\u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C \u0431\u0435\u0437 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u044F",
|
|
763
|
+
"ohne zustimmung fortfahren",
|
|
764
|
+
"nur notwendige",
|
|
765
|
+
"schlie\xDFen",
|
|
766
|
+
];
|
|
767
|
+
|
|
768
|
+
const detectWallPhrases = (text) => wallPhrases.some((phrase) => text.includes(phrase));
|
|
769
|
+
|
|
770
|
+
const isEnabled = (element) => {
|
|
771
|
+
if (!(element instanceof HTMLElement)) {
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
774
|
+
if (element.getAttribute("aria-disabled") === "true") {
|
|
775
|
+
return false;
|
|
776
|
+
}
|
|
777
|
+
if (element instanceof HTMLButtonElement || element instanceof HTMLInputElement) {
|
|
778
|
+
return !element.disabled;
|
|
779
|
+
}
|
|
780
|
+
return true;
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
const controlMetricsFromElement = (element) => {
|
|
784
|
+
if (!(element instanceof HTMLElement)) {
|
|
785
|
+
return null;
|
|
786
|
+
}
|
|
787
|
+
const rect = element.getBoundingClientRect();
|
|
788
|
+
const width = Number.isFinite(rect.width) ? Math.max(0, rect.width) : 0;
|
|
789
|
+
const height = Number.isFinite(rect.height) ? Math.max(0, rect.height) : 0;
|
|
790
|
+
return {
|
|
791
|
+
selector: compactSelector(element),
|
|
792
|
+
label: (getVisibleText(element) || null),
|
|
793
|
+
visible: isVisible(element),
|
|
794
|
+
enabled: isEnabled(element),
|
|
795
|
+
x: Number.isFinite(rect.x) ? rect.x : 0,
|
|
796
|
+
y: Number.isFinite(rect.y) ? rect.y : 0,
|
|
797
|
+
width,
|
|
798
|
+
height,
|
|
799
|
+
area: width * height,
|
|
800
|
+
};
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
const hasKeyword = (text, attr, keywords, attrTokens) =>
|
|
804
|
+
textMatchesKeyword(text, keywords) || hasAttrTokens(attr, attrTokens);
|
|
805
|
+
|
|
806
|
+
const pickBestControl = (nodes, predicates) => {
|
|
807
|
+
const candidates = [];
|
|
808
|
+
for (const element of nodes) {
|
|
809
|
+
if (!(element instanceof HTMLElement) || isNavigationalAnchor(element)) {
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
const text = getVisibleText(element);
|
|
813
|
+
const attr = buildAttributeCorpus(element);
|
|
814
|
+
if (!predicates(text, attr)) {
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
const metrics = controlMetricsFromElement(element);
|
|
818
|
+
if (!metrics) {
|
|
819
|
+
continue;
|
|
820
|
+
}
|
|
821
|
+
candidates.push(metrics);
|
|
822
|
+
}
|
|
823
|
+
if (candidates.length === 0) {
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
candidates.sort((a, b) => {
|
|
827
|
+
const aInViewport = a.visible && a.y >= 0 && a.y < (window.innerHeight || 0);
|
|
828
|
+
const bInViewport = b.visible && b.y >= 0 && b.y < (window.innerHeight || 0);
|
|
829
|
+
if (aInViewport !== bInViewport) {
|
|
830
|
+
return aInViewport ? -1 : 1;
|
|
831
|
+
}
|
|
832
|
+
if (a.visible !== b.visible) {
|
|
833
|
+
return a.visible ? -1 : 1;
|
|
834
|
+
}
|
|
835
|
+
if (a.enabled !== b.enabled) {
|
|
836
|
+
return a.enabled ? -1 : 1;
|
|
837
|
+
}
|
|
838
|
+
return b.area - a.area;
|
|
839
|
+
});
|
|
840
|
+
return candidates[0];
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
const detectDismissWithoutConsent = (root, actionNodes) => {
|
|
844
|
+
const closeSelectors = [
|
|
845
|
+
"[aria-label*='close']",
|
|
846
|
+
"[class*='close']",
|
|
847
|
+
"[id*='close']",
|
|
848
|
+
"[data-testid*='close']",
|
|
849
|
+
];
|
|
850
|
+
for (const sel of closeSelectors) {
|
|
851
|
+
try {
|
|
852
|
+
const hit = root.querySelector(sel);
|
|
853
|
+
if (hit instanceof HTMLElement && isVisible(hit)) {
|
|
854
|
+
return true;
|
|
855
|
+
}
|
|
856
|
+
} catch (_e) {}
|
|
857
|
+
}
|
|
858
|
+
for (const element of actionNodes) {
|
|
859
|
+
if (!(element instanceof HTMLElement) || !isVisible(element)) {
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
const text = getVisibleText(element);
|
|
863
|
+
const attr = buildAttributeCorpus(element);
|
|
864
|
+
if (dismissTokens.some((token) => text.includes(token) || attr.includes(token))) {
|
|
865
|
+
return true;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return false;
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
const detectButtons = (root) => {
|
|
872
|
+
let acceptPresent = false;
|
|
873
|
+
let declinePresent = false;
|
|
874
|
+
let settingsPresent = false;
|
|
875
|
+
let acceptMetrics = null;
|
|
876
|
+
let declineMetrics = null;
|
|
877
|
+
let settingsMetrics = null;
|
|
878
|
+
for (const sel of acceptVendorSelectors) {
|
|
879
|
+
try {
|
|
880
|
+
const hit = root.querySelector(sel);
|
|
881
|
+
if (hit instanceof HTMLElement) {
|
|
882
|
+
const metrics = controlMetricsFromElement(hit);
|
|
883
|
+
if (metrics) {
|
|
884
|
+
acceptMetrics = acceptMetrics ?? metrics;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
if (hit instanceof HTMLElement && isVisible(hit)) {
|
|
888
|
+
acceptPresent = true;
|
|
889
|
+
}
|
|
890
|
+
} catch (_e) {}
|
|
891
|
+
}
|
|
892
|
+
for (const sel of declineVendorSelectors) {
|
|
893
|
+
try {
|
|
894
|
+
const hit = root.querySelector(sel);
|
|
895
|
+
if (hit instanceof HTMLElement) {
|
|
896
|
+
const metrics = controlMetricsFromElement(hit);
|
|
897
|
+
if (metrics) {
|
|
898
|
+
declineMetrics = declineMetrics ?? metrics;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
if (hit instanceof HTMLElement && isVisible(hit)) {
|
|
902
|
+
declinePresent = true;
|
|
903
|
+
}
|
|
904
|
+
} catch (_e) {}
|
|
905
|
+
}
|
|
906
|
+
const actionNodes = Array.from(
|
|
907
|
+
root.querySelectorAll(
|
|
908
|
+
"button, [role='button'], input[type='button'], input[type='submit'], a[role='button'], a[href]",
|
|
909
|
+
),
|
|
910
|
+
);
|
|
911
|
+
for (const el of actionNodes) {
|
|
912
|
+
if (!(el instanceof HTMLElement) || !isVisible(el)) {
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
if (isNavigationalAnchor(el)) {
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
const text = getVisibleText(el);
|
|
919
|
+
const attr = buildAttributeCorpus(el);
|
|
920
|
+
if (hasKeyword(text, attr, acceptedModeKeywords, acceptAttrTokens)) {
|
|
921
|
+
acceptPresent = true;
|
|
922
|
+
}
|
|
923
|
+
if (hasKeyword(text, attr, declinedModeKeywords, declineAttrTokens)) {
|
|
924
|
+
declinePresent = true;
|
|
925
|
+
}
|
|
926
|
+
if (hasKeyword(text, attr, settingsModeKeywords, settingsAttrTokens)) {
|
|
927
|
+
settingsPresent = true;
|
|
928
|
+
}
|
|
929
|
+
if (hasConsentContext(root)) {
|
|
930
|
+
if (
|
|
931
|
+
text.includes("preference") ||
|
|
932
|
+
text.includes("customize") ||
|
|
933
|
+
text.includes("customise") ||
|
|
934
|
+
text.includes("manage") ||
|
|
935
|
+
attr.includes("preference") ||
|
|
936
|
+
attr.includes("customize") ||
|
|
937
|
+
attr.includes("manage")
|
|
938
|
+
) {
|
|
939
|
+
settingsPresent = true;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (!acceptMetrics) {
|
|
944
|
+
acceptMetrics = pickBestControl(actionNodes, (text, attr) =>
|
|
945
|
+
hasKeyword(text, attr, acceptedModeKeywords, acceptAttrTokens),
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
if (!declineMetrics) {
|
|
949
|
+
declineMetrics = pickBestControl(actionNodes, (text, attr) =>
|
|
950
|
+
hasKeyword(text, attr, declinedModeKeywords, declineAttrTokens),
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
settingsMetrics = pickBestControl(actionNodes, (text, attr) => {
|
|
954
|
+
if (hasKeyword(text, attr, settingsModeKeywords, settingsAttrTokens)) {
|
|
955
|
+
return true;
|
|
956
|
+
}
|
|
957
|
+
if (!hasConsentContext(root)) {
|
|
958
|
+
return false;
|
|
959
|
+
}
|
|
960
|
+
return (
|
|
961
|
+
text.includes("preference") ||
|
|
962
|
+
text.includes("customize") ||
|
|
963
|
+
text.includes("customise") ||
|
|
964
|
+
text.includes("manage") ||
|
|
965
|
+
attr.includes("preference") ||
|
|
966
|
+
attr.includes("customize") ||
|
|
967
|
+
attr.includes("manage")
|
|
968
|
+
);
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
const bannerTextSnippetRaw = getVisibleText(root).slice(0, 240);
|
|
972
|
+
const wallPhrasesDetected = detectWallPhrases(bannerTextSnippetRaw);
|
|
973
|
+
const dismissWithoutConsentPresent = detectDismissWithoutConsent(root, actionNodes);
|
|
974
|
+
return {
|
|
975
|
+
acceptPresent,
|
|
976
|
+
declinePresent,
|
|
977
|
+
settingsPresent,
|
|
978
|
+
consentUx: {
|
|
979
|
+
bannerTextSnippet: bannerTextSnippetRaw || null,
|
|
980
|
+
wallPhrasesDetected,
|
|
981
|
+
dismissWithoutConsentPresent,
|
|
982
|
+
acceptMetrics,
|
|
983
|
+
declineMetrics,
|
|
984
|
+
settingsMetrics,
|
|
985
|
+
},
|
|
986
|
+
};
|
|
987
|
+
};
|
|
988
|
+
|
|
989
|
+
const computeBlocking = (root) => {
|
|
990
|
+
const html = document.documentElement;
|
|
991
|
+
const body = document.body;
|
|
992
|
+
const oh = getComputedStyle(html).overflowY;
|
|
993
|
+
const ob = getComputedStyle(body).overflowY;
|
|
994
|
+
const ohx = getComputedStyle(html).overflow;
|
|
995
|
+
const obx = getComputedStyle(body).overflow;
|
|
996
|
+
if (
|
|
997
|
+
(oh === "hidden" || ob === "hidden" || ohx === "hidden" || obx === "hidden") &&
|
|
998
|
+
isVisible(root)
|
|
999
|
+
) {
|
|
1000
|
+
return true;
|
|
1001
|
+
}
|
|
1002
|
+
const modals = document.querySelectorAll('[role="dialog"][aria-modal="true"]');
|
|
1003
|
+
for (const m of modals) {
|
|
1004
|
+
if (!(m instanceof HTMLElement) || !isVisible(m)) {
|
|
1005
|
+
continue;
|
|
1006
|
+
}
|
|
1007
|
+
// Cookie UIs (e.g. Complianz) often set role=dialog + aria-modal on the banner node itself.
|
|
1008
|
+
// That is not a separate viewport-blocking overlay; cropping to the banner root is correct.
|
|
1009
|
+
if (m === root) {
|
|
1010
|
+
continue;
|
|
1011
|
+
}
|
|
1012
|
+
if (m.contains(root) || root.contains(m)) {
|
|
1013
|
+
return true;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
const cx = Math.floor(window.innerWidth / 2);
|
|
1017
|
+
const cy = Math.floor(window.innerHeight / 2);
|
|
1018
|
+
const hit = document.elementFromPoint(cx, cy);
|
|
1019
|
+
if (hit && root.contains(hit)) {
|
|
1020
|
+
return true;
|
|
1021
|
+
}
|
|
1022
|
+
let p = hit;
|
|
1023
|
+
for (let i = 0; i < 8 && p; i++) {
|
|
1024
|
+
const st = window.getComputedStyle(p);
|
|
1025
|
+
if (st.position === "fixed" && parseFloat(st.opacity || "1") > 0.2) {
|
|
1026
|
+
const r = p.getBoundingClientRect();
|
|
1027
|
+
if (r.width >= window.innerWidth * 0.85 && r.height >= window.innerHeight * 0.85) {
|
|
1028
|
+
const cls = (typeof p.className === "string" ? p.className : "").toLowerCase();
|
|
1029
|
+
const id = (p.id || "").toLowerCase();
|
|
1030
|
+
if (
|
|
1031
|
+
cls.includes("overlay") ||
|
|
1032
|
+
cls.includes("backdrop") ||
|
|
1033
|
+
cls.includes("modal") ||
|
|
1034
|
+
id.includes("backdrop") ||
|
|
1035
|
+
id.includes("overlay")
|
|
1036
|
+
) {
|
|
1037
|
+
return true;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
p = p.parentElement;
|
|
1042
|
+
}
|
|
1043
|
+
return false;
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
const deriveCaptureQuality = (args) => {
|
|
1047
|
+
const reasons = [];
|
|
1048
|
+
const bbox = args.bbox;
|
|
1049
|
+
if (!bbox) {
|
|
1050
|
+
reasons.push("missing_bbox");
|
|
1051
|
+
return { qualityClass: "unusable", reasons };
|
|
1052
|
+
}
|
|
1053
|
+
const widthRatio = window.innerWidth > 0 ? bbox.width / window.innerWidth : 0;
|
|
1054
|
+
const area = bbox.width * bbox.height;
|
|
1055
|
+
let score = 0;
|
|
1056
|
+
if (args.buttons.acceptPresent && args.buttons.declinePresent) {
|
|
1057
|
+
score += 24;
|
|
1058
|
+
reasons.push("has_accept_and_decline");
|
|
1059
|
+
} else if (args.buttons.acceptPresent || args.buttons.declinePresent) {
|
|
1060
|
+
score += 12;
|
|
1061
|
+
reasons.push("has_single_primary_action");
|
|
1062
|
+
} else if (args.buttons.settingsPresent) {
|
|
1063
|
+
score += 6;
|
|
1064
|
+
reasons.push("has_settings_action");
|
|
1065
|
+
} else {
|
|
1066
|
+
reasons.push("no_detected_actions");
|
|
1067
|
+
}
|
|
1068
|
+
if (args.confidence === "high") {
|
|
1069
|
+
score += 24;
|
|
1070
|
+
} else if (args.confidence === "medium") {
|
|
1071
|
+
score += 12;
|
|
1072
|
+
}
|
|
1073
|
+
if (isControlLikeRoot(args.root)) {
|
|
1074
|
+
score -= 28;
|
|
1075
|
+
reasons.push("control_like_root");
|
|
1076
|
+
}
|
|
1077
|
+
if (widthRatio < 0.28) {
|
|
1078
|
+
score -= 16;
|
|
1079
|
+
reasons.push("narrow_bbox");
|
|
1080
|
+
}
|
|
1081
|
+
if (area < 30000) {
|
|
1082
|
+
score -= 16;
|
|
1083
|
+
reasons.push("tiny_bbox_area");
|
|
1084
|
+
}
|
|
1085
|
+
if ((args.basis || "").includes("ancestor_promotion_applied")) {
|
|
1086
|
+
score += 8;
|
|
1087
|
+
reasons.push("ancestor_promotion_applied");
|
|
1088
|
+
}
|
|
1089
|
+
if (args.fullscreen || args.blocking) {
|
|
1090
|
+
score += 10;
|
|
1091
|
+
}
|
|
1092
|
+
if (score >= 40) {
|
|
1093
|
+
return { qualityClass: "high", reasons };
|
|
1094
|
+
}
|
|
1095
|
+
if (score >= 20) {
|
|
1096
|
+
return { qualityClass: "medium", reasons };
|
|
1097
|
+
}
|
|
1098
|
+
if (score >= 4) {
|
|
1099
|
+
return { qualityClass: "low", reasons };
|
|
1100
|
+
}
|
|
1101
|
+
return { qualityClass: "unusable", reasons };
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
const found = findBannerRoot();
|
|
1105
|
+
if (!found) {
|
|
1106
|
+
return {
|
|
1107
|
+
consentBannerChecked: true,
|
|
1108
|
+
consentBannerFound: "no",
|
|
1109
|
+
consentDetectionConfidence: "low",
|
|
1110
|
+
consentBannerDetectionBasis: "no_match",
|
|
1111
|
+
consentUiOnInitialLoad: "no",
|
|
1112
|
+
consentButtons: { acceptPresent: false, declinePresent: false, settingsPresent: false },
|
|
1113
|
+
consentBannerFullscreen: false,
|
|
1114
|
+
consentBannerBlocking: false,
|
|
1115
|
+
consentBannerBoundingBox: null,
|
|
1116
|
+
consentBannerSelectorForCapture: null,
|
|
1117
|
+
consentScreenshotCandidate: null,
|
|
1118
|
+
consentCaptureQualityClass: "unusable",
|
|
1119
|
+
consentCaptureQualityReasons: ["no_match"],
|
|
1120
|
+
consentUx: null,
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
const { root, basis, standaloneNavigationalLink, hasActionableControls: candidateActionableControls } = found;
|
|
1125
|
+
const rect = root.getBoundingClientRect();
|
|
1126
|
+
const vw = window.innerWidth;
|
|
1127
|
+
const vh = window.innerHeight;
|
|
1128
|
+
const fullscreen = rect.width >= vw * 0.9 && rect.height >= vh * 0.9;
|
|
1129
|
+
const blocking = computeBlocking(root);
|
|
1130
|
+
const buttonDetection = detectButtons(root);
|
|
1131
|
+
const buttons = {
|
|
1132
|
+
acceptPresent: buttonDetection.acceptPresent,
|
|
1133
|
+
declinePresent: buttonDetection.declinePresent,
|
|
1134
|
+
settingsPresent: buttonDetection.settingsPresent,
|
|
1135
|
+
};
|
|
1136
|
+
const bbox =
|
|
1137
|
+
Number.isFinite(rect.x) && Number.isFinite(rect.y) && rect.width > 1 && rect.height > 1
|
|
1138
|
+
? { x: rect.x, y: rect.y, width: rect.width, height: rect.height }
|
|
1139
|
+
: null;
|
|
1140
|
+
const selectorForCapture = compactSelector(root);
|
|
1141
|
+
const visibleOnInitialLoad = isVisible(root);
|
|
1142
|
+
|
|
1143
|
+
let consentDetectionConfidence = "low";
|
|
1144
|
+
if (
|
|
1145
|
+
visibleOnInitialLoad &&
|
|
1146
|
+
bbox &&
|
|
1147
|
+
(buttons.acceptPresent || buttons.declinePresent)
|
|
1148
|
+
) {
|
|
1149
|
+
consentDetectionConfidence = "high";
|
|
1150
|
+
} else if (
|
|
1151
|
+
visibleOnInitialLoad &&
|
|
1152
|
+
(buttons.settingsPresent || candidateActionableControls || Boolean(bbox))
|
|
1153
|
+
) {
|
|
1154
|
+
consentDetectionConfidence = "medium";
|
|
1155
|
+
}
|
|
1156
|
+
if (standaloneNavigationalLink) {
|
|
1157
|
+
consentDetectionConfidence = "low";
|
|
1158
|
+
}
|
|
1159
|
+
const captureQuality = deriveCaptureQuality({
|
|
1160
|
+
root,
|
|
1161
|
+
bbox,
|
|
1162
|
+
buttons,
|
|
1163
|
+
basis,
|
|
1164
|
+
confidence: consentDetectionConfidence,
|
|
1165
|
+
fullscreen,
|
|
1166
|
+
blocking,
|
|
1167
|
+
});
|
|
1168
|
+
|
|
1169
|
+
const qualifiesAsConsentBanner =
|
|
1170
|
+
buttons.acceptPresent ||
|
|
1171
|
+
buttons.declinePresent ||
|
|
1172
|
+
(buttons.settingsPresent && hasStrongConsentContext(root));
|
|
1173
|
+
if (!qualifiesAsConsentBanner) {
|
|
1174
|
+
return {
|
|
1175
|
+
consentBannerChecked: true,
|
|
1176
|
+
consentBannerFound: "no",
|
|
1177
|
+
consentDetectionConfidence: "low",
|
|
1178
|
+
consentBannerDetectionBasis: appendBasis(basis, "precision_gate:insufficient_consent_signals"),
|
|
1179
|
+
consentUiOnInitialLoad: "no",
|
|
1180
|
+
consentButtons: buttons,
|
|
1181
|
+
consentBannerFullscreen: false,
|
|
1182
|
+
consentBannerBlocking: false,
|
|
1183
|
+
consentBannerBoundingBox: null,
|
|
1184
|
+
consentBannerSelectorForCapture: null,
|
|
1185
|
+
consentScreenshotCandidate: null,
|
|
1186
|
+
consentCaptureQualityClass: "unusable",
|
|
1187
|
+
consentCaptureQualityReasons: ["precision_gate_rejected"],
|
|
1188
|
+
consentUx: null,
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
return {
|
|
1193
|
+
consentBannerChecked: true,
|
|
1194
|
+
consentBannerFound: "yes",
|
|
1195
|
+
consentDetectionConfidence,
|
|
1196
|
+
consentBannerDetectionBasis: basis,
|
|
1197
|
+
consentUiOnInitialLoad: visibleOnInitialLoad ? "yes" : "no",
|
|
1198
|
+
consentButtons: buttons,
|
|
1199
|
+
consentBannerFullscreen: fullscreen,
|
|
1200
|
+
consentBannerBlocking: blocking,
|
|
1201
|
+
consentBannerBoundingBox: bbox,
|
|
1202
|
+
consentBannerSelectorForCapture: selectorForCapture,
|
|
1203
|
+
consentScreenshotCandidate: null,
|
|
1204
|
+
consentCaptureQualityClass: captureQuality.qualityClass,
|
|
1205
|
+
consentCaptureQualityReasons: captureQuality.reasons,
|
|
1206
|
+
consentUx: buttonDetection.consentUx,
|
|
1207
|
+
};
|
|
1208
|
+
})()`}function Mt(e){return`(() => {
|
|
1209
|
+
const args = ${JSON.stringify(e)};
|
|
1210
|
+
const mode = args.mode;
|
|
1211
|
+
const acceptedModeKeywords = args.acceptedModeKeywords;
|
|
1212
|
+
const declinedModeKeywords = args.declinedModeKeywords;
|
|
1213
|
+
const bannerRootSelector = String(args.bannerRootSelector ?? "").trim();
|
|
1214
|
+
|
|
1215
|
+
const normalize = (value) => String(value ?? "").trim().toLowerCase().replace(/\\s+/g, " ");
|
|
1216
|
+
const getVisibleText = (element) => {
|
|
1217
|
+
const fromInner = element.innerText ?? "";
|
|
1218
|
+
const fromAria = element.getAttribute("aria-label") ?? "";
|
|
1219
|
+
const fromTitle = element.getAttribute("title") ?? "";
|
|
1220
|
+
const fromValue =
|
|
1221
|
+
element instanceof HTMLInputElement ||
|
|
1222
|
+
element instanceof HTMLButtonElement ||
|
|
1223
|
+
element instanceof HTMLOptionElement
|
|
1224
|
+
? element.value ?? ""
|
|
1225
|
+
: "";
|
|
1226
|
+
return normalize([fromInner, fromAria, fromTitle, fromValue].join(" "));
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1229
|
+
const isVisible = (element) => {
|
|
1230
|
+
if (!(element instanceof HTMLElement)) {
|
|
1231
|
+
return false;
|
|
1232
|
+
}
|
|
1233
|
+
const style = window.getComputedStyle(element);
|
|
1234
|
+
if (style.visibility === "hidden" || style.display === "none" || parseFloat(style.opacity || "1") === 0) {
|
|
1235
|
+
return false;
|
|
1236
|
+
}
|
|
1237
|
+
const rect = element.getBoundingClientRect();
|
|
1238
|
+
return rect.width > 0 && rect.height > 0;
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
const buildAttributeCorpus = (element) => {
|
|
1242
|
+
return normalize(
|
|
1243
|
+
[
|
|
1244
|
+
element.id ?? "",
|
|
1245
|
+
element.className ?? "",
|
|
1246
|
+
element.getAttribute("name") ?? "",
|
|
1247
|
+
element.getAttribute("data-testid") ?? "",
|
|
1248
|
+
element.getAttribute("data-test") ?? "",
|
|
1249
|
+
element.getAttribute("data-qa") ?? "",
|
|
1250
|
+
element.getAttribute("aria-label") ?? "",
|
|
1251
|
+
element.getAttribute("role") ?? "",
|
|
1252
|
+
].join(" "),
|
|
1253
|
+
);
|
|
1254
|
+
};
|
|
1255
|
+
|
|
1256
|
+
const consentContextTokens = [
|
|
1257
|
+
"cookie",
|
|
1258
|
+
"cookies",
|
|
1259
|
+
"consent",
|
|
1260
|
+
"privacy",
|
|
1261
|
+
"gdpr",
|
|
1262
|
+
"accept",
|
|
1263
|
+
"allow",
|
|
1264
|
+
"agree",
|
|
1265
|
+
"reject",
|
|
1266
|
+
"decline",
|
|
1267
|
+
"deny",
|
|
1268
|
+
"manage",
|
|
1269
|
+
"preferences",
|
|
1270
|
+
"necessary",
|
|
1271
|
+
"essential",
|
|
1272
|
+
"\u043F\u0440\u0438\u043D\u044F\u0442\u044C",
|
|
1273
|
+
"\u043E\u0442\u043A\u043B\u043E\u043D\u0438\u0442\u044C",
|
|
1274
|
+
"\u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C",
|
|
1275
|
+
"akzeptieren",
|
|
1276
|
+
"ablehnen",
|
|
1277
|
+
];
|
|
1278
|
+
|
|
1279
|
+
const hasConsentContext = (element) => {
|
|
1280
|
+
const contexts = [element];
|
|
1281
|
+
if (element.parentElement) {
|
|
1282
|
+
contexts.push(element.parentElement);
|
|
1283
|
+
}
|
|
1284
|
+
const closestConsentContainer = element.closest(
|
|
1285
|
+
"[id*='cookie'],[class*='cookie'],[id*='consent'],[class*='consent'],[id*='gdpr'],[class*='gdpr'],[role='dialog']",
|
|
1286
|
+
);
|
|
1287
|
+
if (closestConsentContainer) {
|
|
1288
|
+
contexts.push(closestConsentContainer);
|
|
1289
|
+
}
|
|
1290
|
+
for (const ctx of contexts) {
|
|
1291
|
+
const contextText = getVisibleText(ctx);
|
|
1292
|
+
const contextAttributes = buildAttributeCorpus(ctx);
|
|
1293
|
+
if (
|
|
1294
|
+
consentContextTokens.some(
|
|
1295
|
+
(token) => contextText.includes(token) || contextAttributes.includes(token),
|
|
1296
|
+
)
|
|
1297
|
+
) {
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
return false;
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
const isNavigationalAnchor = (element) => {
|
|
1305
|
+
if (!(element instanceof HTMLAnchorElement)) {
|
|
1306
|
+
return false;
|
|
1307
|
+
}
|
|
1308
|
+
const href = (element.getAttribute("href") ?? "").trim();
|
|
1309
|
+
if (!href) {
|
|
1310
|
+
return false;
|
|
1311
|
+
}
|
|
1312
|
+
const normalizedHref = href.toLowerCase();
|
|
1313
|
+
if (
|
|
1314
|
+
normalizedHref.startsWith("#") ||
|
|
1315
|
+
normalizedHref.startsWith("javascript:") ||
|
|
1316
|
+
normalizedHref === "about:blank"
|
|
1317
|
+
) {
|
|
1318
|
+
return false;
|
|
1319
|
+
}
|
|
1320
|
+
return true;
|
|
1321
|
+
};
|
|
1322
|
+
|
|
1323
|
+
if (mode === "none") {
|
|
1324
|
+
return {
|
|
1325
|
+
consentOutcome: "not_applicable",
|
|
1326
|
+
interactionAttempted: false,
|
|
1327
|
+
interactionStrategy: "none",
|
|
1328
|
+
interactionMatchedSelector: null,
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
const modeKeywords = mode === "accepted" ? acceptedModeKeywords : declinedModeKeywords;
|
|
1333
|
+
const modeSelectors =
|
|
1334
|
+
mode === "accepted"
|
|
1335
|
+
? [
|
|
1336
|
+
"#onetrust-accept-btn-handler",
|
|
1337
|
+
"#didomi-notice-agree-button",
|
|
1338
|
+
"#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll",
|
|
1339
|
+
".cmplz-accept",
|
|
1340
|
+
".iubenda-cs-accept-btn",
|
|
1341
|
+
"[data-testid*='accept']",
|
|
1342
|
+
"[id*='accept']",
|
|
1343
|
+
"[class*='accept']",
|
|
1344
|
+
"[aria-label*='accept']",
|
|
1345
|
+
"[aria-label*='agree']",
|
|
1346
|
+
"[aria-label*='allow']",
|
|
1347
|
+
]
|
|
1348
|
+
: [
|
|
1349
|
+
"#onetrust-reject-all-handler",
|
|
1350
|
+
"#didomi-notice-disagree-button",
|
|
1351
|
+
"#CybotCookiebotDialogBodyButtonDecline",
|
|
1352
|
+
".cmplz-deny",
|
|
1353
|
+
".cmplz-decline",
|
|
1354
|
+
".iubenda-cs-reject-btn",
|
|
1355
|
+
"[data-testid*='reject']",
|
|
1356
|
+
"[id*='reject']",
|
|
1357
|
+
"[class*='reject']",
|
|
1358
|
+
"[aria-label*='reject']",
|
|
1359
|
+
"[aria-label*='decline']",
|
|
1360
|
+
"[aria-label*='deny']",
|
|
1361
|
+
];
|
|
1362
|
+
|
|
1363
|
+
const modeAttributeTokens =
|
|
1364
|
+
mode === "accepted"
|
|
1365
|
+
? ["accept", "agree", "allow", "consent", "optin"]
|
|
1366
|
+
: ["reject", "decline", "deny", "disagree", "refuse", "optout", "necessary", "essential"];
|
|
1367
|
+
|
|
1368
|
+
const settingsSelectors = [
|
|
1369
|
+
"#onetrust-pc-btn-handler",
|
|
1370
|
+
"#didomi-notice-learn-more-button",
|
|
1371
|
+
"#CybotCookiebotDialogBodyLevelButtonCustomize",
|
|
1372
|
+
".cmplz-manage-options",
|
|
1373
|
+
".iubenda-cs-customize-btn",
|
|
1374
|
+
"[data-testid*='setting']",
|
|
1375
|
+
"[id*='setting']",
|
|
1376
|
+
"[class*='setting']",
|
|
1377
|
+
"[aria-label*='setting']",
|
|
1378
|
+
"[aria-label*='preference']",
|
|
1379
|
+
"[aria-label*='manage']",
|
|
1380
|
+
"a[href*='cookie'][href*='setting']",
|
|
1381
|
+
"a[href*='consent']",
|
|
1382
|
+
];
|
|
1383
|
+
const settingsAttributeTokens = ["setting", "preference", "customize", "manage", "configure", "option"];
|
|
1384
|
+
|
|
1385
|
+
const isInViewport = (element) => {
|
|
1386
|
+
if (!(element instanceof HTMLElement)) {
|
|
1387
|
+
return false;
|
|
1388
|
+
}
|
|
1389
|
+
const rect = element.getBoundingClientRect();
|
|
1390
|
+
const vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
1391
|
+
const vw = window.innerWidth || document.documentElement.clientWidth || 0;
|
|
1392
|
+
return rect.bottom > 0 && rect.top < vh && rect.right > 0 && rect.left < vw;
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1395
|
+
const tokenMatchesBounded = (corpus, token) => {
|
|
1396
|
+
if (!corpus || !token) {
|
|
1397
|
+
return false;
|
|
1398
|
+
}
|
|
1399
|
+
if (token === "allow" && /not-allowed|disallowed|without-consent/.test(corpus)) {
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1402
|
+
const escaped = String(token).replace(/[.*+?^\${}()|[\\]\\\\]/g, "\\\\$&");
|
|
1403
|
+
return new RegExp("(^|[^a-z0-9_-])" + escaped + "([^a-z0-9_-]|$)", "i").test(corpus);
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
const hasAttrTokens = (attr, tokens) => tokens.some((token) => tokenMatchesBounded(attr, token));
|
|
1407
|
+
|
|
1408
|
+
const textMatchesKeyword = (text, keywords) =>
|
|
1409
|
+
keywords.some((keyword) => {
|
|
1410
|
+
const normalizedKeyword = normalize(keyword);
|
|
1411
|
+
if (!normalizedKeyword) {
|
|
1412
|
+
return false;
|
|
1413
|
+
}
|
|
1414
|
+
if (text === normalizedKeyword) {
|
|
1415
|
+
return true;
|
|
1416
|
+
}
|
|
1417
|
+
return (
|
|
1418
|
+
text.includes(" " + normalizedKeyword + " ") ||
|
|
1419
|
+
text.startsWith(normalizedKeyword + " ") ||
|
|
1420
|
+
text.endsWith(" " + normalizedKeyword)
|
|
1421
|
+
);
|
|
1422
|
+
});
|
|
1423
|
+
|
|
1424
|
+
const hasModeAttributeMatch = (element) => {
|
|
1425
|
+
const attributeCorpus = buildAttributeCorpus(element);
|
|
1426
|
+
if (!attributeCorpus) {
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
return hasAttrTokens(attributeCorpus, modeAttributeTokens);
|
|
1430
|
+
};
|
|
1431
|
+
|
|
1432
|
+
const hasSettingsAttributeMatch = (element) => {
|
|
1433
|
+
const attributeCorpus = buildAttributeCorpus(element);
|
|
1434
|
+
if (!attributeCorpus) {
|
|
1435
|
+
return false;
|
|
1436
|
+
}
|
|
1437
|
+
return hasAttrTokens(attributeCorpus, settingsAttributeTokens);
|
|
1438
|
+
};
|
|
1439
|
+
|
|
1440
|
+
const bannerRoot =
|
|
1441
|
+
bannerRootSelector && document.querySelector(bannerRootSelector) instanceof HTMLElement
|
|
1442
|
+
? document.querySelector(bannerRootSelector)
|
|
1443
|
+
: null;
|
|
1444
|
+
const searchRoot = bannerRoot instanceof HTMLElement ? bannerRoot : document;
|
|
1445
|
+
const candidates = Array.from(
|
|
1446
|
+
searchRoot.querySelectorAll(
|
|
1447
|
+
"button, [role='button'], input[type='button'], input[type='submit'], a[role='button'], a[href]",
|
|
1448
|
+
),
|
|
1449
|
+
);
|
|
1450
|
+
|
|
1451
|
+
const compactSelector = (element) => {
|
|
1452
|
+
if (!(element instanceof Element)) {
|
|
1453
|
+
return null;
|
|
1454
|
+
}
|
|
1455
|
+
if (element.id) {
|
|
1456
|
+
return "#" + element.id;
|
|
1457
|
+
}
|
|
1458
|
+
const tag = element.tagName.toLowerCase();
|
|
1459
|
+
const className =
|
|
1460
|
+
typeof element.className === "string"
|
|
1461
|
+
? element.className
|
|
1462
|
+
.split(/\\s+/)
|
|
1463
|
+
.filter(Boolean)
|
|
1464
|
+
.slice(0, 2)
|
|
1465
|
+
.join(".")
|
|
1466
|
+
: "";
|
|
1467
|
+
if (className) {
|
|
1468
|
+
return tag + "." + className;
|
|
1469
|
+
}
|
|
1470
|
+
return tag;
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
const clickElement = (element, strategy) => {
|
|
1474
|
+
try {
|
|
1475
|
+
element.click();
|
|
1476
|
+
return {
|
|
1477
|
+
consentOutcome: mode === "accepted" ? "clicked_accept" : "clicked_decline",
|
|
1478
|
+
interactionAttempted: true,
|
|
1479
|
+
interactionStrategy: strategy,
|
|
1480
|
+
interactionMatchedSelector: compactSelector(element),
|
|
1481
|
+
};
|
|
1482
|
+
} catch (_e) {
|
|
1483
|
+
return {
|
|
1484
|
+
consentOutcome: "interaction_failed",
|
|
1485
|
+
interactionAttempted: true,
|
|
1486
|
+
interactionStrategy: strategy,
|
|
1487
|
+
interactionMatchedSelector: compactSelector(element),
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
};
|
|
1491
|
+
|
|
1492
|
+
for (const selector of modeSelectors) {
|
|
1493
|
+
const directMatch = searchRoot.querySelector(selector);
|
|
1494
|
+
if (directMatch && isVisible(directMatch) && isInViewport(directMatch) && directMatch instanceof HTMLElement) {
|
|
1495
|
+
if (isNavigationalAnchor(directMatch)) {
|
|
1496
|
+
continue;
|
|
1497
|
+
}
|
|
1498
|
+
return clickElement(directMatch, mode === "accepted" ? "direct_accept" : "direct_decline");
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
const ranked = [];
|
|
1503
|
+
for (const element of candidates) {
|
|
1504
|
+
if (!(element instanceof HTMLElement) || !isVisible(element) || !isInViewport(element) || isNavigationalAnchor(element)) {
|
|
1505
|
+
continue;
|
|
1506
|
+
}
|
|
1507
|
+
if (element instanceof HTMLButtonElement && element.disabled) {
|
|
1508
|
+
continue;
|
|
1509
|
+
}
|
|
1510
|
+
if (element instanceof HTMLInputElement && element.disabled) {
|
|
1511
|
+
continue;
|
|
1512
|
+
}
|
|
1513
|
+
if (element.getAttribute("aria-disabled") === "true") {
|
|
1514
|
+
continue;
|
|
1515
|
+
}
|
|
1516
|
+
const text = getVisibleText(element);
|
|
1517
|
+
let score = 0;
|
|
1518
|
+
if (textMatchesKeyword(text, modeKeywords)) {
|
|
1519
|
+
const exact = modeKeywords.some((keyword) => text === normalize(keyword));
|
|
1520
|
+
score += exact ? 100 : 60;
|
|
1521
|
+
} else if (hasModeAttributeMatch(element)) {
|
|
1522
|
+
score += 20;
|
|
1523
|
+
} else {
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (bannerRoot instanceof HTMLElement && !bannerRoot.contains(element)) {
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1529
|
+
if (!bannerRoot && !hasConsentContext(element)) {
|
|
1530
|
+
continue;
|
|
1531
|
+
}
|
|
1532
|
+
ranked.push({ element, score });
|
|
1533
|
+
}
|
|
1534
|
+
ranked.sort((a, b) => b.score - a.score);
|
|
1535
|
+
const selected = ranked[0]?.element;
|
|
1536
|
+
if (selected && selected instanceof HTMLElement) {
|
|
1537
|
+
return clickElement(selected, mode === "accepted" ? "direct_accept" : "direct_decline");
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
if (mode === "declined") {
|
|
1541
|
+
for (const selector of settingsSelectors) {
|
|
1542
|
+
const maybe = document.querySelector(selector);
|
|
1543
|
+
if (!(maybe instanceof HTMLElement) || !isVisible(maybe) || isNavigationalAnchor(maybe)) {
|
|
1544
|
+
continue;
|
|
1545
|
+
}
|
|
1546
|
+
try {
|
|
1547
|
+
maybe.click();
|
|
1548
|
+
} catch (_e) {
|
|
1549
|
+
continue;
|
|
1550
|
+
}
|
|
1551
|
+
const postClickCandidates = Array.from(
|
|
1552
|
+
document.querySelectorAll(
|
|
1553
|
+
"button, [role='button'], input[type='button'], input[type='submit'], a[role='button'], a[href]",
|
|
1554
|
+
),
|
|
1555
|
+
);
|
|
1556
|
+
const postClickReject = postClickCandidates.find((element) => {
|
|
1557
|
+
if (!(element instanceof HTMLElement) || !isVisible(element) || isNavigationalAnchor(element)) {
|
|
1558
|
+
return false;
|
|
1559
|
+
}
|
|
1560
|
+
const text = getVisibleText(element);
|
|
1561
|
+
const hasKeywordMatch = declinedModeKeywords.some((keyword) => text.includes(normalize(keyword)));
|
|
1562
|
+
return hasKeywordMatch || hasModeAttributeMatch(element);
|
|
1563
|
+
});
|
|
1564
|
+
if (postClickReject && postClickReject instanceof HTMLElement) {
|
|
1565
|
+
return clickElement(postClickReject, "open_settings_then_decline");
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
const settingsCandidate = candidates.find((element) => {
|
|
1570
|
+
if (!(element instanceof HTMLElement) || !isVisible(element) || isNavigationalAnchor(element)) {
|
|
1571
|
+
return false;
|
|
1572
|
+
}
|
|
1573
|
+
const text = getVisibleText(element);
|
|
1574
|
+
const hasKeywordMatch =
|
|
1575
|
+
text.includes("setting") ||
|
|
1576
|
+
text.includes("preference") ||
|
|
1577
|
+
text.includes("manage") ||
|
|
1578
|
+
text.includes("customize") ||
|
|
1579
|
+
text.includes("\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A") ||
|
|
1580
|
+
text.includes("\u0443\u043F\u0440\u0430\u0432\u043B");
|
|
1581
|
+
return hasKeywordMatch || hasSettingsAttributeMatch(element);
|
|
1582
|
+
});
|
|
1583
|
+
if (settingsCandidate && settingsCandidate instanceof HTMLElement) {
|
|
1584
|
+
try {
|
|
1585
|
+
settingsCandidate.click();
|
|
1586
|
+
return {
|
|
1587
|
+
consentOutcome: "banner_not_found",
|
|
1588
|
+
interactionAttempted: true,
|
|
1589
|
+
interactionStrategy: "open_settings_then_decline",
|
|
1590
|
+
interactionMatchedSelector: compactSelector(settingsCandidate),
|
|
1591
|
+
};
|
|
1592
|
+
} catch (_e) {}
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
return {
|
|
1597
|
+
consentOutcome: "banner_not_found",
|
|
1598
|
+
interactionAttempted: false,
|
|
1599
|
+
interactionStrategy: "none",
|
|
1600
|
+
interactionMatchedSelector: null,
|
|
1601
|
+
};
|
|
1602
|
+
})()`}function wo(e){return{bannerFound:e.consentBannerFound==="yes",acceptPresent:e.consentButtons.acceptPresent,rejectPresent:e.consentButtons.declinePresent,settingsPresent:e.consentButtons.settingsPresent,detectionConfidence:e.consentDetectionConfidence,detectionBasis:e.consentBannerDetectionBasis??null,bannerTextSnippet:e.consentUx?.bannerTextSnippet??null,matchedAcceptLabel:e.consentUx?.acceptMetrics?.label??null,matchedRejectLabel:e.consentUx?.declineMetrics?.label??null,matchedSettingsLabel:e.consentUx?.settingsMetrics?.label??null,consentUxMetrics:{bannerSelector:e.consentBannerSelectorForCapture??null,acceptLabel:e.consentUx?.acceptMetrics?.label??null,acceptSelector:e.consentUx?.acceptMetrics?.selector??null,rejectLabel:e.consentUx?.declineMetrics?.label??null,rejectSelector:e.consentUx?.declineMetrics?.selector??null,settingsLabel:e.consentUx?.settingsMetrics?.label??null,settingsSelector:e.consentUx?.settingsMetrics?.selector??null,blocking:e.consentBannerBlocking,fullscreen:e.consentBannerFullscreen,boundingBox:e.consentBannerBoundingBox??null,captureQualityClass:e.consentCaptureQualityClass,captureQualityReasons:e.consentCaptureQualityReasons}}}function xo(e,t,o){let a=e==="accepted"?"accept":"reject",n=e==="accepted"?o?.consentUx?.acceptMetrics?.label??void 0:o?.consentUx?.declineMetrics?.label??void 0;if(!t.interactionAttempted)return{attempted:!0,succeeded:!1,action:a,error:"no matching consent control found",matchedSelector:t.interactionMatchedSelector??void 0,...n?{matchedText:n}:{}};let i=t.consentOutcome==="clicked_accept"||t.consentOutcome==="clicked_decline";return{attempted:!0,succeeded:i,action:a,...t.interactionMatchedSelector?{matchedSelector:t.interactionMatchedSelector}:{},...n?{matchedText:n}:{},...i?{}:{error:t.consentOutcome||"consent interaction failed"}}}function So(e){return`(async () => {
|
|
1603
|
+
const indexedDbSampleLimitInner = ${JSON.stringify(e)};
|
|
1604
|
+
const records = [];
|
|
1605
|
+
const stringifyValue = (input) => {
|
|
1606
|
+
if (typeof input === "string") {
|
|
1607
|
+
return input;
|
|
1608
|
+
}
|
|
1609
|
+
if (typeof input === "number" || typeof input === "boolean" || typeof input === "bigint") {
|
|
1610
|
+
return String(input);
|
|
1611
|
+
}
|
|
1612
|
+
if (input === null || input === undefined) {
|
|
1613
|
+
return "";
|
|
1614
|
+
}
|
|
1615
|
+
try {
|
|
1616
|
+
return JSON.stringify(input);
|
|
1617
|
+
} catch (_e) {
|
|
1618
|
+
return Object.prototype.toString.call(input);
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
const collectWebStorage = (storageType, readStorage) => {
|
|
1622
|
+
try {
|
|
1623
|
+
const storage = readStorage();
|
|
1624
|
+
for (let index = 0; index < storage.length; index += 1) {
|
|
1625
|
+
const key = storage.key(index);
|
|
1626
|
+
if (key === null) {
|
|
1627
|
+
continue;
|
|
1628
|
+
}
|
|
1629
|
+
records.push({
|
|
1630
|
+
storageType,
|
|
1631
|
+
key,
|
|
1632
|
+
value: storage.getItem(key),
|
|
1633
|
+
databaseName: null,
|
|
1634
|
+
objectStoreName: null,
|
|
1635
|
+
collectionStatus: "collected",
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1638
|
+
} catch (_e) {
|
|
1639
|
+
records.push({
|
|
1640
|
+
storageType,
|
|
1641
|
+
key: null,
|
|
1642
|
+
value: null,
|
|
1643
|
+
databaseName: null,
|
|
1644
|
+
objectStoreName: null,
|
|
1645
|
+
collectionStatus: "read_error",
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
};
|
|
1649
|
+
collectWebStorage("local_storage", () => window.localStorage);
|
|
1650
|
+
collectWebStorage("session_storage", () => window.sessionStorage);
|
|
1651
|
+
|
|
1652
|
+
if (indexedDbSampleLimitInner <= 0) {
|
|
1653
|
+
return records;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
if (typeof indexedDB === "undefined" || typeof indexedDB.databases !== "function") {
|
|
1657
|
+
records.push({
|
|
1658
|
+
storageType: "indexeddb",
|
|
1659
|
+
key: null,
|
|
1660
|
+
value: null,
|
|
1661
|
+
databaseName: null,
|
|
1662
|
+
objectStoreName: null,
|
|
1663
|
+
collectionStatus: "unsupported",
|
|
1664
|
+
});
|
|
1665
|
+
return records;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
let discoveredDatabases;
|
|
1669
|
+
try {
|
|
1670
|
+
discoveredDatabases = await indexedDB.databases();
|
|
1671
|
+
} catch (_e) {
|
|
1672
|
+
records.push({
|
|
1673
|
+
storageType: "indexeddb",
|
|
1674
|
+
key: null,
|
|
1675
|
+
value: null,
|
|
1676
|
+
databaseName: null,
|
|
1677
|
+
objectStoreName: null,
|
|
1678
|
+
collectionStatus: "enumeration_error",
|
|
1679
|
+
});
|
|
1680
|
+
return records;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
const databaseNames = discoveredDatabases
|
|
1684
|
+
.map((entry) => entry.name)
|
|
1685
|
+
.filter((name) => typeof name === "string" && name.length > 0);
|
|
1686
|
+
|
|
1687
|
+
for (const databaseName of databaseNames) {
|
|
1688
|
+
let database;
|
|
1689
|
+
try {
|
|
1690
|
+
database = await new Promise((resolve, reject) => {
|
|
1691
|
+
const openRequest = indexedDB.open(databaseName);
|
|
1692
|
+
openRequest.onerror = () => {
|
|
1693
|
+
reject(openRequest.error ?? new Error("Failed to open IndexedDB database."));
|
|
1694
|
+
};
|
|
1695
|
+
openRequest.onsuccess = () => {
|
|
1696
|
+
resolve(openRequest.result);
|
|
1697
|
+
};
|
|
1698
|
+
});
|
|
1699
|
+
} catch (_e) {
|
|
1700
|
+
records.push({
|
|
1701
|
+
storageType: "indexeddb",
|
|
1702
|
+
key: null,
|
|
1703
|
+
value: null,
|
|
1704
|
+
databaseName,
|
|
1705
|
+
objectStoreName: null,
|
|
1706
|
+
collectionStatus: "open_error",
|
|
1707
|
+
});
|
|
1708
|
+
continue;
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
const objectStoreNames = Array.from(database.objectStoreNames);
|
|
1712
|
+
for (const objectStoreName of objectStoreNames) {
|
|
1713
|
+
try {
|
|
1714
|
+
const storeEntries = await new Promise((resolve, reject) => {
|
|
1715
|
+
const tx = database.transaction(objectStoreName, "readonly");
|
|
1716
|
+
const store = tx.objectStore(objectStoreName);
|
|
1717
|
+
const request = store.openCursor();
|
|
1718
|
+
const collectedEntries = [];
|
|
1719
|
+
let collected = 0;
|
|
1720
|
+
request.onerror = () => {
|
|
1721
|
+
reject(request.error ?? new Error("Failed to iterate IndexedDB cursor."));
|
|
1722
|
+
};
|
|
1723
|
+
tx.onerror = () => {
|
|
1724
|
+
reject(tx.error ?? new Error("IndexedDB read transaction failed."));
|
|
1725
|
+
};
|
|
1726
|
+
tx.onabort = () => {
|
|
1727
|
+
reject(tx.error ?? new Error("IndexedDB read transaction aborted."));
|
|
1728
|
+
};
|
|
1729
|
+
request.onsuccess = () => {
|
|
1730
|
+
const cursor = request.result;
|
|
1731
|
+
if (!cursor || collected >= indexedDbSampleLimitInner) {
|
|
1732
|
+
resolve(collectedEntries);
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
collectedEntries.push({
|
|
1736
|
+
storageType: "indexeddb",
|
|
1737
|
+
key: stringifyValue(cursor.primaryKey),
|
|
1738
|
+
value: stringifyValue(cursor.value),
|
|
1739
|
+
databaseName,
|
|
1740
|
+
objectStoreName,
|
|
1741
|
+
collectionStatus: "collected",
|
|
1742
|
+
});
|
|
1743
|
+
collected += 1;
|
|
1744
|
+
cursor.continue();
|
|
1745
|
+
};
|
|
1746
|
+
});
|
|
1747
|
+
records.push(...storeEntries);
|
|
1748
|
+
} catch (_e) {
|
|
1749
|
+
records.push({
|
|
1750
|
+
storageType: "indexeddb",
|
|
1751
|
+
key: null,
|
|
1752
|
+
value: null,
|
|
1753
|
+
databaseName,
|
|
1754
|
+
objectStoreName,
|
|
1755
|
+
collectionStatus: "read_error",
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
database.close();
|
|
1760
|
+
}
|
|
1761
|
+
return records;
|
|
1762
|
+
})()`}function Eo(){return`(() => {
|
|
1763
|
+
const toAbsoluteHttpUrl = (input) => {
|
|
1764
|
+
const trimmed = input.trim();
|
|
1765
|
+
if (!trimmed) {
|
|
1766
|
+
return null;
|
|
1767
|
+
}
|
|
1768
|
+
try {
|
|
1769
|
+
const parsed = new URL(trimmed, window.location.href);
|
|
1770
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
1771
|
+
return null;
|
|
1772
|
+
}
|
|
1773
|
+
return parsed.toString();
|
|
1774
|
+
} catch (_e) {
|
|
1775
|
+
return null;
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
const uniq = (values) =>
|
|
1779
|
+
[...new Set(values.map((value) => value.trim()).filter(Boolean))].sort((left, right) =>
|
|
1780
|
+
left.localeCompare(right),
|
|
1781
|
+
);
|
|
1782
|
+
const loadedScriptUrls = uniq(
|
|
1783
|
+
Array.from(document.querySelectorAll("script[src]"))
|
|
1784
|
+
.map((node) => node.getAttribute("src") ?? "")
|
|
1785
|
+
.map((src) => toAbsoluteHttpUrl(src))
|
|
1786
|
+
.filter((entry) => typeof entry === "string"),
|
|
1787
|
+
);
|
|
1788
|
+
const inlineScripts = Array.from(document.querySelectorAll("script:not([src])"))
|
|
1789
|
+
.map((node) => (node.textContent ?? "").replace(/\\s+/g, " ").trim())
|
|
1790
|
+
.filter(Boolean)
|
|
1791
|
+
.slice(0, 20)
|
|
1792
|
+
.map((script) => script.slice(0, 2000));
|
|
1793
|
+
const resourceUrls = uniq(
|
|
1794
|
+
(typeof performance !== "undefined" && typeof performance.getEntriesByType === "function"
|
|
1795
|
+
? performance.getEntriesByType("resource")
|
|
1796
|
+
: []
|
|
1797
|
+
)
|
|
1798
|
+
.map((entry) => toAbsoluteHttpUrl(entry.name))
|
|
1799
|
+
.filter((entry) => typeof entry === "string"),
|
|
1800
|
+
);
|
|
1801
|
+
const globalChecks = [
|
|
1802
|
+
["dataLayer", () => Array.isArray(window["dataLayer"])],
|
|
1803
|
+
[
|
|
1804
|
+
"google_tag_manager",
|
|
1805
|
+
() => typeof window["google_tag_manager"] === "object",
|
|
1806
|
+
],
|
|
1807
|
+
["gtag", () => typeof window["gtag"] === "function"],
|
|
1808
|
+
["ga", () => typeof window["ga"] === "function"],
|
|
1809
|
+
["fbq", () => typeof window["fbq"] === "function"],
|
|
1810
|
+
["ttq", () => typeof window["ttq"] === "object"],
|
|
1811
|
+
["hj", () => typeof window["hj"] === "function"],
|
|
1812
|
+
["_hjSettings", () => typeof window["_hjSettings"] === "object"],
|
|
1813
|
+
["clarity", () => typeof window["clarity"] === "function"],
|
|
1814
|
+
["ym", () => typeof window["ym"] === "function"],
|
|
1815
|
+
["analytics", () => typeof window["analytics"] === "object"],
|
|
1816
|
+
["amplitude", () => typeof window["amplitude"] === "object"],
|
|
1817
|
+
["Intercom", () => typeof window["Intercom"] === "function"],
|
|
1818
|
+
["zE", () => typeof window["zE"] !== "undefined"],
|
|
1819
|
+
["$zopim", () => typeof window["$zopim"] !== "undefined"],
|
|
1820
|
+
];
|
|
1821
|
+
const knownGlobals = uniq(
|
|
1822
|
+
globalChecks
|
|
1823
|
+
.filter(([, checker]) => {
|
|
1824
|
+
try {
|
|
1825
|
+
return checker();
|
|
1826
|
+
} catch (_e) {
|
|
1827
|
+
return false;
|
|
1828
|
+
}
|
|
1829
|
+
})
|
|
1830
|
+
.map(([name]) => name),
|
|
1831
|
+
);
|
|
1832
|
+
return {
|
|
1833
|
+
loadedScriptUrls,
|
|
1834
|
+
resourceUrls: uniq([...resourceUrls, ...loadedScriptUrls]),
|
|
1835
|
+
knownGlobals,
|
|
1836
|
+
inlineScripts,
|
|
1837
|
+
};
|
|
1838
|
+
})()`}function It(){return`(() => {
|
|
1839
|
+
const normalizeText = (value) =>
|
|
1840
|
+
String(value ?? "")
|
|
1841
|
+
.replace(/\\s+/g, " ")
|
|
1842
|
+
.trim();
|
|
1843
|
+
const normalizeLower = (value) => normalizeText(value).toLowerCase();
|
|
1844
|
+
const uniqSorted = (values) =>
|
|
1845
|
+
[...new Set(values.map((value) => normalizeText(value)).filter(Boolean))].sort((left, right) =>
|
|
1846
|
+
left.localeCompare(right),
|
|
1847
|
+
);
|
|
1848
|
+
const toAbsoluteHttpUrl = (input) => {
|
|
1849
|
+
const raw = normalizeText(input);
|
|
1850
|
+
if (!raw) {
|
|
1851
|
+
return null;
|
|
1852
|
+
}
|
|
1853
|
+
try {
|
|
1854
|
+
const parsed = new URL(raw, window.location.href);
|
|
1855
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
1856
|
+
return null;
|
|
1857
|
+
}
|
|
1858
|
+
return parsed.toString();
|
|
1859
|
+
} catch (_e) {
|
|
1860
|
+
return null;
|
|
1861
|
+
}
|
|
1862
|
+
};
|
|
1863
|
+
const parseIconSizeScore = (sizesRaw) => {
|
|
1864
|
+
const sizes = normalizeLower(sizesRaw);
|
|
1865
|
+
if (!sizes) {
|
|
1866
|
+
return 0;
|
|
1867
|
+
}
|
|
1868
|
+
let max = 0;
|
|
1869
|
+
for (const token of sizes.split(/\\s+/)) {
|
|
1870
|
+
const parts = token.split("x");
|
|
1871
|
+
const w = Number.parseInt(parts[0] ?? "", 10);
|
|
1872
|
+
const h = Number.parseInt(parts[1] ?? "", 10);
|
|
1873
|
+
if (Number.isFinite(w) && Number.isFinite(h) && w > 0 && h > 0) {
|
|
1874
|
+
max = Math.max(max, w * h);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
return max;
|
|
1878
|
+
};
|
|
1879
|
+
const resolveFavicon = () => {
|
|
1880
|
+
const links = Array.from(document.querySelectorAll("link[rel][href]"));
|
|
1881
|
+
const candidates = [];
|
|
1882
|
+
for (const link of links) {
|
|
1883
|
+
const rel = normalizeLower(link.getAttribute("rel"));
|
|
1884
|
+
const href = link.getAttribute("href");
|
|
1885
|
+
const url = toAbsoluteHttpUrl(href);
|
|
1886
|
+
if (!url || !rel) {
|
|
1887
|
+
continue;
|
|
1888
|
+
}
|
|
1889
|
+
let priority = 0;
|
|
1890
|
+
if (rel.includes("apple-touch-icon")) {
|
|
1891
|
+
priority = 4;
|
|
1892
|
+
} else if (rel === "icon" || rel.includes(" icon")) {
|
|
1893
|
+
priority = 2;
|
|
1894
|
+
} else if (rel.includes("shortcut icon")) {
|
|
1895
|
+
priority = 1;
|
|
1896
|
+
}
|
|
1897
|
+
if (priority === 0) {
|
|
1898
|
+
continue;
|
|
1899
|
+
}
|
|
1900
|
+
const sizeScore = parseIconSizeScore(link.getAttribute("sizes"));
|
|
1901
|
+
if (priority === 2 && sizeScore > 0) {
|
|
1902
|
+
priority = 3;
|
|
1903
|
+
}
|
|
1904
|
+
candidates.push({ url, priority, sizeScore });
|
|
1905
|
+
}
|
|
1906
|
+
if (candidates.length > 0) {
|
|
1907
|
+
candidates.sort((left, right) => {
|
|
1908
|
+
if (left.priority !== right.priority) {
|
|
1909
|
+
return right.priority - left.priority;
|
|
1910
|
+
}
|
|
1911
|
+
if (left.sizeScore !== right.sizeScore) {
|
|
1912
|
+
return right.sizeScore - left.sizeScore;
|
|
1913
|
+
}
|
|
1914
|
+
return left.url.localeCompare(right.url);
|
|
1915
|
+
});
|
|
1916
|
+
const best = candidates[0]?.url ?? null;
|
|
1917
|
+
return { url: best, fromExplicitLink: Boolean(best) };
|
|
1918
|
+
}
|
|
1919
|
+
return {
|
|
1920
|
+
url: toAbsoluteHttpUrl(window.location.origin + "/favicon.ico"),
|
|
1921
|
+
fromExplicitLink: false,
|
|
1922
|
+
};
|
|
1923
|
+
};
|
|
1924
|
+
const compactSelector = (element) => {
|
|
1925
|
+
if (!(element instanceof Element)) {
|
|
1926
|
+
return null;
|
|
1927
|
+
}
|
|
1928
|
+
if (element.id) {
|
|
1929
|
+
return "#" + element.id;
|
|
1930
|
+
}
|
|
1931
|
+
const tag = element.tagName.toLowerCase();
|
|
1932
|
+
const className =
|
|
1933
|
+
typeof element.className === "string"
|
|
1934
|
+
? element.className
|
|
1935
|
+
.split(/\\s+/)
|
|
1936
|
+
.filter(Boolean)
|
|
1937
|
+
.slice(0, 2)
|
|
1938
|
+
.join(".")
|
|
1939
|
+
: "";
|
|
1940
|
+
if (className) {
|
|
1941
|
+
return tag + "." + className;
|
|
1942
|
+
}
|
|
1943
|
+
const parent = element.parentElement;
|
|
1944
|
+
if (!parent) {
|
|
1945
|
+
return tag;
|
|
1946
|
+
}
|
|
1947
|
+
const siblings = Array.from(parent.children).filter(
|
|
1948
|
+
(node) => node.tagName.toLowerCase() === tag,
|
|
1949
|
+
);
|
|
1950
|
+
if (siblings.length <= 1) {
|
|
1951
|
+
return tag;
|
|
1952
|
+
}
|
|
1953
|
+
const index = siblings.indexOf(element) + 1;
|
|
1954
|
+
return tag + ":nth-of-type(" + String(index) + ")";
|
|
1955
|
+
};
|
|
1956
|
+
const snippetText = (element) => {
|
|
1957
|
+
if (!(element instanceof HTMLElement)) {
|
|
1958
|
+
return "";
|
|
1959
|
+
}
|
|
1960
|
+
const text = [
|
|
1961
|
+
element.innerText ?? "",
|
|
1962
|
+
element.getAttribute("aria-label") ?? "",
|
|
1963
|
+
element.getAttribute("title") ?? "",
|
|
1964
|
+
element.getAttribute("name") ?? "",
|
|
1965
|
+
element.getAttribute("placeholder") ?? "",
|
|
1966
|
+
].join(" ");
|
|
1967
|
+
return normalizeText(text).slice(0, 260);
|
|
1968
|
+
};
|
|
1969
|
+
const getAnchorUrl = (element) => {
|
|
1970
|
+
if (element instanceof HTMLAnchorElement) {
|
|
1971
|
+
return toAbsoluteHttpUrl(element.getAttribute("href"));
|
|
1972
|
+
}
|
|
1973
|
+
return null;
|
|
1974
|
+
};
|
|
1975
|
+
const getFormUrl = (element) => {
|
|
1976
|
+
if (element instanceof HTMLFormElement) {
|
|
1977
|
+
return toAbsoluteHttpUrl(element.getAttribute("action"));
|
|
1978
|
+
}
|
|
1979
|
+
return null;
|
|
1980
|
+
};
|
|
1981
|
+
const capabilityIndicators = [];
|
|
1982
|
+
const policyIndicators = [];
|
|
1983
|
+
const capabilitySeen = new Set();
|
|
1984
|
+
const policySeen = new Set();
|
|
1985
|
+
const pushCapability = (capability, matchKind, selector, matchedText, url) => {
|
|
1986
|
+
const payload = {
|
|
1987
|
+
capability,
|
|
1988
|
+
matchKind,
|
|
1989
|
+
selector: normalizeText(selector) || null,
|
|
1990
|
+
matchedText: normalizeText(matchedText).slice(0, 260) || null,
|
|
1991
|
+
url: toAbsoluteHttpUrl(url),
|
|
1992
|
+
};
|
|
1993
|
+
const dedupeKey = [
|
|
1994
|
+
payload.capability,
|
|
1995
|
+
payload.matchKind,
|
|
1996
|
+
payload.selector ?? "",
|
|
1997
|
+
payload.matchedText ?? "",
|
|
1998
|
+
payload.url ?? "",
|
|
1999
|
+
].join("|");
|
|
2000
|
+
if (capabilitySeen.has(dedupeKey)) {
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
2003
|
+
capabilitySeen.add(dedupeKey);
|
|
2004
|
+
capabilityIndicators.push(payload);
|
|
2005
|
+
};
|
|
2006
|
+
const pushPolicy = (policy, matchKind, selector, matchedText, url) => {
|
|
2007
|
+
const payload = {
|
|
2008
|
+
policy,
|
|
2009
|
+
matchKind,
|
|
2010
|
+
selector: normalizeText(selector) || null,
|
|
2011
|
+
matchedText: normalizeText(matchedText).slice(0, 260) || null,
|
|
2012
|
+
url: toAbsoluteHttpUrl(url),
|
|
2013
|
+
};
|
|
2014
|
+
const dedupeKey = [
|
|
2015
|
+
payload.policy,
|
|
2016
|
+
payload.matchKind,
|
|
2017
|
+
payload.selector ?? "",
|
|
2018
|
+
payload.matchedText ?? "",
|
|
2019
|
+
payload.url ?? "",
|
|
2020
|
+
].join("|");
|
|
2021
|
+
if (policySeen.has(dedupeKey)) {
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
policySeen.add(dedupeKey);
|
|
2025
|
+
policyIndicators.push(payload);
|
|
2026
|
+
};
|
|
2027
|
+
|
|
2028
|
+
const metaByName = (name) => {
|
|
2029
|
+
const node = document.querySelector('meta[name="' + name + '"]');
|
|
2030
|
+
return node ? normalizeText(node.getAttribute("content")) || null : null;
|
|
2031
|
+
};
|
|
2032
|
+
const metaByProperty = (property) => {
|
|
2033
|
+
const node = document.querySelector('meta[property="' + property + '"]');
|
|
2034
|
+
return node ? normalizeText(node.getAttribute("content")) || null : null;
|
|
2035
|
+
};
|
|
2036
|
+
const schemaTypesRaw = [];
|
|
2037
|
+
const collectSchemaTypes = (value) => {
|
|
2038
|
+
if (Array.isArray(value)) {
|
|
2039
|
+
for (const item of value) {
|
|
2040
|
+
collectSchemaTypes(item);
|
|
2041
|
+
}
|
|
2042
|
+
return;
|
|
2043
|
+
}
|
|
2044
|
+
if (!value || typeof value !== "object") {
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
const maybeType = value["@type"];
|
|
2048
|
+
if (typeof maybeType === "string") {
|
|
2049
|
+
schemaTypesRaw.push(maybeType);
|
|
2050
|
+
} else if (Array.isArray(maybeType)) {
|
|
2051
|
+
for (const entry of maybeType) {
|
|
2052
|
+
if (typeof entry === "string") {
|
|
2053
|
+
schemaTypesRaw.push(entry);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
for (const nested of Object.values(value)) {
|
|
2058
|
+
if (nested && typeof nested === "object") {
|
|
2059
|
+
collectSchemaTypes(nested);
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
};
|
|
2063
|
+
for (const script of Array.from(document.querySelectorAll('script[type="application/ld+json"]'))) {
|
|
2064
|
+
const text = normalizeText(script.textContent);
|
|
2065
|
+
if (!text) {
|
|
2066
|
+
continue;
|
|
2067
|
+
}
|
|
2068
|
+
try {
|
|
2069
|
+
const parsed = JSON.parse(text);
|
|
2070
|
+
collectSchemaTypes(parsed);
|
|
2071
|
+
} catch (_e) {
|
|
2072
|
+
// ignore malformed JSON-LD blocks
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
const scriptLikeUrls = uniqSorted(
|
|
2077
|
+
Array.from(document.querySelectorAll("script[src],link[href],img[src]"))
|
|
2078
|
+
.map((node) => {
|
|
2079
|
+
if (node instanceof HTMLScriptElement) {
|
|
2080
|
+
return node.getAttribute("src");
|
|
2081
|
+
}
|
|
2082
|
+
if (node instanceof HTMLLinkElement) {
|
|
2083
|
+
return node.getAttribute("href");
|
|
2084
|
+
}
|
|
2085
|
+
if (node instanceof HTMLImageElement) {
|
|
2086
|
+
return node.getAttribute("src");
|
|
2087
|
+
}
|
|
2088
|
+
return "";
|
|
2089
|
+
})
|
|
2090
|
+
.map((value) => toAbsoluteHttpUrl(value))
|
|
2091
|
+
.filter((entry) => typeof entry === "string"),
|
|
2092
|
+
);
|
|
2093
|
+
const textCorpus = normalizeLower(
|
|
2094
|
+
[
|
|
2095
|
+
document.title ?? "",
|
|
2096
|
+
document.body?.innerText ?? "",
|
|
2097
|
+
document.documentElement?.getAttribute("lang") ?? "",
|
|
2098
|
+
].join(" "),
|
|
2099
|
+
);
|
|
2100
|
+
const metaGenerator = metaByName("generator");
|
|
2101
|
+
const ogType = metaByProperty("og:type");
|
|
2102
|
+
|
|
2103
|
+
const cmsIndicators = [];
|
|
2104
|
+
if (
|
|
2105
|
+
scriptLikeUrls.some((url) => url.includes("/bitrix/")) ||
|
|
2106
|
+
typeof window["BX"] === "object" ||
|
|
2107
|
+
Object.keys(window).some((key) => key.startsWith("bx_"))
|
|
2108
|
+
) {
|
|
2109
|
+
cmsIndicators.push("bitrix");
|
|
2110
|
+
}
|
|
2111
|
+
if (
|
|
2112
|
+
scriptLikeUrls.some((url) => url.includes("/wp-content/") || url.includes("/wp-includes/")) ||
|
|
2113
|
+
normalizeLower(metaGenerator).includes("wordpress")
|
|
2114
|
+
) {
|
|
2115
|
+
cmsIndicators.push("wordpress");
|
|
2116
|
+
}
|
|
2117
|
+
if (
|
|
2118
|
+
scriptLikeUrls.some((url) => url.includes("tilda")) ||
|
|
2119
|
+
typeof window["tilda"] !== "undefined"
|
|
2120
|
+
) {
|
|
2121
|
+
cmsIndicators.push("tilda");
|
|
2122
|
+
}
|
|
2123
|
+
if (
|
|
2124
|
+
scriptLikeUrls.some((url) => url.includes("joomla")) ||
|
|
2125
|
+
normalizeLower(metaGenerator).includes("joomla")
|
|
2126
|
+
) {
|
|
2127
|
+
cmsIndicators.push("joomla");
|
|
2128
|
+
}
|
|
2129
|
+
if (
|
|
2130
|
+
scriptLikeUrls.some((url) => url.includes("wixstatic.com")) ||
|
|
2131
|
+
textCorpus.includes("wix.com website builder")
|
|
2132
|
+
) {
|
|
2133
|
+
cmsIndicators.push("wix");
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
const platformIndicators = [];
|
|
2137
|
+
if (
|
|
2138
|
+
scriptLikeUrls.some((url) => url.includes("shopify")) ||
|
|
2139
|
+
typeof window["Shopify"] === "object"
|
|
2140
|
+
) {
|
|
2141
|
+
platformIndicators.push("shopify");
|
|
2142
|
+
}
|
|
2143
|
+
if (
|
|
2144
|
+
scriptLikeUrls.some((url) => url.includes("ecwid")) ||
|
|
2145
|
+
typeof window["Ecwid"] === "object"
|
|
2146
|
+
) {
|
|
2147
|
+
platformIndicators.push("ecwid");
|
|
2148
|
+
}
|
|
2149
|
+
if (
|
|
2150
|
+
scriptLikeUrls.some((url) => url.includes("insales")) ||
|
|
2151
|
+
textCorpus.includes("insales")
|
|
2152
|
+
) {
|
|
2153
|
+
platformIndicators.push("insales");
|
|
2154
|
+
}
|
|
2155
|
+
if (
|
|
2156
|
+
scriptLikeUrls.some((url) => url.includes("amocrm") || url.includes("hubspot"))
|
|
2157
|
+
) {
|
|
2158
|
+
platformIndicators.push("crm_marketing_stack");
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
const anchors = Array.from(document.querySelectorAll("a[href]"));
|
|
2162
|
+
const forms = Array.from(document.querySelectorAll("form"));
|
|
2163
|
+
|
|
2164
|
+
const checkoutTokens = [
|
|
2165
|
+
"cart",
|
|
2166
|
+
"checkout",
|
|
2167
|
+
"basket",
|
|
2168
|
+
"korzina",
|
|
2169
|
+
"\u043A\u043E\u0440\u0437\u0438\u043D",
|
|
2170
|
+
"checkout",
|
|
2171
|
+
"oforml",
|
|
2172
|
+
"\u043E\u0444\u043E\u0440\u043C",
|
|
2173
|
+
"\u0437\u0430\u043A\u0430\u0437",
|
|
2174
|
+
"order",
|
|
2175
|
+
"buy",
|
|
2176
|
+
"\u043A\u0443\u043F\u0438\u0442\u044C",
|
|
2177
|
+
"\u043E\u043F\u043B\u0430\u0442",
|
|
2178
|
+
];
|
|
2179
|
+
const accountTokens = [
|
|
2180
|
+
"login",
|
|
2181
|
+
"sign in",
|
|
2182
|
+
"signin",
|
|
2183
|
+
"register",
|
|
2184
|
+
"registration",
|
|
2185
|
+
"account",
|
|
2186
|
+
"cabinet",
|
|
2187
|
+
"auth",
|
|
2188
|
+
"\u0432\u0445\u043E\u0434",
|
|
2189
|
+
"\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446",
|
|
2190
|
+
"\u043B\u0438\u0447\u043D\u044B\u0439 \u043A\u0430\u0431\u0438\u043D\u0435\u0442",
|
|
2191
|
+
"\u0430\u043A\u043A\u0430\u0443\u043D\u0442",
|
|
2192
|
+
"\u043F\u0440\u043E\u0444\u0438\u043B\u044C",
|
|
2193
|
+
];
|
|
2194
|
+
const leadTokens = [
|
|
2195
|
+
"contact",
|
|
2196
|
+
"callback",
|
|
2197
|
+
"quote",
|
|
2198
|
+
"consult",
|
|
2199
|
+
"request",
|
|
2200
|
+
"kontakt",
|
|
2201
|
+
"anfrage",
|
|
2202
|
+
"beratung",
|
|
2203
|
+
"\u0441\u0432\u044F\u0437",
|
|
2204
|
+
"\u043E\u0431\u0440\u0430\u0442\u043D",
|
|
2205
|
+
"\u0437\u0430\u044F\u0432\u043A",
|
|
2206
|
+
"\u043A\u043E\u043D\u0441\u0443\u043B\u044C\u0442\u0430\u0446",
|
|
2207
|
+
];
|
|
2208
|
+
const subscribeTokens = [
|
|
2209
|
+
"subscribe",
|
|
2210
|
+
"subscription",
|
|
2211
|
+
"newsletter",
|
|
2212
|
+
"mailing",
|
|
2213
|
+
"\u043F\u043E\u0434\u043F\u0438\u0441",
|
|
2214
|
+
"\u0440\u0430\u0441\u0441\u044B\u043B",
|
|
2215
|
+
"sms",
|
|
2216
|
+
];
|
|
2217
|
+
const jobTokens = [
|
|
2218
|
+
"career",
|
|
2219
|
+
"vacancy",
|
|
2220
|
+
"job",
|
|
2221
|
+
"\u043A\u0430\u0440\u044C\u0435\u0440",
|
|
2222
|
+
"\u0432\u0430\u043A\u0430\u043D\u0441",
|
|
2223
|
+
"\u0440\u0435\u0437\u044E\u043C\u0435",
|
|
2224
|
+
"resume",
|
|
2225
|
+
"human resources",
|
|
2226
|
+
];
|
|
2227
|
+
const ugcTokens = [
|
|
2228
|
+
"comment",
|
|
2229
|
+
"review",
|
|
2230
|
+
"forum",
|
|
2231
|
+
"discussion",
|
|
2232
|
+
"feedback",
|
|
2233
|
+
"\u043A\u043E\u043C\u043C\u0435\u043D\u0442",
|
|
2234
|
+
"\u043E\u0442\u0437\u044B\u0432",
|
|
2235
|
+
"\u0444\u043E\u0440\u0443\u043C",
|
|
2236
|
+
];
|
|
2237
|
+
const healthTokens = [
|
|
2238
|
+
"clinic",
|
|
2239
|
+
"hospital",
|
|
2240
|
+
"doctor",
|
|
2241
|
+
"pharmacy",
|
|
2242
|
+
"telemedicine",
|
|
2243
|
+
"medical",
|
|
2244
|
+
"appointment",
|
|
2245
|
+
"\u043A\u043B\u0438\u043D\u0438\u043A",
|
|
2246
|
+
"\u043C\u0435\u0434\u0438\u0446",
|
|
2247
|
+
"\u0430\u043F\u0442\u0435\u043A",
|
|
2248
|
+
"\u0437\u0430\u043F\u0438\u0441\u044C \u043A \u0432\u0440\u0430\u0447\u0443",
|
|
2249
|
+
"\u043F\u0440\u0438\u0435\u043C",
|
|
2250
|
+
"\u0442\u0435\u043B\u0435\u043C\u0435\u0434",
|
|
2251
|
+
"\u0432\u0440\u0430\u0447",
|
|
2252
|
+
];
|
|
2253
|
+
const childrenTokens = [
|
|
2254
|
+
"kids",
|
|
2255
|
+
"children",
|
|
2256
|
+
"child",
|
|
2257
|
+
"teen",
|
|
2258
|
+
"toys",
|
|
2259
|
+
"toy store",
|
|
2260
|
+
"school for kids",
|
|
2261
|
+
"\u0434\u0435\u0442\u0441\u043A",
|
|
2262
|
+
"\u0434\u0435\u0442\u0435\u0439",
|
|
2263
|
+
"\u0448\u043A\u043E\u043B\u044C\u043D\u0438\u043A",
|
|
2264
|
+
"\u0440\u043E\u0434\u0438\u0442\u0435\u043B",
|
|
2265
|
+
"0+",
|
|
2266
|
+
"3+",
|
|
2267
|
+
"6+",
|
|
2268
|
+
"12+",
|
|
2269
|
+
"16+",
|
|
2270
|
+
"18+",
|
|
2271
|
+
"parental consent",
|
|
2272
|
+
];
|
|
2273
|
+
|
|
2274
|
+
const containsAnyToken = (value, tokens) => {
|
|
2275
|
+
const lower = normalizeLower(value);
|
|
2276
|
+
if (!lower) {
|
|
2277
|
+
return false;
|
|
2278
|
+
}
|
|
2279
|
+
return tokens.some((token) => lower.includes(token));
|
|
2280
|
+
};
|
|
2281
|
+
|
|
2282
|
+
for (const anchor of anchors) {
|
|
2283
|
+
const text = snippetText(anchor);
|
|
2284
|
+
const href = anchor.getAttribute("href") ?? "";
|
|
2285
|
+
const joined = text + " " + href;
|
|
2286
|
+
const selector = compactSelector(anchor);
|
|
2287
|
+
const url = getAnchorUrl(anchor);
|
|
2288
|
+
if (containsAnyToken(joined, checkoutTokens)) {
|
|
2289
|
+
pushCapability("observed_checkout_flow", "link", selector, text || href, url);
|
|
2290
|
+
}
|
|
2291
|
+
if (containsAnyToken(joined, accountTokens)) {
|
|
2292
|
+
pushCapability("observed_account_area", "link", selector, text || href, url);
|
|
2293
|
+
}
|
|
2294
|
+
if (containsAnyToken(joined, leadTokens)) {
|
|
2295
|
+
pushCapability("observed_lead_forms", "link", selector, text || href, url);
|
|
2296
|
+
}
|
|
2297
|
+
if (containsAnyToken(joined, jobTokens)) {
|
|
2298
|
+
pushCapability("observed_job_application_flow", "link", selector, text || href, url);
|
|
2299
|
+
}
|
|
2300
|
+
if (containsAnyToken(joined, ugcTokens)) {
|
|
2301
|
+
pushCapability("observed_user_generated_content", "link", selector, text || href, url);
|
|
2302
|
+
}
|
|
2303
|
+
if (containsAnyToken(joined, healthTokens)) {
|
|
2304
|
+
pushCapability("inferred_health_context", "content", selector, text || href, url);
|
|
2305
|
+
}
|
|
2306
|
+
if (containsAnyToken(joined, childrenTokens)) {
|
|
2307
|
+
pushCapability("inferred_children_targeting", "content", selector, text || href, url);
|
|
2308
|
+
}
|
|
2309
|
+
if (
|
|
2310
|
+
containsAnyToken(joined, [
|
|
2311
|
+
"privacy",
|
|
2312
|
+
"datenschutz",
|
|
2313
|
+
"datenverarbeitung",
|
|
2314
|
+
"privacy notice",
|
|
2315
|
+
"\u043A\u043E\u043D\u0444\u0438\u0434\u0435\u043D",
|
|
2316
|
+
"personal data",
|
|
2317
|
+
"\u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D",
|
|
2318
|
+
"\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A",
|
|
2319
|
+
])
|
|
2320
|
+
) {
|
|
2321
|
+
pushPolicy("observed_privacy_policy_link", "link", selector, text || href, url);
|
|
2322
|
+
}
|
|
2323
|
+
if (containsAnyToken(joined, ["cookie", "cookies", "\u0444\u0430\u0439\u043B\u044B cookie", "\u043A\u0443\u043A\u0438"])) {
|
|
2324
|
+
pushPolicy("observed_cookie_policy_link", "link", selector, text || href, url);
|
|
2325
|
+
}
|
|
2326
|
+
if (
|
|
2327
|
+
containsAnyToken(joined, [
|
|
2328
|
+
"offer",
|
|
2329
|
+
"\u043E\u0444\u0435\u0440\u0442\u0430",
|
|
2330
|
+
"terms of service",
|
|
2331
|
+
"terms of use",
|
|
2332
|
+
"\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u043E\u0435 \u0441\u043E\u0433\u043B\u0430\u0448\u0435\u043D\u0438\u0435",
|
|
2333
|
+
"\u0443\u0441\u043B\u043E\u0432\u0438\u044F \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F",
|
|
2334
|
+
])
|
|
2335
|
+
) {
|
|
2336
|
+
pushPolicy("observed_public_offer_link", "link", selector, text || href, url);
|
|
2337
|
+
}
|
|
2338
|
+
if (
|
|
2339
|
+
containsAnyToken(joined, [
|
|
2340
|
+
"delivery",
|
|
2341
|
+
"returns",
|
|
2342
|
+
"return policy",
|
|
2343
|
+
"shipping",
|
|
2344
|
+
"\u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0430",
|
|
2345
|
+
"\u0432\u043E\u0437\u0432\u0440\u0430\u0442",
|
|
2346
|
+
"\u043E\u043F\u043B\u0430\u0442\u0430",
|
|
2347
|
+
])
|
|
2348
|
+
) {
|
|
2349
|
+
pushPolicy("observed_delivery_return_links", "link", selector, text || href, url);
|
|
2350
|
+
}
|
|
2351
|
+
if (
|
|
2352
|
+
containsAnyToken(joined, [
|
|
2353
|
+
"data subject",
|
|
2354
|
+
"right to erasure",
|
|
2355
|
+
"right to access",
|
|
2356
|
+
"\u043F\u0440\u0430\u0432\u0430 \u0441\u0443\u0431\u044A\u0435\u043A\u0442\u0430",
|
|
2357
|
+
"\u043E\u0442\u0437\u044B\u0432 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u044F",
|
|
2358
|
+
"\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0445",
|
|
2359
|
+
])
|
|
2360
|
+
) {
|
|
2361
|
+
pushPolicy("observed_data_subject_rights_link", "link", selector, text || href, url);
|
|
2362
|
+
}
|
|
2363
|
+
if (
|
|
2364
|
+
containsAnyToken(joined, [
|
|
2365
|
+
"complaint",
|
|
2366
|
+
"appeal",
|
|
2367
|
+
"feedback",
|
|
2368
|
+
"\u0436\u0430\u043B\u043E\u0431",
|
|
2369
|
+
"\u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438",
|
|
2370
|
+
"\u043E\u0431\u0440\u0430\u0442\u043D\u0430\u044F \u0441\u0432\u044F\u0437\u044C",
|
|
2371
|
+
"\u044D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
2372
|
+
])
|
|
2373
|
+
) {
|
|
2374
|
+
pushPolicy("observed_feedback_or_appeal_channel", "link", selector, text || href, url);
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
for (const form of forms) {
|
|
2379
|
+
const selector = compactSelector(form);
|
|
2380
|
+
const formText = normalizeText(
|
|
2381
|
+
[
|
|
2382
|
+
snippetText(form),
|
|
2383
|
+
form.getAttribute("action") ?? "",
|
|
2384
|
+
Array.from(form.querySelectorAll("input,textarea,button,label"))
|
|
2385
|
+
.map((node) =>
|
|
2386
|
+
normalizeText(
|
|
2387
|
+
(node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement)
|
|
2388
|
+
? [node.name, node.id, node.placeholder, node.value].join(" ")
|
|
2389
|
+
: node.textContent,
|
|
2390
|
+
),
|
|
2391
|
+
)
|
|
2392
|
+
.join(" "),
|
|
2393
|
+
].join(" "),
|
|
2394
|
+
);
|
|
2395
|
+
const formUrl = getFormUrl(form);
|
|
2396
|
+
const hasPassword = form.querySelector('input[type="password"]') !== null;
|
|
2397
|
+
const hasEmail = form.querySelector('input[type="email"]') !== null;
|
|
2398
|
+
const hasTextarea = form.querySelector("textarea") !== null;
|
|
2399
|
+
const hasFile = form.querySelector('input[type="file"]') !== null;
|
|
2400
|
+
const lower = normalizeLower(formText);
|
|
2401
|
+
const isCheckout = containsAnyToken(lower, checkoutTokens);
|
|
2402
|
+
const isAccount = hasPassword || containsAnyToken(lower, accountTokens);
|
|
2403
|
+
const isSubscribe = hasEmail && containsAnyToken(lower, subscribeTokens);
|
|
2404
|
+
const isJob = hasFile && containsAnyToken(lower, jobTokens);
|
|
2405
|
+
|
|
2406
|
+
if (isCheckout) {
|
|
2407
|
+
pushCapability("observed_checkout_flow", "form", selector, formText, formUrl);
|
|
2408
|
+
}
|
|
2409
|
+
if (isAccount) {
|
|
2410
|
+
pushCapability("observed_account_area", "form", selector, formText, formUrl);
|
|
2411
|
+
}
|
|
2412
|
+
if (isSubscribe) {
|
|
2413
|
+
pushCapability("observed_marketing_subscribe", "form", selector, formText, formUrl);
|
|
2414
|
+
}
|
|
2415
|
+
if (isJob) {
|
|
2416
|
+
pushCapability("observed_job_application_flow", "form", selector, formText, formUrl);
|
|
2417
|
+
}
|
|
2418
|
+
if (
|
|
2419
|
+
!isCheckout &&
|
|
2420
|
+
!isAccount &&
|
|
2421
|
+
!isSubscribe &&
|
|
2422
|
+
(hasTextarea || form.querySelectorAll("input").length >= 2 || containsAnyToken(lower, leadTokens))
|
|
2423
|
+
) {
|
|
2424
|
+
pushCapability("observed_lead_forms", "form", selector, formText, formUrl);
|
|
2425
|
+
}
|
|
2426
|
+
if (containsAnyToken(lower, ugcTokens)) {
|
|
2427
|
+
pushCapability("observed_user_generated_content", "form", selector, formText, formUrl);
|
|
2428
|
+
}
|
|
2429
|
+
if (
|
|
2430
|
+
containsAnyToken(lower, [
|
|
2431
|
+
"complaint",
|
|
2432
|
+
"appeal",
|
|
2433
|
+
"feedback",
|
|
2434
|
+
"\u0436\u0430\u043B\u043E\u0431",
|
|
2435
|
+
"\u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438",
|
|
2436
|
+
"\u043E\u0431\u0440\u0430\u0442\u043D\u0430\u044F \u0441\u0432\u044F\u0437\u044C",
|
|
2437
|
+
"\u044D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
2438
|
+
])
|
|
2439
|
+
) {
|
|
2440
|
+
pushPolicy("observed_feedback_or_appeal_channel", "form", selector, formText, formUrl);
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
const paymentProviders = [
|
|
2445
|
+
["yookassa", /yookassa|yoomoney|yoo\\.kassa/i],
|
|
2446
|
+
["robokassa", /robokassa/i],
|
|
2447
|
+
["cloudpayments", /cloudpayments/i],
|
|
2448
|
+
["stripe", /stripe\\.com|js\\.stripe/i],
|
|
2449
|
+
["paypal", /paypal\\.com|paypalobjects/i],
|
|
2450
|
+
["sberbank", /sberbank|ecom\\.sberbank/i],
|
|
2451
|
+
["tbank", /tinkoff|tbank/i],
|
|
2452
|
+
];
|
|
2453
|
+
for (const script of Array.from(document.querySelectorAll("script[src]"))) {
|
|
2454
|
+
const src = script.getAttribute("src") ?? "";
|
|
2455
|
+
const absolute = toAbsoluteHttpUrl(src);
|
|
2456
|
+
if (!absolute) {
|
|
2457
|
+
continue;
|
|
2458
|
+
}
|
|
2459
|
+
for (const [provider, pattern] of paymentProviders) {
|
|
2460
|
+
if (pattern.test(absolute)) {
|
|
2461
|
+
pushCapability(
|
|
2462
|
+
"observed_payment_provider",
|
|
2463
|
+
"script",
|
|
2464
|
+
compactSelector(script),
|
|
2465
|
+
provider,
|
|
2466
|
+
absolute,
|
|
2467
|
+
);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
if (/esia|gosuslugi/i.test(absolute)) {
|
|
2471
|
+
pushCapability(
|
|
2472
|
+
"observed_gov_auth_integration",
|
|
2473
|
+
"script",
|
|
2474
|
+
compactSelector(script),
|
|
2475
|
+
"esia",
|
|
2476
|
+
absolute,
|
|
2477
|
+
);
|
|
2478
|
+
}
|
|
2479
|
+
if (
|
|
2480
|
+
/google-analytics|googletagmanager|doubleclick|facebook|connect\\.facebook|hotjar|clarity|intercom|amplitude|mixpanel|segment/i.test(
|
|
2481
|
+
absolute,
|
|
2482
|
+
)
|
|
2483
|
+
) {
|
|
2484
|
+
pushCapability(
|
|
2485
|
+
"observed_cross_border_services",
|
|
2486
|
+
"script",
|
|
2487
|
+
compactSelector(script),
|
|
2488
|
+
absolute,
|
|
2489
|
+
absolute,
|
|
2490
|
+
);
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
if (
|
|
2495
|
+
document.querySelector(
|
|
2496
|
+
[
|
|
2497
|
+
"[class*='comment']",
|
|
2498
|
+
"[id*='comment']",
|
|
2499
|
+
"[class*='review']",
|
|
2500
|
+
"[id*='review']",
|
|
2501
|
+
"[class*='forum']",
|
|
2502
|
+
"[id*='forum']",
|
|
2503
|
+
"textarea[name*='comment']",
|
|
2504
|
+
].join(","),
|
|
2505
|
+
)
|
|
2506
|
+
) {
|
|
2507
|
+
pushCapability("observed_user_generated_content", "content", null, "ugc_markup", null);
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
if (
|
|
2511
|
+
textCorpus.includes("esia") ||
|
|
2512
|
+
textCorpus.includes("\u0433\u043E\u0441\u0443\u0441\u043B\u0443\u0433") ||
|
|
2513
|
+
window.location.hostname.endsWith(".gov.ru") ||
|
|
2514
|
+
window.location.hostname.endsWith(".gov.by")
|
|
2515
|
+
) {
|
|
2516
|
+
pushCapability(
|
|
2517
|
+
"observed_gov_auth_integration",
|
|
2518
|
+
window.location.hostname.endsWith(".gov.ru") || window.location.hostname.endsWith(".gov.by")
|
|
2519
|
+
? "domain"
|
|
2520
|
+
: "content",
|
|
2521
|
+
null,
|
|
2522
|
+
window.location.hostname,
|
|
2523
|
+
window.location.href,
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
if (containsAnyToken(textCorpus, healthTokens)) {
|
|
2528
|
+
pushCapability("inferred_health_context", "content", "body", "health_terms", window.location.href);
|
|
2529
|
+
}
|
|
2530
|
+
if (containsAnyToken(textCorpus, childrenTokens)) {
|
|
2531
|
+
pushCapability("inferred_children_targeting", "content", "body", "children_terms", window.location.href);
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
const technicalSignals = {
|
|
2535
|
+
metaGenerator,
|
|
2536
|
+
ogType,
|
|
2537
|
+
schemaTypes: uniqSorted(schemaTypesRaw),
|
|
2538
|
+
cmsIndicators: uniqSorted(cmsIndicators),
|
|
2539
|
+
platformIndicators: uniqSorted(platformIndicators),
|
|
2540
|
+
};
|
|
2541
|
+
|
|
2542
|
+
const metaDescription =
|
|
2543
|
+
metaByName("description") ||
|
|
2544
|
+
metaByProperty("og:description") ||
|
|
2545
|
+
metaByName("twitter:description");
|
|
2546
|
+
const canonicalLink = document.querySelector('link[rel="canonical"]');
|
|
2547
|
+
const canonicalUrl = canonicalLink
|
|
2548
|
+
? toAbsoluteHttpUrl(canonicalLink.getAttribute("href"))
|
|
2549
|
+
: null;
|
|
2550
|
+
const htmlLang = normalizeText(document.documentElement.lang) || null;
|
|
2551
|
+
|
|
2552
|
+
const favicon = resolveFavicon();
|
|
2553
|
+
return {
|
|
2554
|
+
faviconUrl: favicon.url,
|
|
2555
|
+
faviconFromExplicitLink: favicon.fromExplicitLink,
|
|
2556
|
+
sourcePageUrl: window.location.href,
|
|
2557
|
+
metaDescription,
|
|
2558
|
+
canonicalUrl,
|
|
2559
|
+
htmlLang,
|
|
2560
|
+
technicalSignals,
|
|
2561
|
+
capabilityIndicators,
|
|
2562
|
+
policyIndicators,
|
|
2563
|
+
};
|
|
2564
|
+
})()`}async function Ot(){let e=Co(import.meta.url),t=X.dirname(Kr(import.meta.url)),o=X.resolve(t,"../../..");for(let a of[process.cwd(),X.join(o,"apps","cli"),X.join(o,"apps","worker"),X.join(o,"apps","web")])try{return Co(X.join(a,"package.json"))("playwright")}catch{}try{return e("playwright")}catch{return null}}async function Wr(e,t,o){return await(await e.chromium.launch(o)).close(),{available:!0,name:t,launchOptions:o}}async function Oe(e={}){let t=e.playwright??await Ot(),o=[];if(!t)return{available:!1,installHint:"Run: npx playwright install chromium",attempts:[{name:"playwright-chromium",error:"playwright package is not available"}]};let a=[{name:"chrome",launchOptions:{channel:"chrome",headless:!0}},{name:"msedge",launchOptions:{channel:"msedge",headless:!0}},{name:"playwright-chromium",launchOptions:{headless:!0}}];for(let n of a)try{return await Wr(t,n.name,n.launchOptions)}catch(i){o.push({name:n.name,error:i instanceof Error?i.message:String(i)})}return{available:!1,installHint:"Run: npx playwright install chromium",attempts:o}}function Dt(e){try{return new URL(e).hostname}catch{return null}}function J(e){return[...new Set(e.filter(t=>!!t))].sort()}function De(e){return/(posthog|google-analytics|googletagmanager|segment|mixpanel|amplitude|clarity|facebook|doubleclick)/i.test(e)}var Gr=10;function zo(e){try{return new URL(e).hostname}catch{return null}}function Yr(e){return e==="local_storage"?"localStorage":e==="session_storage"?"sessionStorage":"indexedDB"}function Xr(e){if(e.key)return e.key;if(e.storageType!=="indexeddb")return null;let t=[e.databaseName,e.objectStoreName,e.collectionStatus].filter(Boolean);return t.length>0?t.join(":"):null}function Jr(e){return as(e.flatMap(t=>{let o=Xr(t);return o?[{type:Yr(t.storageType),key:o,value:t.value}]:[]}))}var Zr=200,_o=160,Qr=220,es=100,ts=100,ns=20;function os(e){let t=new Set,o=[];for(let a of e){let n=a.text.length>_o?a.text.slice(0,_o):a.text,i=`${a.href}\0${n}`;if(!t.has(i)&&(t.add(i),o.push({...a,text:n}),o.length>=Zr))break}return o}function as(e){let t={localStorage:es,sessionStorage:ts,indexedDB:ns},o={localStorage:0,sessionStorage:0,indexedDB:0},a=[];for(let n of e)if(!(o[n.type]>=t[n.type])&&(o[n.type]+=1,a.push(n),a.length>=Qr))break;return a}function is(e){return e.cookies.some(t=>/^(__ph_|ph_|posthog)/i.test(t.name))||e.storage.some(t=>/^(__ph_|ph_|posthog)/i.test(t.key))||e.knownGlobals.some(t=>/posthog/i.test(t))}function Nt(e){try{let t=new URL(e);return/posthog/i.test(t.hostname)||/\/array\/phc_/i.test(t.pathname)||/\/flags\/?$/i.test(t.pathname)||/\/static\/(?:exception-autocapture|surveys|dead-clicks-autocapture|web-vitals)\.js$/i.test(t.pathname)}catch{return!1}}function Ro(e){let t=new Set(e.trackerDomains.map(a=>a.toLowerCase()));return J(e.urls).filter(a=>{let n=zo(a)?.toLowerCase();return n?t.has(n)||De(n)||Nt(a):!1}).slice(0,e.limit??25)}function rs(e){let t=new Set(e.domains.filter(De)),o=is(e);for(let a of e.urls){let n=zo(a);n&&(De(n)||Nt(a)||o&&Nt(a))&&t.add(n)}if(e.knownGlobals.some(a=>/^(dataLayer|google_tag_manager|gtag|ga|fbq|ttq|hj|clarity|ym|analytics|amplitude)$/i.test(a)))for(let a of e.domains.filter(De))t.add(a);return[...t].sort()}var Po=/(?:^|\/)(?:privacy|cookie|cookies|legal|terms|gdpr|impressum|data-protection|datenschutz)(?:\/|$)/i;function ss(e){return!e||e==="/"?"/":e.startsWith("/")?e:`/${e}`}function Lo(e){let t=new Set(["/"]);for(let i of e)t.add(ss(i));let o=[...t],a=o.filter(i=>i!=="/"&&Po.test(i)).sort(),n=o.filter(i=>i!=="/"&&!Po.test(i)).sort();return["/",...a,...n]}function cs(e,t,o){let a=new Set;return t.map(n=>{try{return new URL(n,e).toString()}catch{return null}}).filter(n=>!!n).filter(n=>a.has(n)?!1:(a.add(n),!0)).slice(0,o)}function Uo(e){let t=e.routeCap??8,o=e.routes?.length?e.routes:["/"],a=e.consentModes??["none","accepted","declined"];return cs(e.targetUrl,o,t).flatMap(i=>a.map(r=>({routeUrl:i,consentMode:r,authenticated:e.authenticated})))}function Mo(e){return Uo({...e,consentModes:["none"]})}function Io(e){return Uo({targetUrl:e.targetUrl,routes:[e.routeUrl],authenticated:e.authenticated,routeCap:1,consentModes:["accepted","declined"]})}async function Z(e,t){return e.evaluate(t)}async function me(e,t){await new Promise(o=>setTimeout(o,t))}var ls=2e3,us=100;function To(e){return e.metaDescription?e.faviconFromExplicitLink!==!0:!0}async function ds(e){let t=await Z(e,It());if(!To(t))return t;let o=Date.now()+ls;for(;Date.now()<o&&(await me(e,us),t=await Z(e,It()),!!To(t)););return t}async function Ao(e){return Z(e,Ut({checkBanner:!0,acceptedModeKeywords:Ue,declinedModeKeywords:Me,settingsModeKeywords:jt}))}function jo(e){return e.consentBannerFound==="yes"&&F(e)}async function ms(e){let t=await Ao(e);if(!jo(t)){for(let o of zt)if(await me(e,o),t=await Ao(e),jo(t))break}return t}async function Do(e){let t=await Ot();if(!t)return Ie("playwright package is not available");let o=e.browserRuntime??await Oe({playwright:t});if(!o.available)return Ie("browser runtime is not available");let a=await t.chromium.launch(o.launchOptions);try{let n=await Ot();if(await a.close(),!n)return Ie("playwright package is not available");let i=await n.chromium.launch(o.launchOptions);try{let r=await i.newContext({storageState:e.storageState,...e.acceptLanguage?{extraHTTPHeaders:{"Accept-Language":e.acceptLanguage}}:{}}),s=await r.newPage(),c=[],l={};s.on("request",y=>{c.push(y.url())});let u=await s.goto(e.targetUrl,{waitUntil:"load",timeout:e.timeoutMs??15e3}),d=e.consentMode==="none"?1500:1200;await me(s,d);let m=await ms(s),p=wo(m),f=m.consentBannerSelectorForCapture,E={attempted:!1,succeeded:!0,action:"none"};if(e.consentMode&&e.consentMode!=="none"){let y=await Z(s,Mt({mode:e.consentMode,acceptedModeKeywords:Ue,declinedModeKeywords:Me,bannerRootSelector:f}));E=xo(e.consentMode,y,m),(y.consentOutcome==="clicked_accept"||y.consentOutcome==="clicked_decline")&&(await me(s,700),await me(s,Lt),await s.waitForLoadState?.("networkidle",{timeout:5e3}).catch(()=>{}))}let x=u?.headers?.()??{};for(let y of["content-security-policy","strict-transport-security","x-frame-options","x-content-type-options","referrer-policy"])l[y]=x[y]??null;let S=await s.title().catch(()=>null),h=S&&S.trim()?S.trim():null,k=await Z(s,So(Gr)),P=Jr(k),j=os(await s.evaluate(()=>Array.from(document.querySelectorAll("a[href]")).map((y,z)=>{let R=y;return{href:R.href||R.getAttribute("href")||"",text:(R.textContent||R.getAttribute("aria-label")||"").replace(/\s+/g," ").trim(),selector:`a[href]:nth-of-type(${z+1})`}}))),T=await r.cookies(),_=await Z(s,Eo()),C=await ds(s),B=J([...c,..._.resourceUrls,..._.loadedScriptUrls]),U=J(c.map(Dt)),he=J([...c.filter(y=>/\.(js|mjs)(\?|$)/.test(y)),..._.loadedScriptUrls].map(Dt)),ne=J(B.map(Dt)),A=rs({domains:ne,urls:B,cookies:T,storage:P,knownGlobals:_.knownGlobals}),M=await ps(s,!!e.includeAccessibility);return await r.close(),{characterization:m,evidence:{navigationSucceeded:!0,finalUrl:s.url(),status:u?.status?.()??null,title:h,securityHeaders:l,cookies:T.map(y=>{let z=y.expires,R=Number.isFinite(z)&&(z??0)>0;return{name:y.name,value:y.value,domain:y.domain,path:y.path,expiry:R?new Date(z*1e3).toISOString():null,isSession:!R,secure:y.secure,httpOnly:y.httpOnly,sameSite:y.sameSite}}),storage:P,requestDomains:U,scriptDomains:he,resourceDomains:ne,trackerDomains:A,loadedScriptUrls:Ro({urls:_.loadedScriptUrls,trackerDomains:A}),resourceUrls:Ro({urls:_.resourceUrls,trackerDomains:A}),pageSiteSignals:{faviconUrl:C.faviconUrl??null,faviconFromExplicitLink:C.faviconFromExplicitLink===!0,metaDescription:C.metaDescription??null,canonicalUrl:C.canonicalUrl??null,htmlLang:C.htmlLang??null,policyLinkUrls:J((C.policyIndicators??[]).map(y=>y.url).filter(y=>typeof y=="string"&&y.length>0))},knownGlobals:_.knownGlobals,renderedLinks:j,consent:p,accessibility:M},consentInteraction:E}}finally{await i.close()}}catch(n){return Ie(n instanceof Error?n.message:String(n))}}async function ps(e,t){if(!t)return{scanned:!1,violations:[],skippedReason:"accessibility scan disabled"};try{let a=await new Function("specifier","return import(specifier)")("@axe-core/playwright"),n=a.default??a.AxeBuilder;return{scanned:!0,violations:(await new n({page:e}).analyze()).violations.map(r=>({id:String(r.id),impact:r.impact?String(r.impact):null,description:String(r.description),nodes:Array.isArray(r.nodes)?r.nodes.length:0}))}}catch(o){return{scanned:!1,violations:[],skippedReason:o instanceof Error?o.message:"axe scan unavailable"}}}function gs(e){return{navigationSucceeded:!1,finalUrl:null,status:null,title:null,securityHeaders:{},cookies:[],storage:[],requestDomains:[],scriptDomains:[],resourceDomains:[],trackerDomains:[],consent:{bannerFound:!1,acceptPresent:!1,rejectPresent:!1,settingsPresent:!1,detectionConfidence:"low",detectionBasis:e},accessibility:{scanned:!1,violations:[],skippedReason:e},skippedReason:e}}function Ie(e){return{characterization:{consentBannerFound:"no",consentDetectionConfidence:"low",consentBannerDetectionBasis:e,consentCaptureQualityClass:"unusable",consentButtons:{acceptPresent:!1,declinePresent:!1,settingsPresent:!1},consentBannerSelectorForCapture:null,consentUx:null},evidence:gs(e),consentInteraction:{attempted:!1,succeeded:!1,action:"none",error:e}}}var Bo="Scanning project evidence...",qo="Project evidence scanned.",Fo="Building redacted evidence package...",Ho="Redacted evidence package built.",Vo=10,fs=2;async function $t(e,t,o,a){t&&e.start(o.start),await a(),t&&e.success(o.success)}async function hs(e,t,o,a=null){let n={"content-type":"application/json"};o&&(n.authorization=`Bearer ${o}`);let i=Y(t,a),r=await fetch(e,{method:"POST",headers:n,body:JSON.stringify(i)});if(!r.ok){let s=await r.text().catch(()=>"");throw new Error(`Upload failed with ${r.status}${s?`: ${s.slice(0,240)}`:""}`)}return await r.json().catch(()=>({}))}async function Bt(e){if(!(e.forceUpload??oo(e.args)))return{exitCode:0};let o=e.sink??{log:r=>console.log(r),error:r=>console.error(r)},a=e.upload??hs,n=e.poll??ho,i=await ao(e.args,e.prepareDeps);if(!i.ok)return o.error(i.error),{exitCode:1};e.progress.start("Uploading redacted evidence package...");try{let r=await a(i.uploadUrl,e.evidencePackage,i.session.token,e.securityEvidence??null);if(e.progress.success("Upload succeeded."),r.analysisStatus==="stored_only")return o.log(r.message??"Evidence stored. Report analysis is not generated yet."),{exitCode:0,scanId:r.scanId,reportUrl:r.reportUrl??void 0};let s=r.scanId??e.evidencePackage.scanId;if(r.analysisStatus==="pending"&&r.statusUrl){e.progress.start("Waiting for security grading...");let c=await n({statusUrl:r.statusUrl,bearerToken:i.session.token,webUrl:i.session.webUrl,scanId:s},e.pollDeps);if(e.progress.success("Security grading finished."),c.outcome==="ready"){let l=c.reportUrl??`${i.session.webUrl}/app/scans/${s}`;return e.args.json||o.log(`Report ready: ${l}`),{exitCode:0,scanId:s,reportUrl:l}}return c.outcome==="failed"?(o.error(c.error??"Security grading failed."),{exitCode:1,scanId:s}):(e.args.json||o.log(yo(i.session.webUrl,s)),{exitCode:0,scanId:s})}return r.reportUrl?(e.args.json||o.log(`Report: ${r.reportUrl}`),{exitCode:0,scanId:s,reportUrl:r.reportUrl}):{exitCode:0,scanId:s}}catch(r){return e.progress.stop(),o.error(r instanceof Error?r.message:String(r)),{exitCode:1}}}function Oo(e){if(!e||e==="/")return"/";let t=e.trim();return(t.startsWith("/")?t:`/${t}`).replace(/\/+$/,"")||"/"}function ys(e){return`Runtime baseline routes: ${e.join(", ")}`}function bs(e,t=Vo,o=fs){let a=new Set(["/"]);for(let n of e.runtimeRouteCandidates??[])a.add(Oo(n));for(let n of e.policyCandidates??[])a.add(Oo(n.path));return Lo([...a]).slice(0,t)}function No(e){return`Collecting ${new URL(e.routeUrl).pathname} (${e.consentMode})`}function $o(e,t){let o=new URL(e.routeUrl).pathname;return{profileId:`${e.authenticated?"authenticated":"anonymous"}:${o}:${e.consentMode}`,routeUrl:e.routeUrl,consentMode:e.consentMode,authenticated:e.authenticated,evidence:t.evidence,consentInteraction:t.consentInteraction}}async function Ko(e){let t=e.collect??Do,o=e.routeCap??Vo,a=bs(e.projectEvidence,o,e.pagesPerLevel);e.verbose&&(e.log??(l=>console.log(l)))(ys(a));let n=Mo({targetUrl:e.targetUrl,routes:a,authenticated:e.authenticated,routeCap:o}),i=[],r=[],s=[];for(let[c,l]of n.entries()){e.progress.runtimeProgress(c+1,n.length,No(l));let u=await t({targetUrl:l.routeUrl,storageState:e.storageState,browserRuntime:e.browserRuntime,consentMode:l.consentMode,includeAccessibility:!1,...e.acceptLanguage?{acceptLanguage:e.acceptLanguage}:{}});if(r.push($o(l,u)),F(u.characterization)){let d=new URL(l.routeUrl).pathname;u.evidence.consent.acceptPresent||s.push(`Consent banner on ${d} has no accept control; accept phase may be incomplete`),u.evidence.consent.rejectPresent||s.push(`Consent banner on ${d} has no reject control; decline phase may be incomplete`),i.push(...Io({targetUrl:e.targetUrl,routeUrl:l.routeUrl,authenticated:e.authenticated}))}else if(u.evidence.consent.bannerFound){let d=new URL(l.routeUrl).pathname;s.push(`Skipped consent variants for ${d}: banner detection was too weak to interact safely`)}else{let d=new URL(l.routeUrl).pathname;s.push(`Skipped consent variants for ${d}: no consent banner found`)}}for(let[c,l]of i.entries()){e.progress.runtimeProgress(c+1,i.length,No(l));let u=await t({targetUrl:l.routeUrl,storageState:e.storageState,browserRuntime:e.browserRuntime,consentMode:l.consentMode,includeAccessibility:!1,...e.acceptLanguage?{acceptLanguage:e.acceptLanguage}:{}});r.push($o(l,u))}return e.progress.success(`Runtime evidence collected (${r.length} profiles).`),{profiles:r,warnings:s}}var Ne=512e3;import{readdir as ks,readFile as Wo,stat as vs}from"node:fs/promises";import $e from"node:path";var ws=new Set(["node_modules",".next","dist","build","coverage","out",".git",".vibemole",".cache",".turbo"]),Go=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".json",".yml",".yaml",".toml",".sql",".rules",".env",".local"]),Yo=new Set([".env",".env.local",".env.development",".env.production",".env.test",".env.example",".env.sample",".gitignore",".dockerignore","Dockerfile","docker-compose.yml","docker-compose.yaml","firebase.json","firestore.rules","storage.rules","package.json","package-lock.json","pnpm-lock.yaml","yarn.lock","bun.lockb","next.config.js","next.config.mjs","next.config.ts"]),xs=new Set([".env",".env.local",".env.development",".env.production",".env.test",".env.example",".env.sample"]);function Ss(e,t){let o=e.replace(/\\/g,"/");if(xs.has(t)||t.startsWith(".env."))return"env";if(t==="Dockerfile"||t.startsWith("docker-compose")||o.startsWith(".github/workflows/")&&(t.endsWith(".yml")||t.endsWith(".yaml")))return"devops";if(o.startsWith("supabase/")&&t.endsWith(".sql"))return"sql";if(t.endsWith(".rules")||t==="firebase.json")return"rules";if(t==="package.json"||t==="package-lock.json"||t==="pnpm-lock.yaml"||t==="yarn.lock"||t==="bun.lockb")return"manifest";if(t===".gitignore"||t===".dockerignore"||t.startsWith("next.config."))return"config";let a=$e.extname(t);return Go.has(a)?a===".sql"?"sql":a===".json"||a===".yml"||a===".yaml"||a===".toml"?"config":"source":Yo.has(t)?t==="Dockerfile"||t.startsWith("docker-compose")?"devops":"config":null}function Es(e,t){if(Yo.has(t)||t.startsWith(".env."))return!0;let o=e.replace(/\\/g,"/");if(o.startsWith("supabase/")&&t.endsWith(".sql")||o.startsWith(".github/workflows/")&&(t.endsWith(".yml")||t.endsWith(".yaml")))return!0;let a=$e.extname(t);return Go.has(a)}async function Cs(e){let t=await Wo(e);return t.subarray(0,Math.min(t.length,8192)).includes(0)}async function Xo(e,t,o,a,n){let i;try{i=await ks(t,{withFileTypes:!0})}catch{return}for(let r of i){let s=$e.join(t,r.name),c=$e.relative(e,s).replace(/\\/g,"/");if(r.isDirectory()){if(ws.has(r.name))continue;await Xo(e,s,o,a,n);continue}if(!r.isFile()||!Es(c,r.name))continue;let l=Ss(c,r.name);if(!l)continue;let u;try{u=await vs(s)}catch{continue}if(u.size>Ne){a.push(c);continue}if(await Cs(s)){n.push(c);continue}o.push({relativePath:c,absolutePath:s,sizeBytes:u.size,kind:l})}}async function Jo(e){let t=[],o=[],a=[],n=[];return await Xo(e,e,t,o,a),t.sort((i,r)=>i.relativePath.localeCompare(r.relativePath)),{files:t,skippedLargeFiles:o,skippedBinaryFiles:a,warnings:n}}async function D(e){return Wo(e.absolutePath,"utf8")}var _s=[{prefix:"NEXT_PUBLIC_",ecosystemLabel:"Next.js"},{prefix:"NUXT_PUBLIC_",ecosystemLabel:"Nuxt"},{prefix:"EXPO_PUBLIC_",ecosystemLabel:"Expo"},{prefix:"REACT_APP_",ecosystemLabel:"Create React App"},{prefix:"VITE_",ecosystemLabel:"Vite"},{prefix:"GATSBY_",ecosystemLabel:"Gatsby"},{prefix:"PUBLIC_",ecosystemLabel:"SvelteKit / generic public"}],Be=new Set(["NEXT_PUBLIC_SUPABASE_ANON_KEY","VITE_FIREBASE_API_KEY","NEXT_PUBLIC_FIREBASE_API_KEY"]),Zo="Client-exposed environment variable contains private-looking value",Qo="Deployment workflow exposes private-looking value to frontend",ea="(?:sk_(?:live|test)_|sk-(?:ant-|proj-)?|AIza|(?:AKIA|ASIA)|ghp_|github_pat_|gho_|ghu_|ghs_|ghr_)";function ta(e){for(let{prefix:t,ecosystemLabel:o}of _s)if(e.startsWith(t))return{envName:e,prefix:t,ecosystemLabel:o};return null}function Rs(e){return new RegExp(ea).test(e)}function na(e){let t=e.trim();if(!t||t.startsWith("#"))return null;let o=t.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!o?.[1])return null;let a=o[1],n=ta(a);if(!n||Be.has(a))return null;let i=(o[2]??"").trim();if((i.startsWith('"')&&i.endsWith('"')||i.startsWith("'")&&i.endsWith("'"))&&(i=i.slice(1,-1)),!Rs(i))return null;let r=t.indexOf(a);return{...n,value:i,matchIndex:r>=0?r:0}}function oa(e){let o=new RegExp(`\\b([A-Z][A-Z0-9_]*)\\s*[:=]\\s*['"]?(${ea}[^\\s#'"]*)`).exec(e);if(!o?.[1]||!o[2])return null;let a=o[1],n=ta(a);return!n||Be.has(a)?null:{...n,value:o[2],matchIndex:o.index}}function aa(e,t){return`${e.envName} (${e.ecosystemLabel}, ${e.prefix}) in ${t} uses a value that resembles a private API key.`}function ia(e,t){return`${e}* variables (${t}) are exposed to the browser; values resembling private keys should be reviewed.`}function ra(e,t){return`${t} assigns a private-looking key to ${e.envName} (${e.ecosystemLabel}, ${e.prefix}).`}function sa(e,t){return`CI workflows must not publish private key patterns to ${e}* variables (${t}) that reach browser bundles.`}function qe(e){return{envName:e.envName,prefix:e.prefix,ecosystemLabel:e.ecosystemLabel}}var Ps=[/your[_-]?key[_-]?here/i,/changeme/i,/replace[_-]?me/i,/\bexample\b/i,/\btest\b/i,/\bdummy\b/i,/\bplaceholder\b/i,/\bxxx+\b/i,/<secret>/i],Ts=[{id:"secrets.stripe-secret-key",regex:/\bsk_(live|test)_[A-Za-z0-9]{8,}\b/g,title:"Stripe secret key",tag:"stripe"},{id:"secrets.openai-api-key",regex:/\bsk-proj-[A-Za-z0-9_-]{8,}\b/g,title:"OpenAI API key",tag:"openai"},{id:"secrets.anthropic-api-key",regex:/\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,title:"Anthropic API key",tag:"anthropic"},{id:"secrets.openai-api-key",regex:/\bsk-(?!ant-|proj-)[A-Za-z0-9_-]{12,}\b/g,title:"OpenAI API key",tag:"openai"},{id:"secrets.google-api-key",regex:/\bAIza[A-Za-z0-9_-]{20,}\b/g,title:"Google API key",tag:"google"},{id:"secrets.aws-access-key",regex:/\b(AKIA|ASIA)[A-Z0-9]{12,}\b/g,title:"AWS access key",tag:"aws"},{id:"secrets.github-token",regex:/\b(ghp_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|gho_[A-Za-z0-9_]{20,}|ghu_[A-Za-z0-9_]{20,}|ghs_[A-Za-z0-9_]{20,}|ghr_[A-Za-z0-9_]{20,})\b/g,title:"GitHub token",tag:"github"},{id:"secrets.private-key-block",regex:/-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/g,title:"Private key block",tag:"private-key"}],ca=/\b(?:JWT_SECRET|SESSION_SECRET|AUTH_SECRET|NEXTAUTH_SECRET|SECRET_KEY)\s*=\s*['"]([^'"]{12,})['"]/gi;function Q(e){let t=e.trim();if(t.length<=4)return"***";let o=[{prefix:"sk_live_"},{prefix:"sk_test_"},{prefix:"sk-proj-"},{prefix:"sk-ant-"},{prefix:"sk-"},{prefix:"github_pat_"},{prefix:"ghp_"},{prefix:"gho_"},{prefix:"ghu_"},{prefix:"ghs_"},{prefix:"ghr_"},{prefix:"AKIA"},{prefix:"ASIA"},{prefix:"AIza"}];for(let{prefix:i}of o)if(t.startsWith(i)&&t.length>i.length+4)return`${i}***${t.slice(-4)}`;if(t.includes("PRIVATE KEY"))return"-----BEGIN *** PRIVATE KEY-----";let a=t.slice(-4);return`${t.slice(0,Math.min(6,t.length-4))}***${a}`}function As(e){let t=e.trim();if(!t||t.startsWith("#"))return null;let o=t.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!o?.[1])return null;let a=(o[2]??"").trim();return(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),{name:o[1],value:a}}function js(e,t){let o=As(e);return!o||!Be.has(o.name)?!1:o.value.includes(t)}function zs(e){return Ps.some(t=>t.test(e))}function qt(e){return e.length<8||zs(e)||/^(true|false|null|undefined|\d+)$/i.test(e)?!1:/[A-Za-z0-9]/.test(e)}function Ft(e,t,o,a){return{file:e,line:t,column:o,excerpt:Q(a),redactionApplied:!0}}function Ls(e,t,o,a){let n=[],i=new Set;for(let c of Ts){c.regex.lastIndex=0;let l;for(;(l=c.regex.exec(o))!==null;){let u=l[0];if(js(o,u)||!qt(u))continue;let d=`${c.id}:${t}:${l.index}`;i.has(d)||(i.add(d),n.push({id:c.id,category:"secrets",riskKind:"secret_exposure",status:"observed",confidence:"high",matchType:"regex",title:c.title,detail:`Matched ${c.tag} secret pattern in ${e}.`,reason:a?"Sample env file contains a value that looks like a real secret rather than a placeholder.":"Source file contains a value matching a known secret credential pattern.",sources:[Ft(e,t,l.index+1,u)],tags:[c.tag,"secret-detector"]}))}}ca.lastIndex=0;let r;for(;(r=ca.exec(o))!==null;){let c=r[1]??"";if(!qt(c))continue;let l=`secrets.hardcoded-auth-secret:${t}:${r.index}`;i.has(l)||(i.add(l),n.push({id:"secrets.hardcoded-auth-secret",category:"secrets",riskKind:"secret_exposure",status:"observed",confidence:"medium",matchType:"heuristic",title:"Hardcoded auth secret",detail:`Hardcoded session/JWT secret in ${e}.`,reason:"Environment or config assignment uses a literal value that looks like a real auth secret.",sources:[Ft(e,t,r.index+1,c)],tags:["auth-secret","secret-detector"]}))}let s=na(o);if(s&&qt(s.value)){let c=`secrets.next-public-private-pattern:${s.envName}:${t}`;i.has(c)||(i.add(c),n.push({id:"secrets.next-public-private-pattern",category:"frontend_exposure",riskKind:"secret_exposure",status:"needs_review",confidence:"medium",matchType:"heuristic",title:Zo,detail:aa(s,e),reason:ia(s.prefix,s.ecosystemLabel),sources:[Ft(e,t,s.matchIndex+1,s.value)],tags:["client-exposed-env",s.prefix.replace(/_$/,"").toLowerCase(),"secret-detector"],metadata:qe(s)}))}return n}async function la(e){let t=[],o=new Set;for(let a of e){let i=(await D(a)).split(/\r?\n/),r=a.relativePath===".env.example"||a.relativePath===".env.sample"||a.relativePath.endsWith("/.env.example")||a.relativePath.endsWith("/.env.sample");for(let s=0;s<i.length;s+=1){let c=i[s]??"",l=Ls(a.relativePath,s+1,c,r);for(let u of l){let d=`${u.id}:${u.sources.map(m=>`${m.file}:${m.line}`).join(",")}`;o.has(d)||(o.add(d),t.push(u))}}}return t}var Ht=/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g;function pe(e,t,o,a){return{file:e,line:t,column:a,excerpt:Q(o),redactionApplied:!0}}function Us(e,t){let o=[],a=t.split(/\r?\n/),n=new Set;for(let i=0;i<a.length;i+=1){let r=a[i]??"",s=i+1;if(/\bNEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY\b/.test(r)){let c=`baas.supabase-service-role-next-public:${e}:${s}`;n.has(c)||(n.add(c),o.push({id:"baas.supabase-service-role-next-public",category:"baas_security",riskKind:"unsafe_baas_key_exposure",status:"observed",confidence:"high",matchType:"exact",title:"Supabase service role exposed via NEXT_PUBLIC",detail:`${e} references NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY.`,reason:"Service role keys must not use NEXT_PUBLIC_* names because they are bundled for the browser.",sources:[pe(e,s,r.trim())],tags:["supabase","service-role","next-public"]}))}if(/\bSUPABASE_SERVICE_ROLE_KEY\b/.test(r)&&!/\bNEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY\b/.test(r)){let c=`baas.supabase-service-role-reference:${e}:${s}`;n.has(c)||(n.add(c),o.push({id:"baas.supabase-service-role-reference",category:"baas_security",riskKind:"unsafe_baas_key_exposure",status:"needs_review",confidence:"medium",matchType:"exact",title:"Supabase service role key reference",detail:`${e} references SUPABASE_SERVICE_ROLE_KEY.`,reason:"Privileged Supabase service role material was referenced; verify it is server-only and not committed.",sources:[pe(e,s,r.trim())],tags:["supabase","service-role"]}))}if(/\bservice_role\b/i.test(r)&&!/\bSUPABASE_SERVICE_ROLE_KEY\b/.test(r)){let c=`baas.supabase-service-role-reference:literal:${e}:${s}`;n.has(c)||(n.add(c),o.push({id:"baas.supabase-service-role-reference",category:"baas_security",riskKind:"unsafe_baas_key_exposure",status:"needs_review",confidence:"low",matchType:"heuristic",title:"Supabase service_role reference",detail:`${e} mentions service_role.`,reason:"Literal service_role references may indicate privileged Supabase client configuration.",sources:[pe(e,s,r.trim())],tags:["supabase","service-role"]}))}if(/\bNEXT_PUBLIC_[A-Z0-9_]*SUPABASE[A-Z0-9_]*\b/.test(r)&&Ht.test(r)&&!/\bNEXT_PUBLIC_SUPABASE_ANON_KEY\b/.test(r)){Ht.lastIndex=0;let c=`baas.supabase-jwt-frontend-env:${e}:${s}`;n.has(c)||(n.add(c),o.push({id:"baas.supabase-service-role-next-public",category:"frontend_exposure",riskKind:"unsafe_baas_key_exposure",status:"needs_review",confidence:"medium",matchType:"heuristic",title:"JWT-like Supabase value in frontend env",detail:`${e} assigns a JWT-like value to a NEXT_PUBLIC Supabase variable.`,reason:"JWT-shaped values in NEXT_PUBLIC Supabase env names may expose privileged credentials to the browser.",sources:[pe(e,s,r.trim())],tags:["supabase","jwt","next-public"]})),Ht.lastIndex=0}if(/createClient\s*\([^)]*(?:service_role|SUPABASE_SERVICE_ROLE_KEY)/i.test(r)){let c=`baas.supabase-service-role-client-exposure:${e}:${s}`;n.has(c)||(n.add(c),o.push({id:"baas.supabase-service-role-client-exposure",category:"baas_security",riskKind:"unsafe_baas_key_exposure",status:"observed",confidence:"high",matchType:"heuristic",title:"Supabase client configured with service role",detail:`${e} passes service role material into createClient.`,reason:"createClient should use anon keys in browser-facing code; service role bypasses RLS.",sources:[pe(e,s,r.trim())],tags:["supabase","createClient","service-role"]}))}}return o}async function ua(e){let t=e.filter(n=>n.kind==="source"||n.kind==="env"||n.kind==="config"||n.kind==="sql"||n.kind==="devops"),o=[],a=new Set;for(let n of t){let i=await D(n);for(let r of Us(n.relativePath,i)){let s=`${r.id}:${r.sources.map(c=>`${c.file}:${c.line}`).join(",")}`;a.has(s)||(a.add(s),o.push(r))}}return o}function ge(e){let t=e.replace(/\\/g,"/"),o=t.split("/").filter(Boolean);return o[o.length-1]??t}function Ms(e,t){let o=t.startsWith("/")?t:`/${t}`,a=[];for(let n of e){let i=n.replace(/\\/g,"/");(i===t.replace(/^\//,"")||i.endsWith(o))&&a.push(n)}return a.sort((n,i)=>n.localeCompare(i))}function ee(e,t){return Ms(e,t)[0]}function Fe(e,t){let o=[];for(let a of e)ge(a)===t&&o.push(a);return o.sort((a,n)=>a.localeCompare(n))}function te(e,t){return Fe(e,t)[0]}var Is=[".env",".env.local",".env.production",".env.development.local"],Ds=["package-lock.json","pnpm-lock.yaml","yarn.lock","bun.lockb"],Os=[/\bsk_(live|test)_[A-Za-z0-9]{8,}\b/,/\bsk-(?:ant-|proj-)?[A-Za-z0-9_-]{12,}\b/,/\bAIza[A-Za-z0-9_-]{20,}\b/,/\b(AKIA|ASIA)[A-Z0-9]{12,}\b/,/\b(ghp_|github_pat_|gho_|ghu_|ghs_|ghr_)[A-Za-z0-9_]{20,}\b/];function Ns(e){return new Map(e.map(t=>[t.relativePath,t]))}function $s(e){return e?e.split(/\r?\n/).map(a=>a.trim()).filter(a=>a&&!a.startsWith("#")).some(a=>a===".env"||a===".env*"||a===".env.*"):!1}function Bs(e){return/^\s*USER\s+(?!root\b)/im.test(e)}async function fe(e,t){let o=e.get(t)??[...e.values()].find(a=>ge(a.relativePath)===ge(t));return o?D(o):null}async function da(e,t){let o=Ns(t),a=[],n=ee(o.keys(),".gitignore")??te(o.keys(),".gitignore"),i=ee(o.keys(),".dockerignore")??te(o.keys(),".dockerignore"),r=ee(o.keys(),"Dockerfile")??te(o.keys(),"Dockerfile"),s=ee(o.keys(),"package.json")??te(o.keys(),"package.json"),c=n?await fe(o,n):null,l=i?await fe(o,i):null,u=r?await fe(o,r):null,d=s?await fe(o,s):null,m=Is.filter(h=>o.has(h)||[...o.keys()].some(k=>ge(k)===h));m.length>0&&!$s(c)&&a.push({id:"devops.env-not-gitignored",category:"devops_deployment",riskKind:"deployment_leakage",status:"observed",confidence:"high",matchType:"absence",title:"Env files may not be gitignored",detail:`Found ${m.join(", ")} but .gitignore does not ignore .env or .env*.`,reason:"Environment files with secrets often exist in the repo; missing .env gitignore patterns increase accidental commit risk.",sources:m.map(h=>({file:ee(o.keys(),h)??te(o.keys(),h)??h,line:1})),tags:["gitignore","env"],metadata:{envFiles:m}});let p=!!u,f=!!l;p&&!f&&a.push({id:"devops.dockerignore-missing",category:"devops_deployment",riskKind:"deployment_leakage",status:"observed",confidence:"medium",matchType:"absence",title:".dockerignore is missing",detail:"Dockerfile exists but no .dockerignore was found.",reason:"Without .dockerignore, Docker builds may copy local artifacts (including .env or .git) into images.",sources:[{file:r??"Dockerfile",line:1}],tags:["docker","dockerignore"]}),p&&u&&/COPY\s+\.\s+\./i.test(u)&&!f&&a.push({id:"devops.docker-copy-all-without-dockerignore",category:"devops_deployment",riskKind:"deployment_leakage",status:"observed",confidence:"high",matchType:"heuristic",title:"Dockerfile copies entire build context",detail:"Dockerfile uses COPY . . without a .dockerignore file.",reason:"COPY . . can bundle secrets and VCS metadata into images when .dockerignore is absent.",sources:[{file:r??"Dockerfile",line:u.split(/\r?\n/).findIndex(h=>/COPY\s+\.\s+\./i.test(h))+1||1}],tags:["docker","copy"]}),p&&u&&!Bs(u)&&a.push({id:"devops.docker-non-root-user-missing",category:"devops_deployment",riskKind:"deployment_leakage",status:"needs_review",confidence:"low",matchType:"heuristic",title:"Dockerfile may run as root",detail:"Dockerfile does not declare a non-root USER instruction.",reason:"Containers that run as root increase blast radius if the workload is compromised.",sources:[{file:r??"Dockerfile",line:1}],tags:["docker","user"]});let E=t.filter(h=>h.kind==="devops"&&h.relativePath.startsWith(".github/workflows/"));for(let h of E){let P=(await D(h)).split(/\r?\n/);for(let j=0;j<P.length;j+=1){let T=P[j]??"",_=j+1;Os.some(B=>B.test(T))&&a.push({id:"devops.github-actions-hardcoded-secret",category:"devops_deployment",riskKind:"secret_exposure",status:"observed",confidence:"high",matchType:"regex",title:"Hardcoded secret in GitHub Actions workflow",detail:`${h.relativePath} contains a hardcoded secret-like value.`,reason:"CI workflow files should reference GitHub secrets instead of embedding credential material.",sources:[{file:h.relativePath,line:_,excerpt:Q(T.trim()),redactionApplied:!0}],tags:["github-actions","ci"]}),/\becho\b.*\b(?:SECRET|TOKEN|API_KEY|PASSWORD)\b/i.test(T)&&a.push({id:"devops.github-actions-echo-secret-env",category:"devops_deployment",riskKind:"deployment_leakage",status:"needs_review",confidence:"medium",matchType:"heuristic",title:"Workflow echoes secret-like env names",detail:`${h.relativePath} echoes environment variables that look like secrets.`,reason:"Echoing secret env names in CI logs can leak values when shell tracing or expansion is enabled.",sources:[{file:h.relativePath,line:_,excerpt:T.trim().slice(0,120)}],tags:["github-actions","echo"]});let C=oa(T);C&&a.push({id:"devops.github-actions-next-public-private",category:"frontend_exposure",riskKind:"secret_exposure",status:"needs_review",confidence:"medium",matchType:"heuristic",title:Qo,detail:ra(C,h.relativePath),reason:sa(C.prefix,C.ecosystemLabel),sources:[{file:h.relativePath,line:_,excerpt:Q(T.trim()),redactionApplied:!0}],tags:["github-actions","client-exposed-env",C.prefix.replace(/_$/,"").toLowerCase()],metadata:qe(C)})}}let x=Ds.flatMap(h=>Fe(o.keys(),h));x.length>1&&a.push({id:"devops.multiple-lockfiles",category:"dependencies",riskKind:"supply_chain_hygiene",status:"needs_review",confidence:"medium",matchType:"heuristic",title:"Multiple package lockfiles detected",detail:`Found lockfiles: ${x.join(", ")}.`,reason:"Multiple lockfiles can cause inconsistent dependency resolution across environments.",sources:x.map(h=>({file:h,line:1})),tags:["lockfile","dependencies"],metadata:{lockfiles:[...x]}}),d&&x.length===0&&a.push({id:"devops.lockfile-missing",category:"dependencies",riskKind:"supply_chain_hygiene",status:"observed",confidence:"high",matchType:"absence",title:"package.json without lockfile",detail:"package.json exists but no package-lock.json, pnpm-lock.yaml, yarn.lock, or bun.lockb was found.",reason:"Missing lockfiles make dependency installs non-deterministic and harder to audit.",sources:[{file:s??"package.json",line:1}],tags:["lockfile","dependencies"]});let S=["next.config.js","next.config.mjs","next.config.ts"].flatMap(h=>Fe(o.keys(),h));for(let h of S){let k=await fe(o,h);if(k&&/productionBrowserSourceMaps\s*:\s*true/.test(k)){let P=k.split(/\r?\n/).findIndex(j=>/productionBrowserSourceMaps\s*:\s*true/.test(j))+1;a.push({id:"devops.production-browser-source-maps",category:"frontend_exposure",riskKind:"deployment_leakage",status:"needs_review",confidence:"low",matchType:"heuristic",title:"Production browser source maps enabled",detail:`${h} sets productionBrowserSourceMaps: true.`,reason:"Source maps can be legitimate for debugging but should be reviewed for production exposure of client-side code.",sources:[{file:h,line:P||1}],tags:["nextjs","source-maps"]})}}return a}function qs(e){let t=new Set,o=[];for(let a of e){let n=[a.id,a.category,...a.sources.map(i=>`${i.file}:${i.line}:${i.column??0}`)].join("|");t.has(n)||(t.add(n),o.push(a))}return o}function Fs(e){return[...e].sort((t,o)=>{let a=t.category.localeCompare(o.category);if(a!==0)return a;let n=t.id.localeCompare(o.id);if(n!==0)return n;let i=t.sources[0]?.file??"",r=o.sources[0]?.file??"",s=i.localeCompare(r);return s!==0?s:(t.sources[0]?.line??0)-(o.sources[0]?.line??0)})}function Hs(e){let t=0,o=0,a=0;for(let n of e)n.status==="observed"&&(t+=1),n.status==="needs_review"&&(o+=1),n.status==="not_applicable"&&(a+=1);return{signalsObserved:t,needsReview:o,notApplicable:a}}async function ma(e){let{root:t,scanId:o,generatedAt:a=new Date().toISOString()}=e,n=await Jo(t),i=await la(n.files),r=await ua(n.files),s=await da(t,n.files),c=[{id:"secrets",status:"completed",filesScanned:n.files.length,signals:i.length,warnings:[]},{id:"baas",status:"completed",filesScanned:n.files.length,signals:r.length,warnings:[]},{id:"devops",status:"completed",filesScanned:n.files.length,signals:s.length,warnings:n.warnings}],l=Fs(qs([...i,...r,...s])),u=Hs(l),d=await Promise.all(n.files.map(async m=>({path:m.relativePath,content:await D(m)})));return{version:Re,scanId:o,generatedAt:a,root:t,summary:{filesScanned:n.files.length,filesSkipped:n.skippedLargeFiles.length+n.skippedBinaryFiles.length,signalsObserved:u.signalsObserved,needsReview:u.needsReview,notApplicable:u.notApplicable},detectors:c,signals:l,repoSnapshot:{paths:n.files.map(m=>m.relativePath),files:d},diagnostics:{maxFileBytes:Ne,skippedLargeFiles:n.skippedLargeFiles,skippedBinaryFiles:n.skippedBinaryFiles,warnings:n.warnings}}}import{mkdir as Vs,writeFile as Ks}from"node:fs/promises";import pa from"node:path";var Ws={secrets:"secrets",frontend_exposure:"frontend",devops_deployment:"devops",baas_security:"baas",dependencies:"deps"},Gs=["secrets","baas_security","devops_deployment","frontend_exposure","dependencies"];function Ys(e){let t=new Map;for(let o of e.signals)o.status==="not_observed"||o.status==="not_applicable"||t.set(o.category,(t.get(o.category)??0)+1);return t}function Vt(e){let t=Ys(e),o=[...t.values()].reduce((n,i)=>n+i,0),a=Gs.filter(n=>(t.get(n)??0)>0).map(n=>`${t.get(n)} ${Ws[n]}`);return a.length===0?"0 signals":`${o} signals: ${a.join(" \xB7 ")}`}async function ga(e,t){let o=pa.join(e,".vibemole","security");await Vs(o,{recursive:!0});let a=pa.join(o,"evidence.json");return await Ks(a,`${JSON.stringify(t,null,2)}
|
|
2565
|
+
`,"utf8"),a}var Zs=fa.dirname(Js(import.meta.url)),Qs=fa.resolve(Zs,"../../..");function ec(e){return!e&&!!(O.stdin.isTTY&&O.stdout.isTTY)}async function tc(){let e;try{e=mn(O.argv.slice(2))}catch(s){return console.error(s instanceof Error?s.message:String(s)),console.error(Qe()),1}if(e.command==="help")return console.log(Qe()),0;if(e.command==="login"){let s=`${O.env.USER||"user"}@${Xs.hostname()}`;return await _e(e.webUrl,s),0}if(e.command==="logout")return await zn(),console.log("Logged out of VibeMole CLI."),0;if(e.command==="whoami"){let s=await V(),c=Ee(s,e);if("error"in c)return console.error(c.error),1;if(se(s))return console.error("CLI session expired. Run: vibemole login"),1;let l=await jn(c.webUrl,s.token);return console.log(`userId: ${l.userId}`),console.log(`tokenPrefix: ${l.tokenPrefix}`),console.log(`webUrl: ${s.webUrl}`),0}let t=O.cwd(),o=ec(e.json),a=new Ae(O.stderr,!e.json),n=e.url,i=null,r=0;try{let s;if(await $t(a,e.verbose,{start:Bo,success:qo},async()=>{s=await Bn(t)}),!n&&!e.noRuntime){let p=await qn({root:t,onOutput:e.verbose?f=>O.stderr.write(f):void 0});n=p.targetUrl,i=p.process,n||console.error("Could not discover a localhost URL from package.json scripts. Re-run with --url or --no-runtime.")}let c=[],l=[],u=!1;if(!e.noRuntime&&n){let p=await Oe();if(!p.available&&o&&await ie("No browser runtime was found. Install Playwright Chromium now to run runtime checks?",!0)&&(await gn({repoRoot:Qs,cwd:t}),p=await Oe()),p.available){let f=await Sn({root:t,targetUrl:n,noLogin:e.noLogin,loginRequired:e.loginRequired,loginMethod:e.loginMethod,loginRefresh:e.loginRefresh,interactive:o});u=f.authenticated,!f.authenticated&&e.loginRequired&&e.verbose&&console.error(`Authenticated scan not available: ${f.reason}`);let E=await Ko({targetUrl:n,projectEvidence:s,authenticated:u,storageState:f.storageState,browserRuntime:p,progress:a,routeCap:e.runtimeRouteCap,pagesPerLevel:e.runtimePagesPerLevel,acceptLanguage:xe(e.locale),verbose:e.verbose});c=E.profiles,l=E.warnings}else console.error("Browser runtime unavailable; evidence package will include project and policy-route evidence only.")}let d,m;if(await $t(a,e.verbose,{start:Fo,success:Ho},async()=>{d=await no({root:t,targetUrl:n,reportLocale:e.locale,collectorRouteCap:e.runtimeRouteCap,projectEvidence:s,runtimeProfiles:c,collectorWarnings:l}),m=await to(t,d)}),e.security){let p=await ma({root:t,scanId:d.scanId});if(e.noUpload)await ga(t,p),e.json?console.log(JSON.stringify(Y(d,p),null,2)):(e.verbose?console.log(Te(d)):console.log(Le(d)),console.log(`Evidence file: ${m}`),console.log(Vt(p)));else{let f=await Bt({args:e,evidencePackage:d,securityEvidence:p,progress:a,forceUpload:!0});r=f.exitCode,e.json?console.log(JSON.stringify({...Y(d,p),scanId:f.scanId??d.scanId,...f.reportUrl?{reportUrl:f.reportUrl}:{}},null,2)):r===0&&(e.verbose?console.log(Te(d)):console.log(Le(d)),console.log(`Evidence file: ${m}`),console.log(Vt(p)))}}else e.json?console.log(JSON.stringify(Y(d,null),null,2)):(e.verbose?console.log(Te(d)):console.log(Le(d)),console.log(`Evidence file: ${m}`),r=(await Bt({args:e,evidencePackage:d,progress:a})).exitCode)}finally{i?.kill()}return r}tc().then(e=>{O.exitCode=e}).catch(e=>{console.error(e instanceof Error?e.message:String(e)),O.exitCode=1});
|