[{"data":1,"prerenderedAt":3299},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Fbot-detection":64,"navigation":191,"navLinks_footer":816,"\u002Fdocs\u002Fbot-detection\u002Fapi_page":829,"\u002Fdocs\u002Fbot-detection\u002Fapi_surround":2238,"\u002Fdocs\u002Fbot-detection\u002Fapi":2241},{"id":4,"extension":5,"links":6,"meta":61,"stem":62,"__hash__":63},"navigationMenu\u002Fnavigation.json","json",[7,52,57],{"nested":8,"label":9,"icon":10,"to":11,"children":12},true,"Docs","i-lucide-book-open","\u002Fdocs\u002Fgetting-started",[13,19,26,32,39,45],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},"Getting Started","i-lucide-rocket","An introduction to help you understand the core components.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fdocshub","Start Here",{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},"Auth H3 Client","i-lucide-key-round","\u002Fdocs\u002Fauth-h3client","Seamlessly enforce OAuth 2.0 authentication and session management integrated directly as the client of the IAM module.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth-h3client","Core",{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},"IAM","i-lucide-shield-check","\u002Fdocs\u002Fiam","Identity and Access Management featuring granular roles, permissions, and security policies.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth",{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},"Bot Detection","i-lucide-cpu","\u002Fdocs\u002Fbot-detection","Advanced behavioral analysis and request fingerprinting to stop malicious automated traffic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fbot-detector","Security",{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},"Shield Base","i-lucide-database-zap","\u002Fdocs\u002Fshield-base","CLI and programmatic toolkit for compiling offline-ready IP intelligence databases from BGP, GeoIP, Tor, FireHOL, and other public threat feeds.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fshield-base-cli",{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},"Utils","i-lucide-wrench","\u002Fdocs\u002Futils","A standard library of highly optimized helpers for formatting, validation, and core logic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Futils","Library",{"nested":53,"label":54,"icon":55,"to":56},false,"Blog","i-lucide-pen-line","\u002Fblog",{"nested":53,"label":58,"icon":59,"to":60},"Website","lucide:app-window-mac","https:\u002F\u002Friavzon.com",{},"navigation","gkaQ0xRGxSLrLyM3kttLe0oBwkrR1EBjlepF8LSbwF8",[65],{"title":9,"path":66,"stem":67,"children":68,"page":53},"\u002Fdocs","docs",[69],{"title":70,"path":35,"stem":71,"children":72},"Bot Detector","docs\u002Fbot-detection\u002Findex",[73,74,77,81,85,106,180,183,187],{"title":70,"path":35,"stem":71},{"title":14,"path":75,"stem":76},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":78,"path":79,"stem":80},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":82,"path":83,"stem":84},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":86,"path":87,"stem":88,"children":89,"page":53},"Guides","\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[90,94,98,102],{"title":91,"path":92,"stem":93},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":95,"path":96,"stem":97},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":99,"path":100,"stem":101},"Logging","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":103,"path":104,"stem":105},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":107,"path":108,"stem":109,"children":110},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[111,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176],{"title":107,"path":108,"stem":109},{"title":113,"path":114,"stem":115},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":117,"path":118,"stem":119},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":121,"path":122,"stem":123},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":125,"path":126,"stem":127},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":129,"path":130,"stem":131},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":133,"path":134,"stem":135},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":137,"path":138,"stem":139},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":141,"path":142,"stem":143},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":145,"path":146,"stem":147},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":149,"path":150,"stem":151},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":153,"path":154,"stem":155},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":157,"path":158,"stem":159},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":161,"path":162,"stem":163},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":165,"path":166,"stem":167},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":169,"path":170,"stem":171},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":173,"path":174,"stem":175},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":177,"path":178,"stem":179},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":181,"stem":182},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":184,"path":185,"stem":186},"API Reference","\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":188,"path":189,"stem":190},"Configuration","\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",[192],{"title":9,"path":66,"stem":67,"children":193,"page":53},[194,338,373,378,556,623],{"title":20,"path":22,"stem":195,"children":196},"docs\u002Fauth-h3client\u002Findex",[197,198,207,243,269,291,294,314,317],{"title":20,"path":22,"stem":195},{"title":14,"path":199,"stem":200,"children":201},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[202,203],{"title":14,"path":199,"stem":200},{"title":204,"path":205,"stem":206},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":208,"path":209,"stem":210,"children":211},"Essentials","\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[212,213,217,221,225,229,233,236,240],{"title":208,"path":209,"stem":210},{"title":214,"path":215,"stem":216},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":218,"path":219,"stem":220},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":222,"path":223,"stem":224},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":226,"path":227,"stem":228},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":230,"path":231,"stem":232},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":234,"stem":235},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":237,"path":238,"stem":239},"Cookies","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":99,"path":241,"stem":242},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":244,"path":245,"stem":246,"children":247},"MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[248,249,253,257,261,265],{"title":244,"path":245,"stem":246},{"title":250,"path":251,"stem":252},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":254,"path":255,"stem":256},"Password Reset","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":258,"path":259,"stem":260},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":262,"path":263,"stem":264},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":266,"path":267,"stem":268},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":270,"path":271,"stem":272,"children":273},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[274,275,279,283,287],{"title":270,"path":271,"stem":272},{"title":276,"path":277,"stem":278},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":280,"path":281,"stem":282},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":284,"path":285,"stem":286},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":288,"path":289,"stem":290},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":292,"stem":293},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":86,"path":295,"stem":296,"children":297,"page":53},"\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[298,302,306,310],{"title":299,"path":300,"stem":301},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":303,"path":304,"stem":305},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":307,"path":308,"stem":309},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":311,"path":312,"stem":313},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":188,"path":315,"stem":316},"\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":184,"path":318,"stem":319,"children":320},"\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[321,322,326,330,334],{"title":184,"path":318,"stem":319},{"title":323,"path":324,"stem":325},"Routes Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":327,"path":328,"stem":329},"Middleware Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":331,"path":332,"stem":333},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":335,"path":336,"stem":337},"Utilities","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",{"title":70,"path":35,"stem":71,"children":339},[340,341,342,343,344,350,370,371,372],{"title":70,"path":35,"stem":71},{"title":14,"path":75,"stem":76},{"title":78,"path":79,"stem":80},{"title":82,"path":83,"stem":84},{"title":86,"path":87,"stem":88,"children":345,"page":53},[346,347,348,349],{"title":91,"path":92,"stem":93},{"title":95,"path":96,"stem":97},{"title":99,"path":100,"stem":101},{"title":103,"path":104,"stem":105},{"title":107,"path":108,"stem":109,"children":351},[352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369],{"title":107,"path":108,"stem":109},{"title":113,"path":114,"stem":115},{"title":117,"path":118,"stem":119},{"title":121,"path":122,"stem":123},{"title":125,"path":126,"stem":127},{"title":129,"path":130,"stem":131},{"title":133,"path":134,"stem":135},{"title":137,"path":138,"stem":139},{"title":141,"path":142,"stem":143},{"title":145,"path":146,"stem":147},{"title":149,"path":150,"stem":151},{"title":153,"path":154,"stem":155},{"title":157,"path":158,"stem":159},{"title":161,"path":162,"stem":163},{"title":165,"path":166,"stem":167},{"title":169,"path":170,"stem":171},{"title":173,"path":174,"stem":175},{"title":177,"path":178,"stem":179},{"title":38,"path":181,"stem":182},{"title":184,"path":185,"stem":186},{"title":188,"path":189,"stem":190},{"title":374,"path":11,"stem":375,"children":376},"Introduction","docs\u002Fgetting-started\u002Findex",[377],{"title":374,"path":11,"stem":375},{"title":27,"path":29,"stem":379,"children":380},"docs\u002Fiam\u002Findex",[381,382,385,520,523,539,542],{"title":27,"path":29,"stem":379},{"title":14,"path":383,"stem":384},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":208,"path":386,"stem":387,"children":388},"\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[389,390,394,398,402,406,410,414,418,422,426,430,433,437,441,445,449,452,456,460,463,467,470],{"title":208,"path":386,"stem":387},{"title":391,"path":392,"stem":393},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":395,"path":396,"stem":397},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":399,"path":400,"stem":401},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":403,"path":404,"stem":405},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":407,"path":408,"stem":409},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":411,"path":412,"stem":413},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":415,"path":416,"stem":417},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":419,"path":420,"stem":421},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":423,"path":424,"stem":425},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":427,"path":428,"stem":429},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":244,"path":431,"stem":432},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":434,"path":435,"stem":436},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":438,"path":439,"stem":440},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":442,"path":443,"stem":444},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":446,"path":447,"stem":448},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":99,"path":450,"stem":451},"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":453,"path":454,"stem":455},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":457,"path":458,"stem":459},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":237,"path":461,"stem":462},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":464,"path":465,"stem":466},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":254,"path":468,"stem":469},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":471,"path":472,"stem":473,"children":474},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[475,476,480,484,514,517],{"title":471,"path":472,"stem":473},{"title":477,"path":478,"stem":479},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":481,"path":482,"stem":483},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":485,"path":486,"stem":487,"children":488},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[489,490,494,498,502,506,510],{"title":485,"path":486,"stem":487},{"title":491,"path":492,"stem":493},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":495,"path":496,"stem":497},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":499,"path":500,"stem":501},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":503,"path":504,"stem":505},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":507,"path":508,"stem":509},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":511,"path":512,"stem":513},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":453,"path":515,"stem":516},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":518,"stem":519},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":521,"stem":522},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":86,"path":524,"stem":525,"children":526,"page":53},"\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[527,531,535],{"title":528,"path":529,"stem":530},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":532,"path":533,"stem":534},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":536,"path":537,"stem":538},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":188,"path":540,"stem":541},"\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":543,"path":544,"stem":545,"children":546,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[547,550,553],{"title":184,"path":548,"stem":549},"\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":327,"path":551,"stem":552},"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":323,"path":554,"stem":555},"\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",{"title":40,"path":42,"stem":557,"children":558},"docs\u002Fshield-base\u002Findex",[559,560,563,567,608,612,616,620],{"title":40,"path":42,"stem":557},{"title":14,"path":561,"stem":562},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":564,"path":565,"stem":566},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":82,"path":568,"stem":569,"children":570},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[571,572,576,580,584,588,592,596,600,604],{"title":82,"path":568,"stem":569},{"title":573,"path":574,"stem":575},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":577,"path":578,"stem":579},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":581,"path":582,"stem":583},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":585,"path":586,"stem":587},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":589,"path":590,"stem":591},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":593,"path":594,"stem":595},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":597,"path":598,"stem":599},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":601,"path":602,"stem":603},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":605,"path":606,"stem":607},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":609,"path":610,"stem":611},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":613,"path":614,"stem":615},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":617,"path":618,"stem":619},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":184,"path":621,"stem":622},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":335,"path":48,"stem":624,"children":625},"docs\u002Futils\u002Findex",[626,627,644,677,774],{"title":335,"path":48,"stem":624},{"title":628,"path":629,"stem":630,"children":631,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[632,636,640],{"title":633,"path":634,"stem":635},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":637,"path":638,"stem":639},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":641,"path":642,"stem":643},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":645,"path":646,"stem":647,"children":648,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[649,653,657,661,665,669,673],{"title":650,"path":651,"stem":652},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":654,"path":655,"stem":656},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":658,"path":659,"stem":660},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":662,"path":663,"stem":664},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":666,"path":667,"stem":668},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":670,"path":671,"stem":672},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":674,"path":675,"stem":676},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":678,"path":679,"stem":680,"children":681,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[682,686,690,694,698,702,706,710,714,718,722,726,730,734,738,742,746,750,754,758,762,766,770],{"title":683,"path":684,"stem":685},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":687,"path":688,"stem":689},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":691,"path":692,"stem":693},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":695,"path":696,"stem":697},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":699,"path":700,"stem":701},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":703,"path":704,"stem":705},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":707,"path":708,"stem":709},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":711,"path":712,"stem":713},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":715,"path":716,"stem":717},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":719,"path":720,"stem":721},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":723,"path":724,"stem":725},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":727,"path":728,"stem":729},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":731,"path":732,"stem":733},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":735,"path":736,"stem":737},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":739,"path":740,"stem":741},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":743,"path":744,"stem":745},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":747,"path":748,"stem":749},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":751,"path":752,"stem":753},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":755,"path":756,"stem":757},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":759,"path":760,"stem":761},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":763,"path":764,"stem":765},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":767,"path":768,"stem":769},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":771,"path":772,"stem":773},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":775,"path":776,"stem":777,"children":778},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[779,780,784,788,792,796,800,804,808,812],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":785,"path":786,"stem":787},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":789,"path":790,"stem":791},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":793,"path":794,"stem":795},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":797,"path":798,"stem":799},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":801,"path":802,"stem":803},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":805,"path":806,"stem":807},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":809,"path":810,"stem":811},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":813,"path":814,"stem":815},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",{"id":4,"extension":5,"links":817,"meta":828,"stem":62,"__hash__":63},[818,826,827],{"nested":8,"label":9,"icon":10,"to":11,"children":819},[820,821,822,823,824,825],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},{"nested":53,"label":54,"icon":55,"to":56},{"nested":53,"label":58,"icon":59,"to":60},{},{"id":830,"title":184,"body":831,"description":2230,"extension":2231,"icon":2232,"meta":2233,"module":2234,"navigation":8,"path":185,"rawbody":2235,"seo":2236,"stem":186,"__hash__":2237},"docs\u002Fdocs\u002Fbot-detection\u002F05.api.md",{"type":832,"value":833,"toc":2198},"minimark",[834,861,866,873,885,927,933,939,949,953,959,973,1012,1016,1019,1023,1029,1065,1094,1098,1218,1224,1241,1247,1257,1315,1317,1321,1327,1344,1348,1354,1365,1370,1376,1384,1388,1393,1402,1406,1408,1411,1417,1424,1451,1455,1461,1472,1501,1505,1511,1535,1585,1590,1596,1609,1655,1659,1665,1671,1764,1768,1774,1783,1844,1849,1855,1875,1879,1881,1885,1891,1913,1978,1988,1995,2032,2034,2037,2194],[835,836,837,838,842,843,846,847,846,850,846,853,856,857,860],"p",{},"All public exports from ",[839,840,841],"code",{},"@riavzon\u002Fbot-detector"," are documented below. Every getter (",[839,844,845],{},"getDataSources",", ",[839,848,849],{},"getStorage",[839,851,852],{},"getDb",[839,854,855],{},"getBatchQueue",") throws if called before ",[839,858,859],{},"defineConfiguration"," resolves.",[862,863,865],"h2",{"id":864},"initialization","Initialization",[867,868,870],"h3",{"id":869},"defineconfigurationconfig",[839,871,872],{},"defineConfiguration(config)",[835,874,875,876,879,880,884],{},"Initializes the middleware. Opens all MMDB and LMDB databases, starts the batch write queue, and sets up the cache and database connection. Call it once before attaching ",[839,877,878],{},"detectBots"," to your app. The full configuration reference is in the ",[881,882,883],"a",{"href":189},"Configuration guide",".",[886,887,888,904],"table",{},[889,890,891],"thead",{},[892,893,894,898,901],"tr",{},[895,896,897],"th",{},"Parameter",[895,899,900],{},"Type",[895,902,903],{},"Description",[905,906,907],"tbody",{},[892,908,909,915,920],{},[910,911,912],"td",{},[839,913,914],{},"config",[910,916,917],{},[839,918,919],{},"BotDetectorConfigInput",[910,921,922,923,926],{},"Library configuration object. Only ",[839,924,925],{},"store.main"," is required; see the configuration guide for full schema.",[835,928,929,930],{},"Returns: ",[839,931,932],{},"Promise\u003Cvoid>",[867,934,936],{"id":935},"warmup",[839,937,938],{},"warmUp()",[835,940,941,942,945,946,948],{},"Warms the database connection pool by running parallel ",[839,943,944],{},"SELECT 1"," queries, then fires a dummy visitor query to prime the query plan cache. Call this after ",[839,947,859],{}," resolves but before the server starts accepting traffic.",[835,950,929,951],{},[839,952,932],{},[867,954,956],{"id":955},"createtablesgetdb",[839,957,958],{},"createTables(getDb())",[835,960,961,962,846,965,968,969,972],{},"Creates the required database tables (",[839,963,964],{},"visitors",[839,966,967],{},"banned",") in the configured database. The CLI equivalent is ",[839,970,971],{},"npx bot-detector load-schema",". Call this programmatically when you need to control table creation from code rather than from the CLI.",[886,974,975,985],{},[889,976,977],{},[892,978,979,981,983],{},[895,980,897],{},[895,982,900],{},[895,984,903],{},[905,986,987],{},[892,988,989,994,998],{},[910,990,991],{},[839,992,993],{},"db",[910,995,996],{},[839,997,457],{},[910,999,1000,1001,1004,1005,1007,1008,1011],{},"A ",[839,1002,1003],{},"db0"," ",[839,1006,457],{}," instance to run the schema creation against (pass ",[839,1009,1010],{},"getDb()"," to provide the initialized database).",[835,1013,929,1014],{},[839,1015,932],{},[1017,1018],"hr",{},[862,1020,1022],{"id":1021},"middleware","Middleware",[867,1024,1026],{"id":1025},"detectbotsbuildcustomcontext",[839,1027,1028],{},"detectBots(buildCustomContext?)",[835,1030,1031,1032,1035,1036,1039,1040,1043,1044,1047,1048,1051,1052,846,1055,846,1057,1060,1061,1064],{},"Returns an Express ",[839,1033,1034],{},"RequestHandler",". Always call it as a factory: ",[839,1037,1038],{},"detectBots()",". The optional ",[839,1041,1042],{},"buildCustomContext"," function runs once per request before any checker executes and populates ",[839,1045,1046],{},"ctx.custom"," with typed data you define. When a request passes detection, the middleware sets ",[839,1049,1050],{},"req.botDetection"," with ",[839,1053,1054],{},"success",[839,1056,967],{},[839,1058,1059],{},"time",", and ",[839,1062,1063],{},"ipAddress"," fields.",[886,1066,1067,1077],{},[889,1068,1069],{},[892,1070,1071,1073,1075],{},[895,1072,897],{},[895,1074,900],{},[895,1076,903],{},[905,1078,1079],{},[892,1080,1081,1085,1091],{},[910,1082,1083],{},[839,1084,1042],{},[910,1086,1087,1090],{},[839,1088,1089],{},"(req: Request) => unknown"," (optional)",[910,1092,1093],{},"Optional factory that runs per request to build a custom context object passed to checkers.",[835,1095,929,1096],{},[839,1097,1034],{},[1099,1100,1106],"pre",{"className":1101,"code":1102,"filename":1103,"language":1104,"meta":1105,"style":1105},"language-ts shiki shiki-themes light-plus light-plus dracula","app.use(\n  detectBots\u003CClientSignals>((req) => ({\n    hasWebDriver: req.headers['x-webdriver'] === 'true',\n  }))\n)\n","server.ts","ts","",[839,1107,1108,1127,1157,1206,1212],{"__ignoreMap":1105},[1109,1110,1113,1117,1120,1124],"span",{"class":1111,"line":1112},"line",1,[1109,1114,1116],{"class":1115},"sjsA6","app",[1109,1118,884],{"class":1119},"sDd4n",[1109,1121,1123],{"class":1122},"sHOzp","use",[1109,1125,1126],{"class":1119},"(\n",[1109,1128,1130,1133,1136,1140,1143,1147,1150,1154],{"class":1111,"line":1129},2,[1109,1131,1132],{"class":1122},"  detectBots",[1109,1134,1135],{"class":1119},"\u003C",[1109,1137,1139],{"class":1138},"sW-rI","ClientSignals",[1109,1141,1142],{"class":1119},">((",[1109,1144,1146],{"class":1145},"sygFZ","req",[1109,1148,1149],{"class":1119},") ",[1109,1151,1153],{"class":1152},"sl46w","=>",[1109,1155,1156],{"class":1119}," ({\n",[1109,1158,1160,1163,1167,1170,1172,1175,1178,1182,1186,1188,1191,1195,1198,1201,1203],{"class":1111,"line":1159},3,[1109,1161,1162],{"class":1115},"    hasWebDriver",[1109,1164,1166],{"class":1165},"s34zl",":",[1109,1168,1169],{"class":1115}," req",[1109,1171,884],{"class":1119},[1109,1173,1174],{"class":1115},"headers",[1109,1176,1177],{"class":1119},"[",[1109,1179,1181],{"class":1180},"sFkSl","'",[1109,1183,1185],{"class":1184},"sFB1V","x-webdriver",[1109,1187,1181],{"class":1180},[1109,1189,1190],{"class":1119},"] ",[1109,1192,1194],{"class":1193},"saOXh","===",[1109,1196,1197],{"class":1180}," '",[1109,1199,1200],{"class":1184},"true",[1109,1202,1181],{"class":1180},[1109,1204,1205],{"class":1119},",\n",[1109,1207,1209],{"class":1111,"line":1208},4,[1109,1210,1211],{"class":1119},"  }))\n",[1109,1213,1215],{"class":1111,"line":1214},5,[1109,1216,1217],{"class":1119},")\n",[867,1219,1221],{"id":1220},"apiresponse",[839,1222,1223],{},"ApiResponse",[835,1225,1226,1227,1230,1231,1233,1234,1237,1238,884],{},"An Express ",[839,1228,1229],{},"Router"," that mounts ",[839,1232,1038],{}," at ",[839,1235,1236],{},"\u002Fcheck"," and returns ",[839,1239,1240],{},"{ results: req.botDetection, message: 'Fingerprint logged successfully' }",[835,1242,1243,1244],{},"Type: ",[839,1245,1246],{},"express.Router",[835,1248,1249,1250,1253,1254,884],{},"Usage: mount under a path ",[839,1251,1252],{},"app.use('\u002Fbot', ApiResponse)"," which will expose ",[839,1255,1256],{},"POST \u002Fbot\u002Fcheck",[1099,1258,1260],{"className":1101,"code":1259,"filename":1103,"language":1104,"meta":1105,"style":1105},"import { ApiResponse } from '@riavzon\u002Fbot-detector'\n\napp.use('\u002Fbot', ApiResponse)\n",[839,1261,1262,1286,1291],{"__ignoreMap":1105},[1109,1263,1264,1268,1271,1273,1276,1279,1281,1283],{"class":1111,"line":1112},[1109,1265,1267],{"class":1266},"sZ328","import",[1109,1269,1270],{"class":1119}," { ",[1109,1272,1223],{"class":1115},[1109,1274,1275],{"class":1119}," } ",[1109,1277,1278],{"class":1266},"from",[1109,1280,1197],{"class":1180},[1109,1282,841],{"class":1184},[1109,1284,1285],{"class":1180},"'\n",[1109,1287,1288],{"class":1111,"line":1129},[1109,1289,1290],{"emptyLinePlaceholder":8},"\n",[1109,1292,1293,1295,1297,1299,1302,1304,1307,1309,1311,1313],{"class":1111,"line":1159},[1109,1294,1116],{"class":1115},[1109,1296,884],{"class":1119},[1109,1298,1123],{"class":1122},[1109,1300,1301],{"class":1119},"(",[1109,1303,1181],{"class":1180},[1109,1305,1306],{"class":1184},"\u002Fbot",[1109,1308,1181],{"class":1180},[1109,1310,846],{"class":1119},[1109,1312,1223],{"class":1115},[1109,1314,1217],{"class":1119},[1017,1316],{},[862,1318,1320],{"id":1319},"data-access","Data Access",[867,1322,1324],{"id":1323},"getdatasources",[839,1325,1326],{},"getDataSources()",[835,1328,1329,1330,1333,1334,1336,1337,1339,1340,1343],{},"Returns the initialized ",[839,1331,1332],{},"DataSources"," instance. Throws if called before ",[839,1335,859],{}," resolves. ",[839,1338,1332],{}," exposes synchronous MMDB and LMDB lookup methods for every compiled database: ASN, city, country, Tor nodes, proxies, good bots, FireHOL threat feeds, banned IPs, high-risk IPs, and User-Agent patterns. See the ",[881,1341,1342],{"href":83},"Data Sources guide"," for the full method reference.",[835,1345,929,1346],{},[839,1347,1332],{},[867,1349,1351],{"id":1350},"getstorage",[839,1352,1353],{},"getStorage()",[835,1355,1329,1356,1004,1359,1333,1362,1364],{},[839,1357,1358],{},"unstorage",[839,1360,1361],{},"Storage",[839,1363,859],{}," resolves. Use it to read and write shared state from within custom checkers.",[835,1366,929,1367,1369],{},[839,1368,1361],{}," (unstorage)",[867,1371,1373],{"id":1372},"getbatchqueue",[839,1374,1375],{},"getBatchQueue()",[835,1377,1329,1378,1380,1381,1383],{},[839,1379,683],{}," instance used for deferred database writes. Throws if called before ",[839,1382,859],{}," resolves. Jobs are deduplicated by key within each flush interval.",[835,1385,929,1386],{},[839,1387,683],{},[867,1389,1391],{"id":1390},"getdb",[839,1392,1010],{},[835,1394,1329,1395,1004,1397,1333,1399,1401],{},[839,1396,1003],{},[839,1398,457],{},[839,1400,859],{}," resolves. Use it for direct SQL access to the visitor persistence layer.",[835,1403,929,1404],{},[839,1405,457],{},[1017,1407],{},[862,1409,335],{"id":1410},"utilities",[867,1412,1414],{"id":1413},"parseuauastring",[839,1415,1416],{},"parseUA(uaString)",[835,1418,1419,1420,1423],{},"Parses a User-Agent string and returns a ",[839,1421,1422],{},"ParsedUAResult"," with browser name, version, type, OS, device type, vendor, and model.",[886,1425,1426,1436],{},[889,1427,1428],{},[892,1429,1430,1432,1434],{},[895,1431,897],{},[895,1433,900],{},[895,1435,903],{},[905,1437,1438],{},[892,1439,1440,1445,1448],{},[910,1441,1442],{},[839,1443,1444],{},"uaString",[910,1446,1447],{},"`string",[910,1449,1450],{},"number`",[835,1452,929,1453],{},[839,1454,1422],{},[867,1456,1458],{"id":1457},"getgeodataip",[839,1459,1460],{},"getGeoData(ip)",[835,1462,1463,1464,1467,1468,1471],{},"Returns the full ",[839,1465,1466],{},"GeoResponse"," for any IP address using the compiled MMDB databases. Returns ",[839,1469,1470],{},"null"," if the IP is not in the databases. Useful for geo lookups outside the middleware context.",[886,1473,1474,1484],{},[889,1475,1476],{},[892,1477,1478,1480,1482],{},[895,1479,897],{},[895,1481,900],{},[895,1483,903],{},[905,1485,1486],{},[892,1487,1488,1493,1498],{},[910,1489,1490],{},[839,1491,1492],{},"ip",[910,1494,1495],{},[839,1496,1497],{},"string",[910,1499,1500],{},"IPv4 or IPv6 address to resolve against compiled MMDB data.",[835,1502,929,1503],{},[839,1504,1466],{},[867,1506,1508],{"id":1507},"banipip-info",[839,1509,1510],{},"banIp(ip, info)",[835,1512,1513,1514,1517,1518,1521,1522,1525,1526,1528,1529,1532,1533,884],{},"Issues a ",[839,1515,1516],{},"ufw"," firewall rule (",[839,1519,1520],{},"sudo ufw insert 1 deny from \u003Cip>",") to block the IP at the OS level. Only runs when ",[839,1523,1524],{},"punishmentType.enableFireWallBan"," is ",[839,1527,1200],{},", returns immediately otherwise. Requires the Node.js process to have passwordless ",[839,1530,1531],{},"sudo"," access to ",[839,1534,1516],{},[886,1536,1537,1547],{},[889,1538,1539],{},[892,1540,1541,1543,1545],{},[895,1542,897],{},[895,1544,900],{},[895,1546,903],{},[905,1548,1549,1562],{},[892,1550,1551,1555,1559],{},[910,1552,1553],{},[839,1554,1492],{},[910,1556,1557],{},[839,1558,1497],{},[910,1560,1561],{},"IP address to ban.",[892,1563,1564,1569,1574],{},[910,1565,1566],{},[839,1567,1568],{},"info",[910,1570,1571],{},[839,1572,1573],{},"BannedInfo",[910,1575,1576,1577,1580,1581,1584],{},"Ban metadata including ",[839,1578,1579],{},"score"," and ",[839,1582,1583],{},"reasons"," array used for logging.",[835,1586,929,1587],{},[839,1588,1589],{},"Promise\u003Cvoid> | void",[867,1591,1593],{"id":1592},"updateisbotisbot-cookie",[839,1594,1595],{},"updateIsBot(isBot, cookie)",[835,1597,1598,1599,1602,1603,1605,1606,884],{},"Updates the ",[839,1600,1601],{},"is_bot"," column in the ",[839,1604,964],{}," table for the given ",[839,1607,1608],{},"canary_id",[886,1610,1611,1621],{},[889,1612,1613],{},[892,1614,1615,1617,1619],{},[895,1616,897],{},[895,1618,900],{},[895,1620,903],{},[905,1622,1623,1638],{},[892,1624,1625,1630,1635],{},[910,1626,1627],{},[839,1628,1629],{},"isBot",[910,1631,1632],{},[839,1633,1634],{},"boolean",[910,1636,1637],{},"Whether the visitor is a bot.",[892,1639,1640,1645,1649],{},[910,1641,1642],{},[839,1643,1644],{},"cookie",[910,1646,1647],{},[839,1648,1497],{},[910,1650,1651,1652,1654],{},"The ",[839,1653,1608],{}," cookie value identifying the visitor.",[835,1656,929,1657],{},[839,1658,932],{},[867,1660,1662],{"id":1661},"updatebannedipcookie-ipaddress-country-useragent-info",[839,1663,1664],{},"updateBannedIP(cookie, ipAddress, country, userAgent, info)",[835,1666,1667,1668,1670],{},"Upserts a row into the ",[839,1669,967],{}," table with the visitor's canary cookie, IP address, country, User-Agent, ban reasons, and score.",[886,1672,1673,1683],{},[889,1674,1675],{},[892,1676,1677,1679,1681],{},[895,1678,897],{},[895,1680,900],{},[895,1682,903],{},[905,1684,1685,1699,1712,1726,1740],{},[892,1686,1687,1691,1695],{},[910,1688,1689],{},[839,1690,1644],{},[910,1692,1693],{},[839,1694,1497],{},[910,1696,1651,1697,1654],{},[839,1698,1608],{},[892,1700,1701,1705,1709],{},[910,1702,1703],{},[839,1704,1063],{},[910,1706,1707],{},[839,1708,1497],{},[910,1710,1711],{},"Visitor IP address.",[892,1713,1714,1719,1723],{},[910,1715,1716],{},[839,1717,1718],{},"country",[910,1720,1721],{},[839,1722,1497],{},[910,1724,1725],{},"Country name or code.",[892,1727,1728,1733,1737],{},[910,1729,1730],{},[839,1731,1732],{},"userAgent",[910,1734,1735],{},[839,1736,1497],{},[910,1738,1739],{},"Raw User-Agent string.",[892,1741,1742,1746,1750],{},[910,1743,1744],{},[839,1745,1568],{},[910,1747,1748],{},[839,1749,1573],{},[910,1751,1752,1753,1580,1755,1757,1758,1761,1762,1064],{},"Ban metadata (",[839,1754,1579],{},[839,1756,1583],{},") used for the ",[839,1759,1760],{},"reason","\u002F",[839,1763,1579],{},[835,1765,929,1766],{},[839,1767,932],{},[867,1769,1771],{"id":1770},"updatevisitorsdata-cookie-visitorid",[839,1772,1773],{},"updateVisitors(data, cookie, visitorId)",[835,1775,1776,1777,1779,1780,884],{},"Updates the full fingerprint record in the ",[839,1778,964],{}," table for a given canary and visitor ID pair. Returns ",[839,1781,1782],{},"{ success: boolean, reason?: string }",[886,1784,1785,1795],{},[889,1786,1787],{},[892,1788,1789,1791,1793],{},[895,1790,897],{},[895,1792,900],{},[895,1794,903],{},[905,1796,1797,1812,1826],{},[892,1798,1799,1804,1809],{},[910,1800,1801],{},[839,1802,1803],{},"data",[910,1805,1806],{},[839,1807,1808],{},"VisitorFingerPrint",[910,1810,1811],{},"Full fingerprint object (userAgent, ipAddress, device info, geo fields, etc.).",[892,1813,1814,1818,1822],{},[910,1815,1816],{},[839,1817,1644],{},[910,1819,1820],{},[839,1821,1497],{},[910,1823,1651,1824,1654],{},[839,1825,1608],{},[892,1827,1828,1833,1837],{},[910,1829,1830],{},[839,1831,1832],{},"visitorId",[910,1834,1835],{},[839,1836,1497],{},[910,1838,1839,1840,1843],{},"Visitor's ",[839,1841,1842],{},"visitor_id"," UUID.",[835,1845,929,1846],{},[839,1847,1848],{},"Promise\u003C{ success: boolean; reason?: string }>",[867,1850,1852],{"id":1851},"rungeneration",[839,1853,1854],{},"runGeneration()",[835,1856,1857,1858,1861,1862,1580,1865,1868,1869,1525,1872,1874],{},"Programmatic equivalent of ",[839,1859,1860],{},"npx bot-detector generate",". Compiles ",[839,1863,1864],{},"banned.mmdb",[839,1866,1867],{},"highRisk.mmdb"," from your database. When ",[839,1870,1871],{},"generator.deleteAfterBuild",[839,1873,1200],{},", source rows are deleted after each successful compile.",[835,1876,929,1877],{},[839,1878,932],{},[1017,1880],{},[862,1882,1884],{"id":1883},"checker-system","Checker System",[867,1886,1888],{"id":1887},"checkerregistry",[839,1889,1890],{},"CheckerRegistry",[835,1892,1893,1894,1897,1898,1901,1902,1580,1905,1908,1909,1912],{},"Registry for custom bot checker plugins. Use ",[839,1895,1896],{},"CheckerRegistry.register(checker)"," to add a checker that implements ",[839,1899,1900],{},"IBotChecker",". Checkers are partitioned into ",[839,1903,1904],{},"cheap",[839,1906,1907],{},"heavy"," phases and filtered by your configuration at runtime. ",[839,1910,1911],{},"CheckerRegistry.clear()"," removes all registered checkers, which is useful in tests.",[886,1914,1915,1927],{},[889,1916,1917],{},[892,1918,1919,1922,1925],{},[895,1920,1921],{},"Method",[895,1923,1924],{},"Signature",[895,1926,903],{},[905,1928,1929,1944,1963],{},[892,1930,1931,1936,1941],{},[910,1932,1933],{},[839,1934,1935],{},"register",[910,1937,1938],{},[839,1939,1940],{},"(checker: IBotChecker\u003CBanReasonCode>) => void",[910,1942,1943],{},"Register a checker plugin instance.",[892,1945,1946,1951,1954],{},[910,1947,1948],{},[839,1949,1950],{},"getEnabled",[910,1952,1953],{},"`(phase: 'cheap'",[910,1955,1956,1957],{},"'heavy', config: BotDetectorConfig) => IBotChecker",[1958,1959,1960,1962],"ban-reason-code",{},[1109,1961],{},"`",[892,1964,1965,1970,1975],{},[910,1966,1967],{},[839,1968,1969],{},"clear",[910,1971,1972],{},[839,1973,1974],{},"() => void",[910,1976,1977],{},"Remove all registered checkers (useful in tests).",[867,1979,1981,1984,1985],{"id":1980},"badbotdetected-goodbotdetected",[839,1982,1983],{},"BadBotDetected"," \u002F ",[839,1986,1987],{},"GoodBotDetected",[835,1989,1990,1991,1994],{},"Error subclasses thrown when a checker conclusively identifies a bad or good bot. Re-exported from ",[839,1992,1993],{},"helpers\u002Fexceptions"," for use in custom checkers and error-handling middleware.",[886,1996,1997,2008],{},[889,1998,1999],{},[892,2000,2001,2004,2006],{},[895,2002,2003],{},"Constructor Parameter",[895,2005,900],{},[895,2007,903],{},[905,2009,2010],{},[892,2011,2012,2017,2021],{},[910,2013,2014],{},[839,2015,2016],{},"message",[910,2018,2019,1090],{},[839,2020,1497],{},[910,2022,2023,2024,2027,2028,2031],{},"Optional error message; defaults to ",[839,2025,2026],{},"'Bad bot detected'"," or ",[839,2029,2030],{},"'Good bot detected'"," respectively.",[1017,2033],{},[862,2035,617],{"id":2036},"typescript-types",[886,2038,2039,2047],{},[889,2040,2041],{},[892,2042,2043,2045],{},[895,2044,900],{},[895,2046,903],{},[905,2048,2049,2059,2074,2084,2094,2106,2117,2128,2138,2148,2158,2168,2180],{},[892,2050,2051,2056],{},[910,2052,2053],{},[839,2054,2055],{},"BotDetectorConfig",[910,2057,2058],{},"Fully resolved configuration object with all defaults applied.",[892,2060,2061,2065],{},[910,2062,2063],{},[839,2064,919],{},[910,2066,2067,2068,2070,2071,2073],{},"Input shape for ",[839,2069,859],{},". Only ",[839,2072,925],{}," is required.",[892,2075,2076,2081],{},[910,2077,2078],{},[839,2079,2080],{},"ValidationContext\u003CTCustom>",[910,2082,2083],{},"Per-request context passed to every checker.",[892,2085,2086,2091],{},[910,2087,2088],{},[839,2089,2090],{},"IBotChecker\u003CCode, TCustom>",[910,2092,2093],{},"Interface for custom checker classes.",[892,2095,2096,2100],{},[910,2097,2098],{},[839,2099,1466],{},[910,2101,2102,2103,884],{},"Object returned by ",[839,2104,2105],{},"getGeoData",[892,2107,2108,2112],{},[910,2109,2110],{},[839,2111,1422],{},[910,2113,2102,2114,884],{},[839,2115,2116],{},"parseUA",[892,2118,2119,2123],{},[910,2120,2121],{},[839,2122,1573],{},[910,2124,2125,884],{},[839,2126,2127],{},"{ score: number; reasons: BanReasonCode[] }",[892,2129,2130,2135],{},[910,2131,2132],{},[839,2133,2134],{},"BanReasonCode",[910,2136,2137],{},"Union of all ban reason string literals.",[892,2139,2140,2145],{},[910,2141,2142],{},[839,2143,2144],{},"DbConfig",[910,2146,2147],{},"Discriminated union of all supported database driver configs.",[892,2149,2150,2155],{},[910,2151,2152],{},[839,2153,2154],{},"SupportedDbDrivers",[910,2156,2157],{},"Interface mapping each driver key to its options type.",[892,2159,2160,2165],{},[910,2161,2162],{},[839,2163,2164],{},"CacheConfig",[910,2166,2167],{},"Discriminated union of all supported cache driver configs.",[892,2169,2170,2174],{},[910,2171,2172],{},[839,2173,1808],{},[910,2175,2176,2177,2179],{},"Shape of the visitor record in the ",[839,2178,964],{}," table.",[892,2181,2182,2187],{},[910,2183,2184],{},[839,2185,2186],{},"ThreatRecordModified",[910,2188,2189,2190,2193],{},"FireHOL threat record extended with a ",[839,2191,2192],{},"network"," CIDR field.",[2195,2196,2197],"style",{},"html pre.shiki code .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sW-rI, html code.shiki .sW-rI{--shiki-light:#267F99;--shiki-light-font-style:inherit;--shiki-default:#267F99;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .sygFZ, html code.shiki .sygFZ{--shiki-light:#001080;--shiki-light-font-style:inherit;--shiki-default:#001080;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .sl46w, html code.shiki .sl46w{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#FF79C6}html pre.shiki code .s34zl, html code.shiki .s34zl{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#FF79C6}html pre.shiki code .sFkSl, html code.shiki .sFkSl{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#E9F284}html pre.shiki code .sFB1V, html code.shiki .sFB1V{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#F1FA8C}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}",{"title":1105,"searchDepth":1129,"depth":1129,"links":2199},[2200,2205,2209,2215,2224,2229],{"id":864,"depth":1129,"text":865,"children":2201},[2202,2203,2204],{"id":869,"depth":1159,"text":872},{"id":935,"depth":1159,"text":938},{"id":955,"depth":1159,"text":958},{"id":1021,"depth":1129,"text":1022,"children":2206},[2207,2208],{"id":1025,"depth":1159,"text":1028},{"id":1220,"depth":1159,"text":1223},{"id":1319,"depth":1129,"text":1320,"children":2210},[2211,2212,2213,2214],{"id":1323,"depth":1159,"text":1326},{"id":1350,"depth":1159,"text":1353},{"id":1372,"depth":1159,"text":1375},{"id":1390,"depth":1159,"text":1010},{"id":1410,"depth":1129,"text":335,"children":2216},[2217,2218,2219,2220,2221,2222,2223],{"id":1413,"depth":1159,"text":1416},{"id":1457,"depth":1159,"text":1460},{"id":1507,"depth":1159,"text":1510},{"id":1592,"depth":1159,"text":1595},{"id":1661,"depth":1159,"text":1664},{"id":1770,"depth":1159,"text":1773},{"id":1851,"depth":1159,"text":1854},{"id":1883,"depth":1129,"text":1884,"children":2225},[2226,2227],{"id":1887,"depth":1159,"text":1890},{"id":1980,"depth":1159,"text":2228},"BadBotDetected \u002F GoodBotDetected",{"id":2036,"depth":1129,"text":617},"All public exports from @riavzon\u002Fbot-detector.","md","i-lucide-code",{},null,"---\ntitle: API Reference\ndescription: All public exports from @riavzon\u002Fbot-detector.\nicon: i-lucide-code\n---\n\nAll public exports from `@riavzon\u002Fbot-detector` are documented below. Every getter (`getDataSources`, `getStorage`, `getDb`, `getBatchQueue`) throws if called before `defineConfiguration` resolves.\n\n## Initialization\n\n### `defineConfiguration(config)`\n\nInitializes the middleware. Opens all MMDB and LMDB databases, starts the batch write queue, and sets up the cache and database connection. Call it once before attaching `detectBots` to your app. The full configuration reference is in the [Configuration guide](\u002Fdocs\u002Fbot-detection\u002Fconfiguration).\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `config` | `BotDetectorConfigInput` | Library configuration object. Only `store.main` is required; see the configuration guide for full schema. |\n\nReturns: `Promise\u003Cvoid>`\n\n### `warmUp()`\n\nWarms the database connection pool by running parallel `SELECT 1` queries, then fires a dummy visitor query to prime the query plan cache. Call this after `defineConfiguration` resolves but before the server starts accepting traffic.\n\nReturns: `Promise\u003Cvoid>`\n\n### `createTables(getDb())`\n\nCreates the required database tables (`visitors`, `banned`) in the configured database. The CLI equivalent is `npx bot-detector load-schema`. Call this programmatically when you need to control table creation from code rather than from the CLI.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `db` | `Database` | A `db0` `Database` instance to run the schema creation against (pass `getDb()` to provide the initialized database). |\n\nReturns: `Promise\u003Cvoid>`\n\n---\n\n## Middleware\n\n### `detectBots(buildCustomContext?)`\n\nReturns an Express `RequestHandler`. Always call it as a factory: `detectBots()`. The optional `buildCustomContext` function runs once per request before any checker executes and populates `ctx.custom` with typed data you define. When a request passes detection, the middleware sets `req.botDetection` with `success`, `banned`, `time`, and `ipAddress` fields.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `buildCustomContext` | `(req: Request) => unknown` (optional) | Optional factory that runs per request to build a custom context object passed to checkers. |\n\nReturns: `RequestHandler`\n\n```ts [server.ts]\napp.use(\n  detectBots\u003CClientSignals>((req) => ({\n    hasWebDriver: req.headers['x-webdriver'] === 'true',\n  }))\n)\n```\n\n\n### `ApiResponse`\n\nAn Express `Router` that mounts `detectBots()` at `\u002Fcheck` and returns `{ results: req.botDetection, message: 'Fingerprint logged successfully' }`.\n\nType: `express.Router`\n\nUsage: mount under a path `app.use('\u002Fbot', ApiResponse)` which will expose `POST \u002Fbot\u002Fcheck`.\n\n```ts [server.ts]\nimport { ApiResponse } from '@riavzon\u002Fbot-detector'\n\napp.use('\u002Fbot', ApiResponse)\n```\n\n---\n\n## Data Access\n\n### `getDataSources()`\n\nReturns the initialized `DataSources` instance. Throws if called before `defineConfiguration` resolves. `DataSources` exposes synchronous MMDB and LMDB lookup methods for every compiled database: ASN, city, country, Tor nodes, proxies, good bots, FireHOL threat feeds, banned IPs, high-risk IPs, and User-Agent patterns. See the [Data Sources guide](\u002Fdocs\u002Fbot-detection\u002Fdata-sources) for the full method reference.\n\nReturns: `DataSources`\n\n### `getStorage()`\n\nReturns the initialized `unstorage` `Storage` instance. Throws if called before `defineConfiguration` resolves. Use it to read and write shared state from within custom checkers.\n\nReturns: `Storage` (unstorage)\n\n### `getBatchQueue()`\n\nReturns the initialized `BatchQueue` instance used for deferred database writes. Throws if called before `defineConfiguration` resolves. Jobs are deduplicated by key within each flush interval.\n\nReturns: `BatchQueue`\n\n### `getDb()`\n\nReturns the initialized `db0` `Database` instance. Throws if called before `defineConfiguration` resolves. Use it for direct SQL access to the visitor persistence layer.\n\nReturns: `Database`\n\n---\n\n## Utilities\n\n### `parseUA(uaString)`\n\nParses a User-Agent string and returns a `ParsedUAResult` with browser name, version, type, OS, device type, vendor, and model.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `uaString` | `string | number` | User-Agent value to parse. Non-string inputs are cast to string. |\n\nReturns: `ParsedUAResult`\n\n### `getGeoData(ip)`\n\nReturns the full `GeoResponse` for any IP address using the compiled MMDB databases. Returns `null` if the IP is not in the databases. Useful for geo lookups outside the middleware context.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `ip` | `string` | IPv4 or IPv6 address to resolve against compiled MMDB data. |\n\nReturns: `GeoResponse`\n\n### `banIp(ip, info)`\n\nIssues a `ufw` firewall rule (`sudo ufw insert 1 deny from \u003Cip>`) to block the IP at the OS level. Only runs when `punishmentType.enableFireWallBan` is `true`, returns immediately otherwise. Requires the Node.js process to have passwordless `sudo` access to `ufw`.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `ip` | `string` | IP address to ban. |\n| `info` | `BannedInfo` | Ban metadata including `score` and `reasons` array used for logging. |\n\nReturns: `Promise\u003Cvoid> | void`\n\n### `updateIsBot(isBot, cookie)`\n\nUpdates the `is_bot` column in the `visitors` table for the given `canary_id`.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `isBot` | `boolean` | Whether the visitor is a bot. |\n| `cookie` | `string` | The `canary_id` cookie value identifying the visitor. |\n\nReturns: `Promise\u003Cvoid>`\n\n### `updateBannedIP(cookie, ipAddress, country, userAgent, info)`\n\nUpserts a row into the `banned` table with the visitor's canary cookie, IP address, country, User-Agent, ban reasons, and score.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `cookie` | `string` | The `canary_id` cookie value identifying the visitor. |\n| `ipAddress` | `string` | Visitor IP address. |\n| `country` | `string` | Country name or code. |\n| `userAgent` | `string` | Raw User-Agent string. |\n| `info` | `BannedInfo` | Ban metadata (`score` and `reasons`) used for the `reason`\u002F`score` fields. |\n\nReturns: `Promise\u003Cvoid>`\n\n### `updateVisitors(data, cookie, visitorId)`\n\nUpdates the full fingerprint record in the `visitors` table for a given canary and visitor ID pair. Returns `{ success: boolean, reason?: string }`.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `data` | `VisitorFingerPrint` | Full fingerprint object (userAgent, ipAddress, device info, geo fields, etc.). |\n| `cookie` | `string` | The `canary_id` cookie value identifying the visitor. |\n| `visitorId` | `string` | Visitor's `visitor_id` UUID. |\n\nReturns: `Promise\u003C{ success: boolean; reason?: string }>`\n\n### `runGeneration()`\n\nProgrammatic equivalent of `npx bot-detector generate`. Compiles `banned.mmdb` and `highRisk.mmdb` from your database. When `generator.deleteAfterBuild` is `true`, source rows are deleted after each successful compile.\n\nReturns: `Promise\u003Cvoid>`\n\n---\n\n## Checker System\n\n### `CheckerRegistry`\n\nRegistry for custom bot checker plugins. Use `CheckerRegistry.register(checker)` to add a checker that implements `IBotChecker`. Checkers are partitioned into `cheap` and `heavy` phases and filtered by your configuration at runtime. `CheckerRegistry.clear()` removes all registered checkers, which is useful in tests.\n\n| Method | Signature | Description |\n| --- | --- | --- |\n| `register` | `(checker: IBotChecker\u003CBanReasonCode>) => void` | Register a checker plugin instance. |\n| `getEnabled` | `(phase: 'cheap' | 'heavy', config: BotDetectorConfig) => IBotChecker\u003CBanReasonCode>[]` | Returns enabled checkers for a phase given the resolved config. |\n| `clear` | `() => void` | Remove all registered checkers (useful in tests). |\n\n### `BadBotDetected` \u002F `GoodBotDetected`\n\nError subclasses thrown when a checker conclusively identifies a bad or good bot. Re-exported from `helpers\u002Fexceptions` for use in custom checkers and error-handling middleware.\n\n| Constructor Parameter | Type | Description |\n| --- | --- | --- |\n| `message` | `string` (optional) | Optional error message; defaults to `'Bad bot detected'` or `'Good bot detected'` respectively. |\n\n---\n\n## TypeScript Types\n\n| Type | Description |\n| --- | --- |\n| `BotDetectorConfig` | Fully resolved configuration object with all defaults applied. |\n| `BotDetectorConfigInput` | Input shape for `defineConfiguration`. Only `store.main` is required. |\n| `ValidationContext\u003CTCustom>` | Per-request context passed to every checker. |\n| `IBotChecker\u003CCode, TCustom>` | Interface for custom checker classes. |\n| `GeoResponse` | Object returned by `getGeoData`. |\n| `ParsedUAResult` | Object returned by `parseUA`. |\n| `BannedInfo` | `{ score: number; reasons: BanReasonCode[] }`. |\n| `BanReasonCode` | Union of all ban reason string literals. |\n| `DbConfig` | Discriminated union of all supported database driver configs. |\n| `SupportedDbDrivers` | Interface mapping each driver key to its options type. |\n| `CacheConfig` | Discriminated union of all supported cache driver configs. |\n| `VisitorFingerPrint` | Shape of the visitor record in the `visitors` table. |\n| `ThreatRecordModified` | FireHOL threat record extended with a `network` CIDR field. |\n",{"title":184,"description":2230},"Wvlna7AWCm3waGVP2BuY8H8bUE_FvDeC-k7ZosQeLsY",[2239,2240],{"title":38,"path":181,"stem":182,"children":-1},{"title":188,"path":189,"stem":190,"children":-1},{"id":830,"title":184,"body":2242,"description":2230,"extension":2231,"icon":2232,"meta":3297,"module":2234,"navigation":8,"path":185,"rawbody":2235,"seo":3298,"stem":186,"__hash__":2237},{"type":832,"value":2243,"toc":3266},[2244,2258,2260,2264,2270,2298,2302,2306,2312,2316,2320,2328,2360,2364,2366,2368,2372,2392,2418,2422,2494,2498,2508,2512,2518,2566,2568,2570,2574,2584,2588,2592,2600,2604,2608,2614,2618,2622,2630,2634,2636,2638,2642,2646,2670,2674,2678,2684,2710,2714,2718,2732,2774,2778,2782,2790,2830,2834,2838,2842,2926,2930,2934,2940,2994,2998,3002,3014,3018,3020,3022,3026,3038,3090,3096,3100,3130,3132,3134,3264],[835,2245,837,2246,842,2248,846,2250,846,2252,846,2254,856,2256,860],{},[839,2247,841],{},[839,2249,845],{},[839,2251,849],{},[839,2253,852],{},[839,2255,855],{},[839,2257,859],{},[862,2259,865],{"id":864},[867,2261,2262],{"id":869},[839,2263,872],{},[835,2265,875,2266,879,2268,884],{},[839,2267,878],{},[881,2269,883],{"href":189},[886,2271,2272,2282],{},[889,2273,2274],{},[892,2275,2276,2278,2280],{},[895,2277,897],{},[895,2279,900],{},[895,2281,903],{},[905,2283,2284],{},[892,2285,2286,2290,2294],{},[910,2287,2288],{},[839,2289,914],{},[910,2291,2292],{},[839,2293,919],{},[910,2295,922,2296,926],{},[839,2297,925],{},[835,2299,929,2300],{},[839,2301,932],{},[867,2303,2304],{"id":935},[839,2305,938],{},[835,2307,941,2308,945,2310,948],{},[839,2309,944],{},[839,2311,859],{},[835,2313,929,2314],{},[839,2315,932],{},[867,2317,2318],{"id":955},[839,2319,958],{},[835,2321,961,2322,846,2324,968,2326,972],{},[839,2323,964],{},[839,2325,967],{},[839,2327,971],{},[886,2329,2330,2340],{},[889,2331,2332],{},[892,2333,2334,2336,2338],{},[895,2335,897],{},[895,2337,900],{},[895,2339,903],{},[905,2341,2342],{},[892,2343,2344,2348,2352],{},[910,2345,2346],{},[839,2347,993],{},[910,2349,2350],{},[839,2351,457],{},[910,2353,1000,2354,1004,2356,1007,2358,1011],{},[839,2355,1003],{},[839,2357,457],{},[839,2359,1010],{},[835,2361,929,2362],{},[839,2363,932],{},[1017,2365],{},[862,2367,1022],{"id":1021},[867,2369,2370],{"id":1025},[839,2371,1028],{},[835,2373,1031,2374,1035,2376,1039,2378,1043,2380,1047,2382,1051,2384,846,2386,846,2388,1060,2390,1064],{},[839,2375,1034],{},[839,2377,1038],{},[839,2379,1042],{},[839,2381,1046],{},[839,2383,1050],{},[839,2385,1054],{},[839,2387,967],{},[839,2389,1059],{},[839,2391,1063],{},[886,2393,2394,2404],{},[889,2395,2396],{},[892,2397,2398,2400,2402],{},[895,2399,897],{},[895,2401,900],{},[895,2403,903],{},[905,2405,2406],{},[892,2407,2408,2412,2416],{},[910,2409,2410],{},[839,2411,1042],{},[910,2413,2414,1090],{},[839,2415,1089],{},[910,2417,1093],{},[835,2419,929,2420],{},[839,2421,1034],{},[1099,2423,2424],{"className":1101,"code":1102,"filename":1103,"language":1104,"meta":1105,"style":1105},[839,2425,2426,2436,2454,2486,2490],{"__ignoreMap":1105},[1109,2427,2428,2430,2432,2434],{"class":1111,"line":1112},[1109,2429,1116],{"class":1115},[1109,2431,884],{"class":1119},[1109,2433,1123],{"class":1122},[1109,2435,1126],{"class":1119},[1109,2437,2438,2440,2442,2444,2446,2448,2450,2452],{"class":1111,"line":1129},[1109,2439,1132],{"class":1122},[1109,2441,1135],{"class":1119},[1109,2443,1139],{"class":1138},[1109,2445,1142],{"class":1119},[1109,2447,1146],{"class":1145},[1109,2449,1149],{"class":1119},[1109,2451,1153],{"class":1152},[1109,2453,1156],{"class":1119},[1109,2455,2456,2458,2460,2462,2464,2466,2468,2470,2472,2474,2476,2478,2480,2482,2484],{"class":1111,"line":1159},[1109,2457,1162],{"class":1115},[1109,2459,1166],{"class":1165},[1109,2461,1169],{"class":1115},[1109,2463,884],{"class":1119},[1109,2465,1174],{"class":1115},[1109,2467,1177],{"class":1119},[1109,2469,1181],{"class":1180},[1109,2471,1185],{"class":1184},[1109,2473,1181],{"class":1180},[1109,2475,1190],{"class":1119},[1109,2477,1194],{"class":1193},[1109,2479,1197],{"class":1180},[1109,2481,1200],{"class":1184},[1109,2483,1181],{"class":1180},[1109,2485,1205],{"class":1119},[1109,2487,2488],{"class":1111,"line":1208},[1109,2489,1211],{"class":1119},[1109,2491,2492],{"class":1111,"line":1214},[1109,2493,1217],{"class":1119},[867,2495,2496],{"id":1220},[839,2497,1223],{},[835,2499,1226,2500,1230,2502,1233,2504,1237,2506,884],{},[839,2501,1229],{},[839,2503,1038],{},[839,2505,1236],{},[839,2507,1240],{},[835,2509,1243,2510],{},[839,2511,1246],{},[835,2513,1249,2514,1253,2516,884],{},[839,2515,1252],{},[839,2517,1256],{},[1099,2519,2520],{"className":1101,"code":1259,"filename":1103,"language":1104,"meta":1105,"style":1105},[839,2521,2522,2540,2544],{"__ignoreMap":1105},[1109,2523,2524,2526,2528,2530,2532,2534,2536,2538],{"class":1111,"line":1112},[1109,2525,1267],{"class":1266},[1109,2527,1270],{"class":1119},[1109,2529,1223],{"class":1115},[1109,2531,1275],{"class":1119},[1109,2533,1278],{"class":1266},[1109,2535,1197],{"class":1180},[1109,2537,841],{"class":1184},[1109,2539,1285],{"class":1180},[1109,2541,2542],{"class":1111,"line":1129},[1109,2543,1290],{"emptyLinePlaceholder":8},[1109,2545,2546,2548,2550,2552,2554,2556,2558,2560,2562,2564],{"class":1111,"line":1159},[1109,2547,1116],{"class":1115},[1109,2549,884],{"class":1119},[1109,2551,1123],{"class":1122},[1109,2553,1301],{"class":1119},[1109,2555,1181],{"class":1180},[1109,2557,1306],{"class":1184},[1109,2559,1181],{"class":1180},[1109,2561,846],{"class":1119},[1109,2563,1223],{"class":1115},[1109,2565,1217],{"class":1119},[1017,2567],{},[862,2569,1320],{"id":1319},[867,2571,2572],{"id":1323},[839,2573,1326],{},[835,2575,1329,2576,1333,2578,1336,2580,1339,2582,1343],{},[839,2577,1332],{},[839,2579,859],{},[839,2581,1332],{},[881,2583,1342],{"href":83},[835,2585,929,2586],{},[839,2587,1332],{},[867,2589,2590],{"id":1350},[839,2591,1353],{},[835,2593,1329,2594,1004,2596,1333,2598,1364],{},[839,2595,1358],{},[839,2597,1361],{},[839,2599,859],{},[835,2601,929,2602,1369],{},[839,2603,1361],{},[867,2605,2606],{"id":1372},[839,2607,1375],{},[835,2609,1329,2610,1380,2612,1383],{},[839,2611,683],{},[839,2613,859],{},[835,2615,929,2616],{},[839,2617,683],{},[867,2619,2620],{"id":1390},[839,2621,1010],{},[835,2623,1329,2624,1004,2626,1333,2628,1401],{},[839,2625,1003],{},[839,2627,457],{},[839,2629,859],{},[835,2631,929,2632],{},[839,2633,457],{},[1017,2635],{},[862,2637,335],{"id":1410},[867,2639,2640],{"id":1413},[839,2641,1416],{},[835,2643,1419,2644,1423],{},[839,2645,1422],{},[886,2647,2648,2658],{},[889,2649,2650],{},[892,2651,2652,2654,2656],{},[895,2653,897],{},[895,2655,900],{},[895,2657,903],{},[905,2659,2660],{},[892,2661,2662,2666,2668],{},[910,2663,2664],{},[839,2665,1444],{},[910,2667,1447],{},[910,2669,1450],{},[835,2671,929,2672],{},[839,2673,1422],{},[867,2675,2676],{"id":1457},[839,2677,1460],{},[835,2679,1463,2680,1467,2682,1471],{},[839,2681,1466],{},[839,2683,1470],{},[886,2685,2686,2696],{},[889,2687,2688],{},[892,2689,2690,2692,2694],{},[895,2691,897],{},[895,2693,900],{},[895,2695,903],{},[905,2697,2698],{},[892,2699,2700,2704,2708],{},[910,2701,2702],{},[839,2703,1492],{},[910,2705,2706],{},[839,2707,1497],{},[910,2709,1500],{},[835,2711,929,2712],{},[839,2713,1466],{},[867,2715,2716],{"id":1507},[839,2717,1510],{},[835,2719,1513,2720,1517,2722,1521,2724,1525,2726,1528,2728,1532,2730,884],{},[839,2721,1516],{},[839,2723,1520],{},[839,2725,1524],{},[839,2727,1200],{},[839,2729,1531],{},[839,2731,1516],{},[886,2733,2734,2744],{},[889,2735,2736],{},[892,2737,2738,2740,2742],{},[895,2739,897],{},[895,2741,900],{},[895,2743,903],{},[905,2745,2746,2758],{},[892,2747,2748,2752,2756],{},[910,2749,2750],{},[839,2751,1492],{},[910,2753,2754],{},[839,2755,1497],{},[910,2757,1561],{},[892,2759,2760,2764,2768],{},[910,2761,2762],{},[839,2763,1568],{},[910,2765,2766],{},[839,2767,1573],{},[910,2769,1576,2770,1580,2772,1584],{},[839,2771,1579],{},[839,2773,1583],{},[835,2775,929,2776],{},[839,2777,1589],{},[867,2779,2780],{"id":1592},[839,2781,1595],{},[835,2783,1598,2784,1602,2786,1605,2788,884],{},[839,2785,1601],{},[839,2787,964],{},[839,2789,1608],{},[886,2791,2792,2802],{},[889,2793,2794],{},[892,2795,2796,2798,2800],{},[895,2797,897],{},[895,2799,900],{},[895,2801,903],{},[905,2803,2804,2816],{},[892,2805,2806,2810,2814],{},[910,2807,2808],{},[839,2809,1629],{},[910,2811,2812],{},[839,2813,1634],{},[910,2815,1637],{},[892,2817,2818,2822,2826],{},[910,2819,2820],{},[839,2821,1644],{},[910,2823,2824],{},[839,2825,1497],{},[910,2827,1651,2828,1654],{},[839,2829,1608],{},[835,2831,929,2832],{},[839,2833,932],{},[867,2835,2836],{"id":1661},[839,2837,1664],{},[835,2839,1667,2840,1670],{},[839,2841,967],{},[886,2843,2844,2854],{},[889,2845,2846],{},[892,2847,2848,2850,2852],{},[895,2849,897],{},[895,2851,900],{},[895,2853,903],{},[905,2855,2856,2870,2882,2894,2906],{},[892,2857,2858,2862,2866],{},[910,2859,2860],{},[839,2861,1644],{},[910,2863,2864],{},[839,2865,1497],{},[910,2867,1651,2868,1654],{},[839,2869,1608],{},[892,2871,2872,2876,2880],{},[910,2873,2874],{},[839,2875,1063],{},[910,2877,2878],{},[839,2879,1497],{},[910,2881,1711],{},[892,2883,2884,2888,2892],{},[910,2885,2886],{},[839,2887,1718],{},[910,2889,2890],{},[839,2891,1497],{},[910,2893,1725],{},[892,2895,2896,2900,2904],{},[910,2897,2898],{},[839,2899,1732],{},[910,2901,2902],{},[839,2903,1497],{},[910,2905,1739],{},[892,2907,2908,2912,2916],{},[910,2909,2910],{},[839,2911,1568],{},[910,2913,2914],{},[839,2915,1573],{},[910,2917,1752,2918,1580,2920,1757,2922,1761,2924,1064],{},[839,2919,1579],{},[839,2921,1583],{},[839,2923,1760],{},[839,2925,1579],{},[835,2927,929,2928],{},[839,2929,932],{},[867,2931,2932],{"id":1770},[839,2933,1773],{},[835,2935,1776,2936,1779,2938,884],{},[839,2937,964],{},[839,2939,1782],{},[886,2941,2942,2952],{},[889,2943,2944],{},[892,2945,2946,2948,2950],{},[895,2947,897],{},[895,2949,900],{},[895,2951,903],{},[905,2953,2954,2966,2980],{},[892,2955,2956,2960,2964],{},[910,2957,2958],{},[839,2959,1803],{},[910,2961,2962],{},[839,2963,1808],{},[910,2965,1811],{},[892,2967,2968,2972,2976],{},[910,2969,2970],{},[839,2971,1644],{},[910,2973,2974],{},[839,2975,1497],{},[910,2977,1651,2978,1654],{},[839,2979,1608],{},[892,2981,2982,2986,2990],{},[910,2983,2984],{},[839,2985,1832],{},[910,2987,2988],{},[839,2989,1497],{},[910,2991,1839,2992,1843],{},[839,2993,1842],{},[835,2995,929,2996],{},[839,2997,1848],{},[867,2999,3000],{"id":1851},[839,3001,1854],{},[835,3003,1857,3004,1861,3006,1580,3008,1868,3010,1525,3012,1874],{},[839,3005,1860],{},[839,3007,1864],{},[839,3009,1867],{},[839,3011,1871],{},[839,3013,1200],{},[835,3015,929,3016],{},[839,3017,932],{},[1017,3019],{},[862,3021,1884],{"id":1883},[867,3023,3024],{"id":1887},[839,3025,1890],{},[835,3027,1893,3028,1897,3030,1901,3032,1580,3034,1908,3036,1912],{},[839,3029,1896],{},[839,3031,1900],{},[839,3033,1904],{},[839,3035,1907],{},[839,3037,1911],{},[886,3039,3040,3050],{},[889,3041,3042],{},[892,3043,3044,3046,3048],{},[895,3045,1921],{},[895,3047,1924],{},[895,3049,903],{},[905,3051,3052,3064,3078],{},[892,3053,3054,3058,3062],{},[910,3055,3056],{},[839,3057,1935],{},[910,3059,3060],{},[839,3061,1940],{},[910,3063,1943],{},[892,3065,3066,3070,3072],{},[910,3067,3068],{},[839,3069,1950],{},[910,3071,1953],{},[910,3073,1956,3074],{},[1958,3075,3076,1962],{},[1109,3077],{},[892,3079,3080,3084,3088],{},[910,3081,3082],{},[839,3083,1969],{},[910,3085,3086],{},[839,3087,1974],{},[910,3089,1977],{},[867,3091,3092,1984,3094],{"id":1980},[839,3093,1983],{},[839,3095,1987],{},[835,3097,1990,3098,1994],{},[839,3099,1993],{},[886,3101,3102,3112],{},[889,3103,3104],{},[892,3105,3106,3108,3110],{},[895,3107,2003],{},[895,3109,900],{},[895,3111,903],{},[905,3113,3114],{},[892,3115,3116,3120,3124],{},[910,3117,3118],{},[839,3119,2016],{},[910,3121,3122,1090],{},[839,3123,1497],{},[910,3125,2023,3126,2027,3128,2031],{},[839,3127,2026],{},[839,3129,2030],{},[1017,3131],{},[862,3133,617],{"id":2036},[886,3135,3136,3144],{},[889,3137,3138],{},[892,3139,3140,3142],{},[895,3141,900],{},[895,3143,903],{},[905,3145,3146,3154,3166,3174,3182,3192,3202,3212,3220,3228,3236,3244,3254],{},[892,3147,3148,3152],{},[910,3149,3150],{},[839,3151,2055],{},[910,3153,2058],{},[892,3155,3156,3160],{},[910,3157,3158],{},[839,3159,919],{},[910,3161,2067,3162,2070,3164,2073],{},[839,3163,859],{},[839,3165,925],{},[892,3167,3168,3172],{},[910,3169,3170],{},[839,3171,2080],{},[910,3173,2083],{},[892,3175,3176,3180],{},[910,3177,3178],{},[839,3179,2090],{},[910,3181,2093],{},[892,3183,3184,3188],{},[910,3185,3186],{},[839,3187,1466],{},[910,3189,2102,3190,884],{},[839,3191,2105],{},[892,3193,3194,3198],{},[910,3195,3196],{},[839,3197,1422],{},[910,3199,2102,3200,884],{},[839,3201,2116],{},[892,3203,3204,3208],{},[910,3205,3206],{},[839,3207,1573],{},[910,3209,3210,884],{},[839,3211,2127],{},[892,3213,3214,3218],{},[910,3215,3216],{},[839,3217,2134],{},[910,3219,2137],{},[892,3221,3222,3226],{},[910,3223,3224],{},[839,3225,2144],{},[910,3227,2147],{},[892,3229,3230,3234],{},[910,3231,3232],{},[839,3233,2154],{},[910,3235,2157],{},[892,3237,3238,3242],{},[910,3239,3240],{},[839,3241,2164],{},[910,3243,2167],{},[892,3245,3246,3250],{},[910,3247,3248],{},[839,3249,1808],{},[910,3251,2176,3252,2179],{},[839,3253,964],{},[892,3255,3256,3260],{},[910,3257,3258],{},[839,3259,2186],{},[910,3261,2189,3262,2193],{},[839,3263,2192],{},[2195,3265,2197],{},{"title":1105,"searchDepth":1129,"depth":1129,"links":3267},[3268,3273,3277,3283,3292,3296],{"id":864,"depth":1129,"text":865,"children":3269},[3270,3271,3272],{"id":869,"depth":1159,"text":872},{"id":935,"depth":1159,"text":938},{"id":955,"depth":1159,"text":958},{"id":1021,"depth":1129,"text":1022,"children":3274},[3275,3276],{"id":1025,"depth":1159,"text":1028},{"id":1220,"depth":1159,"text":1223},{"id":1319,"depth":1129,"text":1320,"children":3278},[3279,3280,3281,3282],{"id":1323,"depth":1159,"text":1326},{"id":1350,"depth":1159,"text":1353},{"id":1372,"depth":1159,"text":1375},{"id":1390,"depth":1159,"text":1010},{"id":1410,"depth":1129,"text":335,"children":3284},[3285,3286,3287,3288,3289,3290,3291],{"id":1413,"depth":1159,"text":1416},{"id":1457,"depth":1159,"text":1460},{"id":1507,"depth":1159,"text":1510},{"id":1592,"depth":1159,"text":1595},{"id":1661,"depth":1159,"text":1664},{"id":1770,"depth":1159,"text":1773},{"id":1851,"depth":1159,"text":1854},{"id":1883,"depth":1129,"text":1884,"children":3293},[3294,3295],{"id":1887,"depth":1159,"text":1890},{"id":1980,"depth":1159,"text":2228},{"id":2036,"depth":1129,"text":617},{},{"title":184,"description":2230},1780436274350]