[{"data":1,"prerenderedAt":2007},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Fiam":64,"navigation":257,"navLinks_footer":837,"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout_page":850,"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout_surround":1558,"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout":1561},{"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":27,"path":29,"stem":70,"children":71},"docs\u002Fiam\u002Findex",[72,73,76,216,219,236,240],{"title":27,"path":29,"stem":70},{"title":14,"path":74,"stem":75},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":77,"path":78,"stem":79,"children":80},"Essentials","\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[81,82,86,90,94,98,102,106,110,114,118,122,126,130,134,138,142,146,150,154,158,162,166],{"title":77,"path":78,"stem":79},{"title":83,"path":84,"stem":85},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":87,"path":88,"stem":89},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":91,"path":92,"stem":93},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":95,"path":96,"stem":97},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":99,"path":100,"stem":101},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":103,"path":104,"stem":105},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":107,"path":108,"stem":109},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":111,"path":112,"stem":113},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":115,"path":116,"stem":117},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":119,"path":120,"stem":121},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":123,"path":124,"stem":125},"MFA","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":127,"path":128,"stem":129},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":131,"path":132,"stem":133},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":135,"path":136,"stem":137},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":139,"path":140,"stem":141},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":143,"path":144,"stem":145},"Logging","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":147,"path":148,"stem":149},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":151,"path":152,"stem":153},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":155,"path":156,"stem":157},"Cookies","\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":159,"path":160,"stem":161},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":163,"path":164,"stem":165},"Password Reset","\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":167,"path":168,"stem":169,"children":170},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[171,172,176,180,210,213],{"title":167,"path":168,"stem":169},{"title":173,"path":174,"stem":175},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":177,"path":178,"stem":179},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":181,"path":182,"stem":183,"children":184},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[185,186,190,194,198,202,206],{"title":181,"path":182,"stem":183},{"title":187,"path":188,"stem":189},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":191,"path":192,"stem":193},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":195,"path":196,"stem":197},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":199,"path":200,"stem":201},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":203,"path":204,"stem":205},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":207,"path":208,"stem":209},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":147,"path":211,"stem":212},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":214,"stem":215},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":217,"stem":218},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":220,"path":221,"stem":222,"children":223,"page":53},"Guides","\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[224,228,232],{"title":225,"path":226,"stem":227},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":229,"path":230,"stem":231},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":233,"path":234,"stem":235},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":237,"path":238,"stem":239},"Configuration","\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":241,"path":242,"stem":243,"children":244,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[245,249,253],{"title":246,"path":247,"stem":248},"API Reference","\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":250,"path":251,"stem":252},"Middleware Reference","\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":254,"path":255,"stem":256},"Routes Reference","\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",[258],{"title":9,"path":66,"stem":67,"children":259,"page":53},[260,398,516,521,577,644],{"title":20,"path":22,"stem":261,"children":262},"docs\u002Fauth-h3client\u002Findex",[263,264,273,307,331,353,356,376,379],{"title":20,"path":22,"stem":261},{"title":14,"path":265,"stem":266,"children":267},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[268,269],{"title":14,"path":265,"stem":266},{"title":270,"path":271,"stem":272},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":77,"path":274,"stem":275,"children":276},"\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[277,278,282,286,290,294,298,301,304],{"title":77,"path":274,"stem":275},{"title":279,"path":280,"stem":281},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":283,"path":284,"stem":285},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":287,"path":288,"stem":289},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":291,"path":292,"stem":293},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":295,"path":296,"stem":297},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":299,"stem":300},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":155,"path":302,"stem":303},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":143,"path":305,"stem":306},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":123,"path":308,"stem":309,"children":310},"\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[311,312,316,319,323,327],{"title":123,"path":308,"stem":309},{"title":313,"path":314,"stem":315},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":163,"path":317,"stem":318},"\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":320,"path":321,"stem":322},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":324,"path":325,"stem":326},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":328,"path":329,"stem":330},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":332,"path":333,"stem":334,"children":335},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[336,337,341,345,349],{"title":332,"path":333,"stem":334},{"title":338,"path":339,"stem":340},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":342,"path":343,"stem":344},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":346,"path":347,"stem":348},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":350,"path":351,"stem":352},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":354,"stem":355},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":220,"path":357,"stem":358,"children":359,"page":53},"\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[360,364,368,372],{"title":361,"path":362,"stem":363},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":365,"path":366,"stem":367},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":369,"path":370,"stem":371},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":373,"path":374,"stem":375},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":237,"path":377,"stem":378},"\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":246,"path":380,"stem":381,"children":382},"\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[383,384,387,390,394],{"title":246,"path":380,"stem":381},{"title":254,"path":385,"stem":386},"\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":250,"path":388,"stem":389},"\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":391,"path":392,"stem":393},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":395,"path":396,"stem":397},"Utilities","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",{"title":399,"path":35,"stem":400,"children":401},"Bot Detector","docs\u002Fbot-detection\u002Findex",[402,403,406,410,414,433,507,510,513],{"title":399,"path":35,"stem":400},{"title":14,"path":404,"stem":405},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":407,"path":408,"stem":409},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":411,"path":412,"stem":413},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":220,"path":415,"stem":416,"children":417,"page":53},"\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[418,422,426,429],{"title":419,"path":420,"stem":421},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":423,"path":424,"stem":425},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":143,"path":427,"stem":428},"\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":430,"path":431,"stem":432},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":434,"path":435,"stem":436,"children":437},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[438,439,443,447,451,455,459,463,467,471,475,479,483,487,491,495,499,503],{"title":434,"path":435,"stem":436},{"title":440,"path":441,"stem":442},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":444,"path":445,"stem":446},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":448,"path":449,"stem":450},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":452,"path":453,"stem":454},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":456,"path":457,"stem":458},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":460,"path":461,"stem":462},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":464,"path":465,"stem":466},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":468,"path":469,"stem":470},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":472,"path":473,"stem":474},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":476,"path":477,"stem":478},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":480,"path":481,"stem":482},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":484,"path":485,"stem":486},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":488,"path":489,"stem":490},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":492,"path":493,"stem":494},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":496,"path":497,"stem":498},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":500,"path":501,"stem":502},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":504,"path":505,"stem":506},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":508,"stem":509},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":246,"path":511,"stem":512},"\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":237,"path":514,"stem":515},"\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",{"title":517,"path":11,"stem":518,"children":519},"Introduction","docs\u002Fgetting-started\u002Findex",[520],{"title":517,"path":11,"stem":518},{"title":27,"path":29,"stem":70,"children":522},[523,524,525,565,566,571,572],{"title":27,"path":29,"stem":70},{"title":14,"path":74,"stem":75},{"title":77,"path":78,"stem":79,"children":526},[527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549],{"title":77,"path":78,"stem":79},{"title":83,"path":84,"stem":85},{"title":87,"path":88,"stem":89},{"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},{"title":111,"path":112,"stem":113},{"title":115,"path":116,"stem":117},{"title":119,"path":120,"stem":121},{"title":123,"path":124,"stem":125},{"title":127,"path":128,"stem":129},{"title":131,"path":132,"stem":133},{"title":135,"path":136,"stem":137},{"title":139,"path":140,"stem":141},{"title":143,"path":144,"stem":145},{"title":147,"path":148,"stem":149},{"title":151,"path":152,"stem":153},{"title":155,"path":156,"stem":157},{"title":159,"path":160,"stem":161},{"title":163,"path":164,"stem":165},{"title":167,"path":168,"stem":169,"children":550},[551,552,553,554,563,564],{"title":167,"path":168,"stem":169},{"title":173,"path":174,"stem":175},{"title":177,"path":178,"stem":179},{"title":181,"path":182,"stem":183,"children":555},[556,557,558,559,560,561,562],{"title":181,"path":182,"stem":183},{"title":187,"path":188,"stem":189},{"title":191,"path":192,"stem":193},{"title":195,"path":196,"stem":197},{"title":199,"path":200,"stem":201},{"title":203,"path":204,"stem":205},{"title":207,"path":208,"stem":209},{"title":147,"path":211,"stem":212},{"title":38,"path":214,"stem":215},{"title":38,"path":217,"stem":218},{"title":220,"path":221,"stem":222,"children":567,"page":53},[568,569,570],{"title":225,"path":226,"stem":227},{"title":229,"path":230,"stem":231},{"title":233,"path":234,"stem":235},{"title":237,"path":238,"stem":239},{"title":241,"path":242,"stem":243,"children":573,"page":53},[574,575,576],{"title":246,"path":247,"stem":248},{"title":250,"path":251,"stem":252},{"title":254,"path":255,"stem":256},{"title":40,"path":42,"stem":578,"children":579},"docs\u002Fshield-base\u002Findex",[580,581,584,588,629,633,637,641],{"title":40,"path":42,"stem":578},{"title":14,"path":582,"stem":583},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":585,"path":586,"stem":587},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":411,"path":589,"stem":590,"children":591},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[592,593,597,601,605,609,613,617,621,625],{"title":411,"path":589,"stem":590},{"title":594,"path":595,"stem":596},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":598,"path":599,"stem":600},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":602,"path":603,"stem":604},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":606,"path":607,"stem":608},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":610,"path":611,"stem":612},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":614,"path":615,"stem":616},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":618,"path":619,"stem":620},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":622,"path":623,"stem":624},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":626,"path":627,"stem":628},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":630,"path":631,"stem":632},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":634,"path":635,"stem":636},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":638,"path":639,"stem":640},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":246,"path":642,"stem":643},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":395,"path":48,"stem":645,"children":646},"docs\u002Futils\u002Findex",[647,648,665,698,795],{"title":395,"path":48,"stem":645},{"title":649,"path":650,"stem":651,"children":652,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[653,657,661],{"title":654,"path":655,"stem":656},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":658,"path":659,"stem":660},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":662,"path":663,"stem":664},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":666,"path":667,"stem":668,"children":669,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[670,674,678,682,686,690,694],{"title":671,"path":672,"stem":673},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":675,"path":676,"stem":677},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":679,"path":680,"stem":681},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":683,"path":684,"stem":685},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":687,"path":688,"stem":689},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":691,"path":692,"stem":693},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":695,"path":696,"stem":697},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":699,"path":700,"stem":701,"children":702,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[703,707,711,715,719,723,727,731,735,739,743,747,751,755,759,763,767,771,775,779,783,787,791],{"title":704,"path":705,"stem":706},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":708,"path":709,"stem":710},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":712,"path":713,"stem":714},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":716,"path":717,"stem":718},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":720,"path":721,"stem":722},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":724,"path":725,"stem":726},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":728,"path":729,"stem":730},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":732,"path":733,"stem":734},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":736,"path":737,"stem":738},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":740,"path":741,"stem":742},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":744,"path":745,"stem":746},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":748,"path":749,"stem":750},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":752,"path":753,"stem":754},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":756,"path":757,"stem":758},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":760,"path":761,"stem":762},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":764,"path":765,"stem":766},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":768,"path":769,"stem":770},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":772,"path":773,"stem":774},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":776,"path":777,"stem":778},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":780,"path":781,"stem":782},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":784,"path":785,"stem":786},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":788,"path":789,"stem":790},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":792,"path":793,"stem":794},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":796,"path":797,"stem":798,"children":799},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[800,801,805,809,813,817,821,825,829,833],{"title":796,"path":797,"stem":798},{"title":802,"path":803,"stem":804},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":806,"path":807,"stem":808},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":810,"path":811,"stem":812},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":814,"path":815,"stem":816},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":818,"path":819,"stem":820},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":822,"path":823,"stem":824},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":826,"path":827,"stem":828},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":830,"path":831,"stem":832},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":834,"path":835,"stem":836},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",{"id":4,"extension":5,"links":838,"meta":849,"stem":62,"__hash__":63},[839,847,848],{"nested":8,"label":9,"icon":10,"to":11,"children":840},[841,842,843,844,845,846],{"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":851,"title":107,"body":852,"description":1550,"extension":1551,"icon":1552,"meta":1553,"module":1554,"navigation":8,"path":108,"rawbody":1555,"seo":1556,"stem":109,"__hash__":1557},"docs\u002Fdocs\u002Fiam\u002F01.essentials\u002F06.logout.md",{"type":853,"value":854,"toc":1539},"minimark",[855,859,862,867,900,906,916,999,1013,1015,1019,1026,1221,1223,1227,1232,1301,1305,1357,1359,1363,1373,1399,1407,1409,1413,1507,1513,1515,1519,1522,1528,1535],[856,857,858],"p",{},"The logout route terminates the current session by invalidating both the refresh token and the access token, then clearing the client cookies. The route requires both tokens to be present, verifies them independently, and uses two separate blocking mechanisms to prevent post-logout reuse.",[860,861],"hr",{},[863,864,866],"h2",{"id":865},"route","Route",[868,869,870,883],"table",{},[871,872,873],"thead",{},[874,875,876,880],"tr",{},[877,878,879],"th",{},"Method",[877,881,882],{},"Path",[884,885,886],"tbody",{},[874,887,888,895],{},[889,890,891],"td",{},[892,893,894],"code",{},"POST",[889,896,897],{},[892,898,899],{},"\u002Fauth\u002Flogout",[856,901,902],{},[903,904,905],"strong",{},"Middleware chain:",[907,908,913],"pre",{"className":909,"code":911,"language":912},[910],"language-text","requireRefreshToken, requireAccessToken, acceptCookieOnly, handleLogout\n","text",[892,914,911],{"__ignoreMap":915},"",[917,918,920,925,940,944,956,960,967,970],"steps",{"level":919},"4",[921,922,924],"h4",{"id":923},"requirerefreshtoken","requireRefreshToken",[856,926,927,928,931,932,935,936,939],{},"Checks that the ",[892,929,930],{},"session"," cookie is present in ",[892,933,934],{},"req.cookies",". Returns ",[892,937,938],{},"401"," if missing.",[921,941,943],{"id":942},"requireaccesstoken","requireAccessToken",[856,945,927,946,949,950,935,953,955],{},[892,947,948],{},"Authorization: Bearer \u003Ctoken>"," header is present and well-formed. Extracts the token and sets it on ",[892,951,952],{},"req.token",[892,954,938],{}," if the header is missing or malformed.",[921,957,959],{"id":958},"acceptcookieonly","acceptCookieOnly",[856,961,962,963,966],{},"Enforces that the request carries no body, no query string, and no ",[892,964,965],{},"Content-Type"," header. This prevents attackers from injecting data into what should be a pure cookie-based request.",[856,968,969],{},"Rejected conditions:",[971,972,973,980,991,994],"ul",{},[974,975,976,977,979],"li",{},"No ",[892,978,930],{}," cookie (401)",[974,981,982,983,986,987,990],{},"Request has a parsed JSON body, a ",[892,984,985],{},"Content-Length"," greater than zero, or ",[892,988,989],{},"Transfer-Encoding: chunked"," (400)",[974,992,993],{},"Query string is present (400)",[974,995,996,998],{},[892,997,965],{}," header is present (400)",[856,1000,1001,1002,1007,1008,1012],{},"See ",[1003,1004,1006],"a",{"href":1005},"\u002Fdocs\u002Fiam\u002Froutes","Routes"," for how to mount the token rotation router and ",[1003,1009,1011],{"href":1010},"\u002Fdocs\u002Fiam\u002Fmiddleware","Middleware"," for details on each middleware.",[860,1014],{},[863,1016,1018],{"id":1017},"the-logout-sequence","The logout sequence",[856,1020,1021,1022,1025],{},"After the middleware chain passes, the ",[892,1023,1024],{},"handleLogout"," controller runs the following steps in order.",[917,1027,1028,1032,1047,1051,1068,1072,1075,1079,1110,1120,1124,1135,1139,1146,1150,1170,1174,1190,1194],{"level":919},[921,1029,1031],{"id":1030},"rate-limiting-ip","Rate limiting (IP)",[856,1033,1034,1035,1038,1039,1042,1043,1046],{},"A union limiter keyed on ",[892,1036,1037],{},"req.ip"," combines a burst guard (2 points per second, blocks 30 minutes) with a slow guard (3 points per 10 minutes, blocks 1 hour). A consecutive-violation cache (10-minute TTL) escalates the block duration on repeated abuse. See ",[1003,1040,147],{"href":1041},"\u002Fdocs\u002Fiam\u002Frate-limiting"," for the ",[892,1044,1045],{},"guard()"," architecture.",[921,1048,1050],{"id":1049},"verify-both-tokens-are-present","Verify both tokens are present",[856,1052,1053,1054,1057,1058,1060,1061,1063,1064,1067],{},"The controller reads the raw refresh token from ",[892,1055,1056],{},"req.cookies.session"," and the access token from ",[892,1059,952],{}," (set by the ",[892,1062,943],{}," middleware). If either is missing at this point, the controller returns ",[892,1065,1066],{},"400 { error: 'Missing token' }",".",[921,1069,1071],{"id":1070},"rate-limiting-token-hash","Rate limiting (token hash)",[856,1073,1074],{},"The refresh token is hashed with SHA-256 and used as the key for a second rate limiter: 3 points per 12 hours, blocking for 15 hours. This prevents an attacker from repeatedly calling logout with the same stolen token to probe for timing differences.",[921,1076,1078],{"id":1077},"consume-the-refresh-token","Consume the refresh token",[856,1080,1081,1082,1085,1086,1089,1090,1093,1094,1097,1098,1101,1102,1105,1106,1109],{},"The controller calls ",[892,1083,1084],{},"consumeAndVerifyRefreshToken(rawRefreshToken)",". This function atomically increments ",[892,1087,1088],{},"usage_count"," to ",[892,1091,1092],{},"1"," inside a transaction, but only if the token exists, is still valid, has not been consumed before (",[892,1095,1096],{},"usage_count = 0","), and has not expired. If the consumption fails, the controller returns the failure reason from the function (e.g. ",[892,1099,1100],{},"Token not found",", ",[892,1103,1104],{},"Token has been revoked",", or ",[892,1107,1108],{},"Token already used",").",[856,1111,1001,1112,1115,1116,1119],{},[1003,1113,91],{"href":1114},"\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens#consumeandverifyrefreshtoken"," for the full semantics of ",[892,1117,1118],{},"consumeAndVerifyRefreshToken",", including the reuse detection path that revokes all sessions when a previously consumed token is presented.",[921,1121,1123],{"id":1122},"revoke-the-refresh-token","Revoke the refresh token",[856,1125,1126,1127,1130,1131,1134],{},"After successful consumption, the controller calls ",[892,1128,1129],{},"revokeRefreshToken(rawRefreshToken)"," to set ",[892,1132,1133],{},"valid = 0"," on the row. The row is not deleted. Keeping it in the table allows the reuse detection system to identify the token later if an attacker tries to use a copy.",[921,1136,1138],{"id":1137},"block-the-token-hash-in-the-rate-limiter","Block the token hash in the rate limiter",[856,1140,1141,1142,1145],{},"The hashed refresh token is blocked in the rate limiter for the remaining ",[892,1143,1144],{},"refresh_ttl"," duration. Any future request using this token hash (whether for rotation, logout, or access) is rejected at the rate-limiter layer before reaching any database logic.",[921,1147,1149],{"id":1148},"verify-the-access-token","Verify the access token",[856,1151,1081,1152,1155,1156,1159,1160,1162,1163,1166,1167,1067],{},[892,1153,1154],{},"verifyAccessToken(accessToken)"," to decode the JWT and extract the ",[892,1157,1158],{},"jti"," (JWT ID). If the token has already expired, the controller still extracts the ",[892,1161,1158],{}," from the payload when the error type is ",[892,1164,1165],{},"TokenExpiredError",". Other verification failures (invalid signature, malformed token) cause the controller to return ",[892,1168,1169],{},"400",[921,1171,1173],{"id":1172},"blacklist-the-jti","Blacklist the JTI",[856,1175,1176,1177,1179,1180,1183,1184,1186,1187,1189],{},"The ",[892,1178,1158],{}," from the access token is blocked in the rate-limiter blacklist for 24 hours (86,400 seconds). The ",[892,1181,1182],{},"protectRoute"," middleware checks every incoming access token's ",[892,1185,1158],{}," against this blacklist. If found, the request is rejected with ",[892,1188,938],{},". This covers the window between logout and the access token's natural expiry.",[921,1191,1193],{"id":1192},"clear-cookies","Clear cookies",[856,1195,1196,1197,1199,1200,1203,1204,1101,1207,1101,1210,1213,1214,1199,1217,1220],{},"The controller clears both the ",[892,1198,930],{}," and ",[892,1201,1202],{},"iat"," cookies by setting them to empty strings with the same options used when they were created (",[892,1205,1206],{},"httpOnly",[892,1208,1209],{},"secure",[892,1211,1212],{},"sameSite: strict",", matching ",[892,1215,1216],{},"path",[892,1218,1219],{},"domain","). This ensures the browser removes the cookies on the next response.",[860,1222],{},[863,1224,1226],{"id":1225},"response","Response",[1228,1229,1231],"h3",{"id":1230},"success-200","Success (200)",[907,1233,1236],{"className":1234,"code":1235,"language":5,"meta":915,"style":915},"language-json shiki shiki-themes light-plus light-plus dracula","{\n  \"ok\": true,\n  \"message\": \"Logged out successfully\"\n}\n",[892,1237,1238,1247,1272,1295],{"__ignoreMap":915},[1239,1240,1243],"span",{"class":1241,"line":1242},"line",1,[1239,1244,1246],{"class":1245},"sDd4n","{\n",[1239,1248,1250,1254,1258,1261,1265,1269],{"class":1241,"line":1249},2,[1239,1251,1253],{"class":1252},"saJyd","  \"",[1239,1255,1257],{"class":1256},"s_W10","ok",[1239,1259,1260],{"class":1252},"\"",[1239,1262,1264],{"class":1263},"saOXh",":",[1239,1266,1268],{"class":1267},"sjR7W"," true",[1239,1270,1271],{"class":1245},",\n",[1239,1273,1275,1277,1280,1282,1284,1288,1292],{"class":1241,"line":1274},3,[1239,1276,1253],{"class":1252},[1239,1278,1279],{"class":1256},"message",[1239,1281,1260],{"class":1252},[1239,1283,1264],{"class":1263},[1239,1285,1287],{"class":1286},"sFkSl"," \"",[1239,1289,1291],{"class":1290},"sFB1V","Logged out successfully",[1239,1293,1294],{"class":1286},"\"\n",[1239,1296,1298],{"class":1241,"line":1297},4,[1239,1299,1300],{"class":1245},"}\n",[1228,1302,1304],{"id":1303},"error-responses","Error responses",[868,1306,1307,1317],{},[871,1308,1309],{},[874,1310,1311,1314],{},[877,1312,1313],{},"Status",[877,1315,1316],{},"Condition",[884,1318,1319,1331,1347],{},[874,1320,1321,1325],{},[889,1322,1323],{},[892,1324,1169],{},[889,1326,1327,1328,1330],{},"Missing token, invalid access token, body or query string present, ",[892,1329,965],{}," header present",[874,1332,1333,1337],{},[889,1334,1335],{},[892,1336,938],{},[889,1338,1339,1340,1342,1343,1346],{},"Missing ",[892,1341,930],{}," cookie, missing ",[892,1344,1345],{},"Authorization"," header, refresh token not found or revoked",[874,1348,1349,1354],{},[889,1350,1351],{},[892,1352,1353],{},"429",[889,1355,1356],{},"Rate limit exceeded (IP or token hash)",[860,1358],{},[863,1360,1362],{"id":1361},"why-both-consume-and-revoke","Why both consume and revoke?",[856,1364,1365,1366,1368,1369,1372],{},"The two-step process (",[892,1367,1118],{}," then ",[892,1370,1371],{},"revokeRefreshToken",") is deliberate:",[1374,1375,1376,1388],"ol",{},[974,1377,1378,1381,1382,1385,1386,1067],{},[903,1379,1380],{},"Consumption"," atomically sets ",[892,1383,1384],{},"usage_count = 1",". This is the reuse detection anchor. If a copy of the token exists elsewhere, any attempt to consume it again triggers the revoke-all-sessions path inside ",[892,1387,1118],{},[974,1389,1390,1392,1393,1395,1396,1398],{},[903,1391,191],{}," sets ",[892,1394,1133],{},". This makes the token fail the basic validity check in any future query, providing an immediate block without relying on the ",[892,1397,1088],{}," check.",[856,1400,1401,1402,1406],{},"Together, these two operations ensure that a stolen token copy is caught by whichever check runs first: the validity check (fast) or the reuse detection check (comprehensive). See the ",[1003,1403,1405],{"href":1404},"\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens#reuse-detection","Reuse Detection"," section in the refresh tokens doc for a full scenario walkthrough.",[860,1408],{},[863,1410,1412],{"id":1411},"rate-limiter-reference","Rate limiter reference",[868,1414,1415,1434],{},[871,1416,1417],{},[874,1418,1419,1422,1425,1428,1431],{},[877,1420,1421],{},"Limiter",[877,1423,1424],{},"Key",[877,1426,1427],{},"Points",[877,1429,1430],{},"Window",[877,1432,1433],{},"Block duration",[884,1435,1436,1454,1472,1489],{},[874,1437,1438,1441,1445,1448,1451],{},[889,1439,1440],{},"IP burst",[889,1442,1443],{},[892,1444,1037],{},[889,1446,1447],{},"2 \u002F 1 second",[889,1449,1450],{},"1 s",[889,1452,1453],{},"30 min",[874,1455,1456,1459,1463,1466,1469],{},[889,1457,1458],{},"IP slow",[889,1460,1461],{},[892,1462,1037],{},[889,1464,1465],{},"3 \u002F 10 minutes",[889,1467,1468],{},"10 min",[889,1470,1471],{},"1 h",[874,1473,1474,1477,1480,1483,1486],{},[889,1475,1476],{},"Token hash",[889,1478,1479],{},"SHA-256 of refresh token",[889,1481,1482],{},"3 \u002F 12 hours",[889,1484,1485],{},"12 h",[889,1487,1488],{},"15 h",[874,1490,1491,1494,1499,1502,1504],{},[889,1492,1493],{},"JTI blacklist",[889,1495,1496,1497],{},"Access token ",[892,1498,1158],{},[889,1500,1501],{},"—",[889,1503,1501],{},[889,1505,1506],{},"24 h",[856,1508,1509,1510,1512],{},"The JTI blacklist is not a traditional rate limiter. It is a key-value block list with a fixed TTL. The ",[892,1511,1182],{}," middleware checks it on every authenticated request.",[860,1514],{},[863,1516,1518],{"id":1517},"lifecycle-summary","Lifecycle summary",[856,1520,1521],{},"The full session lifecycle from login to logout:",[907,1523,1526],{"className":1524,"code":1525,"language":912},[910],"Login - issue refresh token (usage_count=0, valid=1)\n      - issue access token (JWT with jti)\n      - set session + iat cookies\n\n  ... user makes authenticated requests ...\n\nLogout - consume refresh token (usage_count= 0 - 1)\n       - revoke refresh token (valid= 1 - 0)\n       - block token hash in rate limiter\n       - blacklist access token jti for 24h\n       - clear session + iat cookies\n",[892,1527,1525],{"__ignoreMap":915},[856,1529,1530,1531,1534],{},"After logout, the access token is unusable (JTI blacklisted), the refresh token is unusable (consumed, revoked, and hash-blocked), and the client has no cookies. The user must ",[1003,1532,1533],{"href":104},"log in"," again to start a new session.",[1536,1537,1538],"style",{},"html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .saJyd, html code.shiki .saJyd{--shiki-light:#0451A5;--shiki-default:#0451A5;--shiki-dark:#8BE9FE}html pre.shiki code .s_W10, html code.shiki .s_W10{--shiki-light:#0451A5;--shiki-default:#0451A5;--shiki-dark:#8BE9FD}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html pre.shiki code .sjR7W, html code.shiki .sjR7W{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#BD93F9}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 .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);}",{"title":915,"searchDepth":1249,"depth":1249,"links":1540},[1541,1542,1543,1547,1548,1549],{"id":865,"depth":1249,"text":866},{"id":1017,"depth":1249,"text":1018},{"id":1225,"depth":1249,"text":1226,"children":1544},[1545,1546],{"id":1230,"depth":1274,"text":1231},{"id":1303,"depth":1274,"text":1304},{"id":1361,"depth":1249,"text":1362},{"id":1411,"depth":1249,"text":1412},{"id":1517,"depth":1249,"text":1518},"How the IAM service terminates a session by consuming and revoking the refresh token, blacklisting the access token, blocking the token hash in the rate limiter, and clearing cookies.","md","i-lucide-log-out",{},null,"---\ntitle: Logout\ndescription: How the IAM service terminates a session by consuming and revoking the refresh token, blacklisting the access token, blocking the token hash in the rate limiter, and clearing cookies.\nicon: i-lucide-log-out\n---\n\nThe logout route terminates the current session by invalidating both the refresh token and the access token, then clearing the client cookies. The route requires both tokens to be present, verifies them independently, and uses two separate blocking mechanisms to prevent post-logout reuse.\n\n---\n\n## Route\n\n| Method | Path |\n|---|---|\n| `POST` | `\u002Fauth\u002Flogout` |\n\n**Middleware chain:**\n\n```\nrequireRefreshToken, requireAccessToken, acceptCookieOnly, handleLogout\n```\n\n::steps{level=\"4\"}\n#### requireRefreshToken\n\nChecks that the `session` cookie is present in `req.cookies`. Returns `401` if missing.\n\n#### requireAccessToken\n\nChecks that the `Authorization: Bearer \u003Ctoken>` header is present and well-formed. Extracts the token and sets it on `req.token`. Returns `401` if the header is missing or malformed.\n\n#### acceptCookieOnly\n\nEnforces that the request carries no body, no query string, and no `Content-Type` header. This prevents attackers from injecting data into what should be a pure cookie-based request.\n\nRejected conditions:\n- No `session` cookie (401)\n- Request has a parsed JSON body, a `Content-Length` greater than zero, or `Transfer-Encoding: chunked` (400)\n- Query string is present (400)\n- `Content-Type` header is present (400)\n::\n\nSee [Routes](\u002Fdocs\u002Fiam\u002Froutes) for how to mount the token rotation router and [Middleware](\u002Fdocs\u002Fiam\u002Fmiddleware) for details on each middleware.\n\n---\n\n## The logout sequence\n\nAfter the middleware chain passes, the `handleLogout` controller runs the following steps in order.\n\n::steps{level=\"4\"}\n#### Rate limiting (IP)\n\nA union limiter keyed on `req.ip` combines a burst guard (2 points per second, blocks 30 minutes) with a slow guard (3 points per 10 minutes, blocks 1 hour). A consecutive-violation cache (10-minute TTL) escalates the block duration on repeated abuse. See [Rate Limiting](\u002Fdocs\u002Fiam\u002Frate-limiting) for the `guard()` architecture.\n\n#### Verify both tokens are present\n\nThe controller reads the raw refresh token from `req.cookies.session` and the access token from `req.token` (set by the `requireAccessToken` middleware). If either is missing at this point, the controller returns `400 { error: 'Missing token' }`.\n\n#### Rate limiting (token hash)\n\nThe refresh token is hashed with SHA-256 and used as the key for a second rate limiter: 3 points per 12 hours, blocking for 15 hours. This prevents an attacker from repeatedly calling logout with the same stolen token to probe for timing differences.\n\n#### Consume the refresh token\n\nThe controller calls `consumeAndVerifyRefreshToken(rawRefreshToken)`. This function atomically increments `usage_count` to `1` inside a transaction, but only if the token exists, is still valid, has not been consumed before (`usage_count = 0`), and has not expired. If the consumption fails, the controller returns the failure reason from the function (e.g. `Token not found`, `Token has been revoked`, or `Token already used`).\n\nSee [Refresh Tokens](\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens#consumeandverifyrefreshtoken) for the full semantics of `consumeAndVerifyRefreshToken`, including the reuse detection path that revokes all sessions when a previously consumed token is presented.\n\n#### Revoke the refresh token\n\nAfter successful consumption, the controller calls `revokeRefreshToken(rawRefreshToken)` to set `valid = 0` on the row. The row is not deleted. Keeping it in the table allows the reuse detection system to identify the token later if an attacker tries to use a copy.\n\n#### Block the token hash in the rate limiter\n\nThe hashed refresh token is blocked in the rate limiter for the remaining `refresh_ttl` duration. Any future request using this token hash (whether for rotation, logout, or access) is rejected at the rate-limiter layer before reaching any database logic.\n\n#### Verify the access token\n\nThe controller calls `verifyAccessToken(accessToken)` to decode the JWT and extract the `jti` (JWT ID). If the token has already expired, the controller still extracts the `jti` from the payload when the error type is `TokenExpiredError`. Other verification failures (invalid signature, malformed token) cause the controller to return `400`.\n\n#### Blacklist the JTI\n\nThe `jti` from the access token is blocked in the rate-limiter blacklist for 24 hours (86,400 seconds). The `protectRoute` middleware checks every incoming access token's `jti` against this blacklist. If found, the request is rejected with `401`. This covers the window between logout and the access token's natural expiry.\n\n#### Clear cookies\n\nThe controller clears both the `session` and `iat` cookies by setting them to empty strings with the same options used when they were created (`httpOnly`, `secure`, `sameSite: strict`, matching `path` and `domain`). This ensures the browser removes the cookies on the next response.\n::\n\n---\n\n## Response\n\n### Success (200)\n\n```json\n{\n  \"ok\": true,\n  \"message\": \"Logged out successfully\"\n}\n```\n\n### Error responses\n\n| Status | Condition |\n|---|---|\n| `400` | Missing token, invalid access token, body or query string present, `Content-Type` header present |\n| `401` | Missing `session` cookie, missing `Authorization` header, refresh token not found or revoked |\n| `429` | Rate limit exceeded (IP or token hash) |\n\n---\n\n## Why both consume and revoke?\n\nThe two-step process (`consumeAndVerifyRefreshToken` then `revokeRefreshToken`) is deliberate:\n\n1. **Consumption** atomically sets `usage_count = 1`. This is the reuse detection anchor. If a copy of the token exists elsewhere, any attempt to consume it again triggers the revoke-all-sessions path inside `consumeAndVerifyRefreshToken`.\n\n2. **Revocation** sets `valid = 0`. This makes the token fail the basic validity check in any future query, providing an immediate block without relying on the `usage_count` check.\n\nTogether, these two operations ensure that a stolen token copy is caught by whichever check runs first: the validity check (fast) or the reuse detection check (comprehensive). See the [Reuse Detection](\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens#reuse-detection) section in the refresh tokens doc for a full scenario walkthrough.\n\n---\n\n## Rate limiter reference\n\n| Limiter | Key | Points | Window | Block duration |\n|---|---|---|---|---|\n| IP burst | `req.ip` | 2 \u002F 1 second | 1 s | 30 min |\n| IP slow | `req.ip` | 3 \u002F 10 minutes | 10 min | 1 h |\n| Token hash | SHA-256 of refresh token | 3 \u002F 12 hours | 12 h | 15 h |\n| JTI blacklist | Access token `jti` | — | — | 24 h |\n\nThe JTI blacklist is not a traditional rate limiter. It is a key-value block list with a fixed TTL. The `protectRoute` middleware checks it on every authenticated request.\n\n---\n\n## Lifecycle summary\n\nThe full session lifecycle from login to logout:\n\n```\nLogin - issue refresh token (usage_count=0, valid=1)\n      - issue access token (JWT with jti)\n      - set session + iat cookies\n\n  ... user makes authenticated requests ...\n\nLogout - consume refresh token (usage_count= 0 - 1)\n       - revoke refresh token (valid= 1 - 0)\n       - block token hash in rate limiter\n       - blacklist access token jti for 24h\n       - clear session + iat cookies\n```\n\nAfter logout, the access token is unusable (JTI blacklisted), the refresh token is unusable (consumed, revoked, and hash-blocked), and the client has no cookies. The user must [log in](\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin) again to start a new session.",{"title":107,"description":1550},"kE30cXQ4o0lmEt-lu2xdMP_dBAfZUz-WUfKULL1afHM",[1559,1560],{"title":103,"path":104,"stem":105,"children":-1},{"title":111,"path":112,"stem":113,"children":-1},{"id":851,"title":107,"body":1562,"description":1550,"extension":1551,"icon":1552,"meta":2005,"module":1554,"navigation":8,"path":108,"rawbody":1555,"seo":2006,"stem":109,"__hash__":1557},{"type":853,"value":1563,"toc":1994},[1564,1566,1568,1570,1592,1596,1601,1649,1655,1657,1659,1663,1773,1775,1777,1779,1821,1823,1865,1867,1869,1875,1893,1897,1899,1901,1973,1977,1979,1981,1983,1988,1992],[856,1565,858],{},[860,1567],{},[863,1569,866],{"id":865},[868,1571,1572,1580],{},[871,1573,1574],{},[874,1575,1576,1578],{},[877,1577,879],{},[877,1579,882],{},[884,1581,1582],{},[874,1583,1584,1588],{},[889,1585,1586],{},[892,1587,894],{},[889,1589,1590],{},[892,1591,899],{},[856,1593,1594],{},[903,1595,905],{},[907,1597,1599],{"className":1598,"code":911,"language":912},[910],[892,1600,911],{"__ignoreMap":915},[917,1602,1603,1605,1613,1615,1623,1625,1629,1631],{"level":919},[921,1604,924],{"id":923},[856,1606,927,1607,931,1609,935,1611,939],{},[892,1608,930],{},[892,1610,934],{},[892,1612,938],{},[921,1614,943],{"id":942},[856,1616,927,1617,949,1619,935,1621,955],{},[892,1618,948],{},[892,1620,952],{},[892,1622,938],{},[921,1624,959],{"id":958},[856,1626,962,1627,966],{},[892,1628,965],{},[856,1630,969],{},[971,1632,1633,1637,1643,1645],{},[974,1634,976,1635,979],{},[892,1636,930],{},[974,1638,982,1639,986,1641,990],{},[892,1640,985],{},[892,1642,989],{},[974,1644,993],{},[974,1646,1647,998],{},[892,1648,965],{},[856,1650,1001,1651,1007,1653,1012],{},[1003,1652,1006],{"href":1005},[1003,1654,1011],{"href":1010},[860,1656],{},[863,1658,1018],{"id":1017},[856,1660,1021,1661,1025],{},[892,1662,1024],{},[917,1664,1665,1667,1675,1677,1687,1689,1691,1693,1709,1715,1717,1723,1725,1729,1731,1743,1745,1755,1757],{"level":919},[921,1666,1031],{"id":1030},[856,1668,1034,1669,1038,1671,1042,1673,1046],{},[892,1670,1037],{},[1003,1672,147],{"href":1041},[892,1674,1045],{},[921,1676,1050],{"id":1049},[856,1678,1053,1679,1057,1681,1060,1683,1063,1685,1067],{},[892,1680,1056],{},[892,1682,952],{},[892,1684,943],{},[892,1686,1066],{},[921,1688,1071],{"id":1070},[856,1690,1074],{},[921,1692,1078],{"id":1077},[856,1694,1081,1695,1085,1697,1089,1699,1093,1701,1097,1703,1101,1705,1105,1707,1109],{},[892,1696,1084],{},[892,1698,1088],{},[892,1700,1092],{},[892,1702,1096],{},[892,1704,1100],{},[892,1706,1104],{},[892,1708,1108],{},[856,1710,1001,1711,1115,1713,1119],{},[1003,1712,91],{"href":1114},[892,1714,1118],{},[921,1716,1123],{"id":1122},[856,1718,1126,1719,1130,1721,1134],{},[892,1720,1129],{},[892,1722,1133],{},[921,1724,1138],{"id":1137},[856,1726,1141,1727,1145],{},[892,1728,1144],{},[921,1730,1149],{"id":1148},[856,1732,1081,1733,1155,1735,1159,1737,1162,1739,1166,1741,1067],{},[892,1734,1154],{},[892,1736,1158],{},[892,1738,1158],{},[892,1740,1165],{},[892,1742,1169],{},[921,1744,1173],{"id":1172},[856,1746,1176,1747,1179,1749,1183,1751,1186,1753,1189],{},[892,1748,1158],{},[892,1750,1182],{},[892,1752,1158],{},[892,1754,938],{},[921,1756,1193],{"id":1192},[856,1758,1196,1759,1199,1761,1203,1763,1101,1765,1101,1767,1213,1769,1199,1771,1220],{},[892,1760,930],{},[892,1762,1202],{},[892,1764,1206],{},[892,1766,1209],{},[892,1768,1212],{},[892,1770,1216],{},[892,1772,1219],{},[860,1774],{},[863,1776,1226],{"id":1225},[1228,1778,1231],{"id":1230},[907,1780,1781],{"className":1234,"code":1235,"language":5,"meta":915,"style":915},[892,1782,1783,1787,1801,1817],{"__ignoreMap":915},[1239,1784,1785],{"class":1241,"line":1242},[1239,1786,1246],{"class":1245},[1239,1788,1789,1791,1793,1795,1797,1799],{"class":1241,"line":1249},[1239,1790,1253],{"class":1252},[1239,1792,1257],{"class":1256},[1239,1794,1260],{"class":1252},[1239,1796,1264],{"class":1263},[1239,1798,1268],{"class":1267},[1239,1800,1271],{"class":1245},[1239,1802,1803,1805,1807,1809,1811,1813,1815],{"class":1241,"line":1274},[1239,1804,1253],{"class":1252},[1239,1806,1279],{"class":1256},[1239,1808,1260],{"class":1252},[1239,1810,1264],{"class":1263},[1239,1812,1287],{"class":1286},[1239,1814,1291],{"class":1290},[1239,1816,1294],{"class":1286},[1239,1818,1819],{"class":1241,"line":1297},[1239,1820,1300],{"class":1245},[1228,1822,1304],{"id":1303},[868,1824,1825,1833],{},[871,1826,1827],{},[874,1828,1829,1831],{},[877,1830,1313],{},[877,1832,1316],{},[884,1834,1835,1845,1857],{},[874,1836,1837,1841],{},[889,1838,1839],{},[892,1840,1169],{},[889,1842,1327,1843,1330],{},[892,1844,965],{},[874,1846,1847,1851],{},[889,1848,1849],{},[892,1850,938],{},[889,1852,1339,1853,1342,1855,1346],{},[892,1854,930],{},[892,1856,1345],{},[874,1858,1859,1863],{},[889,1860,1861],{},[892,1862,1353],{},[889,1864,1356],{},[860,1866],{},[863,1868,1362],{"id":1361},[856,1870,1365,1871,1368,1873,1372],{},[892,1872,1118],{},[892,1874,1371],{},[1374,1876,1877,1885],{},[974,1878,1879,1381,1881,1385,1883,1067],{},[903,1880,1380],{},[892,1882,1384],{},[892,1884,1118],{},[974,1886,1887,1392,1889,1395,1891,1398],{},[903,1888,191],{},[892,1890,1133],{},[892,1892,1088],{},[856,1894,1401,1895,1406],{},[1003,1896,1405],{"href":1404},[860,1898],{},[863,1900,1412],{"id":1411},[868,1902,1903,1917],{},[871,1904,1905],{},[874,1906,1907,1909,1911,1913,1915],{},[877,1908,1421],{},[877,1910,1424],{},[877,1912,1427],{},[877,1914,1430],{},[877,1916,1433],{},[884,1918,1919,1933,1947,1959],{},[874,1920,1921,1923,1927,1929,1931],{},[889,1922,1440],{},[889,1924,1925],{},[892,1926,1037],{},[889,1928,1447],{},[889,1930,1450],{},[889,1932,1453],{},[874,1934,1935,1937,1941,1943,1945],{},[889,1936,1458],{},[889,1938,1939],{},[892,1940,1037],{},[889,1942,1465],{},[889,1944,1468],{},[889,1946,1471],{},[874,1948,1949,1951,1953,1955,1957],{},[889,1950,1476],{},[889,1952,1479],{},[889,1954,1482],{},[889,1956,1485],{},[889,1958,1488],{},[874,1960,1961,1963,1967,1969,1971],{},[889,1962,1493],{},[889,1964,1496,1965],{},[892,1966,1158],{},[889,1968,1501],{},[889,1970,1501],{},[889,1972,1506],{},[856,1974,1509,1975,1512],{},[892,1976,1182],{},[860,1978],{},[863,1980,1518],{"id":1517},[856,1982,1521],{},[907,1984,1986],{"className":1985,"code":1525,"language":912},[910],[892,1987,1525],{"__ignoreMap":915},[856,1989,1530,1990,1534],{},[1003,1991,1533],{"href":104},[1536,1993,1538],{},{"title":915,"searchDepth":1249,"depth":1249,"links":1995},[1996,1997,1998,2002,2003,2004],{"id":865,"depth":1249,"text":866},{"id":1017,"depth":1249,"text":1018},{"id":1225,"depth":1249,"text":1226,"children":1999},[2000,2001],{"id":1230,"depth":1274,"text":1231},{"id":1303,"depth":1274,"text":1304},{"id":1361,"depth":1249,"text":1362},{"id":1411,"depth":1249,"text":1412},{"id":1517,"depth":1249,"text":1518},{},{"title":107,"description":1550},1780436281705]