1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <meta name="robots" content="noindex"> 7 <title>Sign Up - Abacus.AI</title> 8
8<script> 9 window.dataLayer = window.dataLayer || []; 10 function gtag(){dataLayer.push(arguments);} 11 (function() { 12 var match = document.cookie.match(/(?:^|; )_callow1=([^;]*)/) || document.cookie.match(/(?:^|; )_callow=([^;]*)/); 13 var consent = match ? decodeURIComponent(match[1]) : null; 14 if (consent === 'no') { 15 gtag('consent', 'default', { 16 analytics_storage: 'denied', 17 ad_storage: 'denied', 18 ad_user_data: 'denied', 19 ad_personalization: 'denied' 20 }); 21 } 22 })(); 23 </script>
vendor: 72 bytes, lines 23-24
23 24 <script async src="https://www.googletagmanager.com/gtag/js?id=
24G-NM4YZNYB7G
vendor: 20 bytes, lines 24-25
24"></script> 25
25<script> 26 gtag('js', new Date()); 27 28 gtag('config', 'G-NM4YZNYB7G', {cookie_flags: 'secure;samesite=none'}); 29 gtag('set', 'user_properties', {'exp': 'exp_ns2_revamp'}) 30 gtag('event', 'experiment_set', {'exp': 'exp_ns2_revamp'}) 31 </script>
31 32 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 33 34
34<script>(function () { try { var t = localStorage.getItem('ns2-theme'); if (t === 'light' || t === 'dark') { document.documentElement.setAttribute('data-ns2-theme', t); } } catch (e) {} })();</script>
34 35 36 <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap"> 37 <style> 38 :root{color-scheme:light;--bg:#f6f6fb;--card:#fff;--border:#e6e6f0;--border-strong:#d4d4e4;--text:#14143a;--body:#3d3d5c;--muted:#6b6b85;--accent:#5b3df5;--accent-hover:#4b2fe0;--field:#fff;--hover:#f6f6fb;--glow-a:#cdc2ff;--glow-b:#bfe0ff;--glow-c:#ffd9c9;--shadow:0 24px 60px rgba(20,20,58,.08);--err-bg:#fbe3e8;--err:#b3243f;--logo-ink:block;--logo-white:none} 39 @media (prefers-color-scheme:dark){:root:not([data-ns2-theme="light"]){color-scheme:dark;--bg:#0f0f2e;--card:#15163a;--border:rgba(255,255,255,.1);--border-strong:rgba(255,255,255,.2);--text:#edeef6;--body:#c9ccdd;--muted:#9a9eb8;--field:rgba(255,255,255,.04);--hover:rgba(255,255,255,.06);--glow-a:rgba(99,91,255,.55);--glow-b:rgba(56,132,255,.4);--glow-c:rgba(255,140,120,.25);--shadow:0 24px 60px rgba(0,0,0,.4);--err-bg:#3a1522;--err:#ff8fa3;--logo-ink:none;--logo-white:block}} 40 :root[data-ns2-theme="dark"]{color-scheme:dark;--bg:#0f0f2e;--card:#15163a;--border:rgba(255,255,255,.1);--border-strong:rgba(255,255,255,.2);--text:#edeef6;--body:#c9ccdd;--muted:#9a9eb8;--field:rgba(255,255,255,.04);--hover:rgba(255,255,255,.06);--glow-a:rgba(99,91,255,.55);--glow-b:rgba(56,132,255,.4);--glow-c:rgba(255,140,120,.25);--shadow:0 24px 60px rgba(0,0,0,.4);--err-bg:#3a1522;--err:#ff8fa3;--logo-ink:none;--logo-white:block} 41 *{box-sizing:border-box;margin:0;padding:0} 42 body{background:var(--bg);color:var(--text);font-family:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-weight:400;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:32px 16px;position:relative;overflow-x:hidden} 43 .glow{position:absolute;inset:0;pointer-events:none;overflow:hidden} 44 .glow i{position:absolute;border-radius:50%;filter:blur(90px);opacity:.75} 45 .glow i:nth-child(1){width:520px;height:520px;left:calc(50% - 560px);top:-120px;background:var(--glow-a)} 46 .glow i:nth-child(2){width:460px;height:460px;left:calc(50% + 120px);top:-60px;background:var(--glow-b)} 47 .glow i:nth-child(3){width:380px;height:380px;left:calc(50% - 120px);bottom:-200px;background:var(--glow-c)} 48 @media (prefers-reduced-motion:no-preference){.glow i{animation:drift 14s ease-in-out infinite alternate}.glow i:nth-child(2){animation-delay:-5s}.glow i:nth-child(3){animation-delay:-9s}@keyframes drift{to{transform:translate(40px,30px)}}} 49 .card{position:relative;width:100%;max-width:420px;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:36px 32px 28px;text-align:center;box-shadow:var(--shadow)} 50 .logo{margin-bottom:22px;display:flex;justify-content:center} 51 .logo .ink{display:var(--logo-ink)}.logo .white{display:var(--logo-white)} 52 h1{font-size:24px;font-weight:600;letter-spacing:-.01em;line-height:1.2;margin-bottom:6px;text-wrap:balance} 53 .sub{color:var(--muted);font-size:14px;line-height:1.5;margin-bottom:22px} 54 .sso-btn{display:flex;align-items:center;width:100%;margin-bottom:10px;border:1px solid var(--border-strong);border-radius:999px;background:var(--field);color:var(--text);font-size:14px;font-weight:500;font-family:inherit;padding:6px 14px;min-height:42px;cursor:pointer;transition:background .2s,border-color .2s,transform .2s} 55 .sso-btn:hover{background:var(--hover);border-color:var(--accent);transform:translateY(-1px)} 56 .sso-btn .ic{display:flex;align-items:center;justify-content:center;width:24px;height:24px;flex:none} 57 .sso-btn .lbl{flex:1;text-align:center} 58 .hr{display:flex;align-items:center;gap:12px;margin:18px 0;color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.08em} 59 .hr::before,.hr::after{content:"";flex:1;height:1px;background:var(--border)} 60 input[type=text],input[type=email],input[type=password]{width:100%;height:42px;padding:0 14px;margin-bottom:10px;border:1px solid var(--border-strong);border-radius:10px;background:var(--field);color:var(--text);font-size:14px;font-family:inherit;transition:border-color .2s,box-shadow .2s} 61 input::placeholder{color:var(--muted)} 62 input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 18%,transparent)} 63 .terms{display:flex;align-items:flex-start;gap:8px;margin:4px 0 14px;font-size:12px;color:var(--muted);text-align:left;cursor:pointer;line-height:1.45} 64 .terms input{margin-top:2px;flex:none;cursor:pointer;accent-color:var(--accent);width:15px;height:15px} 65 a{color:var(--accent);text-decoration:none} 66 a:hover{text-decoration:underline} 67 .submit{width:100%;border:0;border-radius:999px;background:var(--accent);color:#fff;font-size:15px;font-weight:600;font-family:inherit;padding:10px 14px;min-height:44px;
67cursor:pointer;box-shadow:0 8px 24px color-mix(in srgb,var(--accent) 35%,transparent);transition:background .2s,transform .2s} 68 .submit:hover{background:var(--accent-hover);transform:translateY(-1px)} 69 .submit[disabled]{opacity:.5;cursor:not-allowed;transform:none} 70 .error{display:none;margin-top:14px;padding:10px 12px;border-radius:10px;background:var(--err-bg);color:var(--err);font-size:13px;text-align:left} 71 #challenge{margin-top:12px;display:flex;justify-content:center} 72 .signin{font-size:14px;color:var(--body);margin-top:20px} 73 </style> 74 75</head> 76<body> 77 78 <div class="glow" aria-hidden="true"><i></i><i></i><i></i></div> 79 <div class="card"> 80 <div class="logo"> 81 <img class="ink" src="https://abacus.ai/static/imgs/logo_text80Dark.webp" alt="Abacus.AI" height="24"> 82 <img class="white" src="https://abacus.ai/static/imgs/logo_text80.webp" alt="Abacus.AI" height="24"> 83 </div> 84 <h1>Create your account</h1> 85 <p class="sub">Every top AI model and the agent, in one subscription.</p> 86 87 <button type="button" class="sso-btn" id="googleSignInButton"> 88 <span class="ic"><img alt="" src="https://abacus.ai/static/imgs/logo_google.webp" width="18"></span> 89 <span class="lbl">Sign up with Google</span> 90 </button> 91 <button type="button" class="sso-btn" id="apple-btn"> 92 <span class="ic"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M16.4 13.2c0-2.5 2-3.7 2.1-3.8-1.1-1.7-2.9-1.9-3.5-1.9-1.5-.2-2.9.9-3.7.9-.8 0-1.9-.9-3.2-.8-1.6 0-3.1 1-4 2.4-1.7 3-0.4 7.4 1.2 9.8.8 1.2
921.8 2.5 3.1 2.4 1.2-.1 1.7-.8 3.2-.8s1.9.8 3.2.8c1.3 0 2.2-1.2 3-2.4.9-1.4 1.3-2.7 1.3-2.8-.1 0-2.6-1-2.7-3.8ZM14 5.9c.7-.8 1.1-1.9 1-3-1 0-2.1.7-2.8 1.5-.6.7-1.2 1.9-1 3 1.1.1 2.2-.6 2.8-1.5Z"/></svg></span> 93 <span class="lbl">Sign up with Apple</span> 94 </button> 95 <button type="button" class="sso-btn" id="ms-btn"> 96 <span class="ic"><svg width="18" height="18" viewBox="0 0 23 23" aria-hidden="true"><rect width="10" height="10" x="1" y="1" fill="#f35325"/><rect width="10" height="10" x="12" y="1" fill="#81bc06"/><rect width="10" height="10" x="1" y="12" fill="#05a6f0"/><rect width="10" height="10" x="12" y="12" fill="#ffba08"/></svg></span> 97 <span class="lbl">Sign up with Microsoft</span> 98 </button> 99 <div class="hr">or</div> 100 <form id="signup-form" novalidate> 101 <input id="name" name="name" type="text" placeholder="Name" autocomplete="name" required> 102 <input id="email" name="email" type="email" placeholder="Email" autocomplete="email" required> 103 <input id="password" name="password" type="password" placeholder="Password" autocomplete="new-password" minlength="8" required> 104 <label class="terms"> 105 <input type="checkbox" id="terms-cb" checked> 106 <span>I agree to the <a href="https://abacus.ai/terms" target="_blank" rel="noopener">Terms of Service</a> and <a href="https://abacus.ai/privacy" target="_blank" rel="noopener">Privacy Policy</a></span> 107 </label> 108 <div id="challenge"></div> 109 <button type="submit" class="submit" id="submit-btn">Sign Up</button> 110 </form> 111 <div class="error" id="error-box" role="alert"></div><div class="signin">Already have an account? <a href="https://apps.abacus.ai/chatllm/signin">Sign in</a></div> 112 </div> 113
113<script> 114 'use strict'; 115 var CFG = { 116 home: "https://apps.abacus.ai/chatllm", 117 orgHost: "apps", 118 signupToken: "", 119 googleId: "528577992200-o78lkkg5l8jbass2s4nmo88ictavvs55.apps.googleusercontent.com", 120 azureId: "b89bbf6f-22a7-4b66-9bcf-6a80edf04dc5", 121 appleId: 'com.AbacusAI.Abacus-AI.sid', 122 captchaKey: "6LfkaWcsAAAAAEukrt6qU6C4HGLx3L2EX-Yxfol3", 123 signupSrc: "hp_ns2_header", 124 postQs: "\u0026src=hp_ns2_header" 125 }; 126 var SOURCE = "signup_ns2"; 127 // ns2 skin: the theme this page showed rides to the app, so the card page (billing_add) keeps it. 128 function ns2ThemeQs() { 129 if (SOURCE !== 'signup_ns2') { return ''; } 130 var chosen = document.documentElement.getAttribute('data-ns2-theme'); 131 var dark = chosen ? chosen === 'dark' : (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches); 132 return '&ns2_theme=' + (dark ? 'dark' : 'light'); 133 } 134 var errorBox = document.getElementById('error-box'); 135 var submitBtn = document.getElementById('submit-btn'); 136 var termsCb = document.getElementById('terms-cb'); 137 var challengeWidgetId = null; 138 var challengeSiteKey = null; 139 140 function showError(msg) { 141 errorBox.textContent = msg || 'Something went wrong. Please try again.'; 142 errorBox.style.display = 'block'; 143 } 144 function apiHeaders() { 145 var h = { 'Content-Type': 'application/json' }; 146 if (CFG.orgHost) { h['X-Abacus-Org-Host'] = CFG.orgHost; } 147 return h; 148 } 149 function api(method, data) { 150 return fetch('/api/v1/' + method, { 151 method: 'POST', credentials: 'same-origin', headers: apiHeaders(), body: JSON.stringify(data) 152 }).then(function (r) { return r.json(); }); 153 } 154 // GA4 sign_up event, mirroring chatweb's logSignUpGaEvent (only for freshly created accounts). 155 function logSignUp(result, method) { 156 try { 157 var createdAt = result && result.createdAt; 158 if (!createdAt || typeof gtag !== 'function') { return; } 159 var normalized = /[zZ]$|[+-]\d{2}:?\d{2}$/.test(createdAt) ? createdAt : createdAt + 'Z'; 160 var createdMs = Date.parse(normalized); 161 if (!isNaN(createdMs) && Date.now() - createdMs <= 5 * 60 * 1000) { 162 gtag('event', 'sign_up', { method: method, transport_type: 'beacon' }); 163 } 164 } catch (e) { /* analytics only */ } 165 } 166 function handleAuthResponse(res, method) { 167 errorBox.style.display = 'none'; 168 if (res && res.success) { 169 logSignUp(res.result, method); 170 // isSignUp=1 mirrors the control flow's post-signup load (loggedout.py redirects control to 171 // /signin?isSignUp=1, and chatweb carries it through the whole onboarding chain): index.html 172 // then runs the light prefetch instead of the full one (the org-less full-prefetch calls just 173 // fail) and page-new paints the dark sign-in gradient during load gaps instead of a white flash. 174 setTimeout(function () { window.location.href = CFG.home + '/?isSignUp=1' + CFG.postQs + ns2ThemeQs(); }, 200); 175 return; 176 } 177 submitBtn.disabled = false; 178 if (res && res.captchaChallengeRequired) { return showChallenge(res.error); } 179 if (res && res.redirectUrl) { window.location.href = res.redirectUrl; return; } 180 showError(res && res.error); 181 } 182 183 // Visible checkbox captcha fallback when the backend flags the attempt as suspicious. 184 function showChallenge(msg) { 185 showError(msg || 'Please verify you are human to continue.'); 186 var g = window.grecaptcha && window.grecaptcha.enterprise; 187 if (challengeWidgetId !== null) { g && g.reset(challengeWidgetId); return; } 188 fetch('/api/v1/_getCaptchaConfig?userAction=signup', { credentials: 'same-origin', headers: CFG.orgHost ? { 'X-Abacus-Org-Host': CFG.orgHost } : {} }) 189 .then(function (r) { return r.json(); }) 190 .then(function (res) { 191 challengeSiteKey = res && res.result && res.result.challengeSiteKey; 192 if (challengeSiteKey && g && g.render) { 193 challengeWidgetId = g.render(document.getElementById('challenge'), { sitekey: challengeSiteKey, theme: 'dark' }); 194 } 195 }); 196 } 197 198 // Email/password signup 199 document.getElementById('signup-form').addEventListener('submit', function (e) { 200 e.preventDefault(); 201 var name = document.getElementById('name').value.trim(); 202 var email = document.getElementById('email').value.trim(); 203 var password = document.getElementById('password').value; 204 if (!termsCb.checked) { return showError('Please agree to the Terms of Service and Privacy Policy to continue.'); } 205 if (!name || !email) { return showError('Please enter your name and email.'); } 206 if (password.length < 8 || !/\d/.test(password) || !/[a-z]/.test(password) || !/[A-Z]/.test(password) || !/[!@#$%^&*()_+\-=\[\]{}|']/.test(password)) { 207 return showError('Password must be at least 8 characters and contain an uppercase letter, a lowercase letter, a number and a special character.'); 208 } 209 submitBtn.disabled = true; 210 var submit = function (recaptchaToken, recaptchaChallengeToken) { 211 api('_createAccount', { 212 name: name, email: email, password: password, 213 recaptchaToken: recaptchaToken || null, recaptchaChallengeToken: recaptchaChallengeToken || null, 214 signupToken: CFG.signupToken || null, signupSource: SOURCE, signupSrc: CFG.signupSrc 215 }).then(function (res) { handleAuthResponse(res, 'password'); }) 216 .catch(function () { submitBtn.disabled = false; showError(); }); 217 }; 218 var g = window.grecaptcha && window.grecaptcha.enterprise; 219 if (challengeWidgetId !== null && g) { 220 var challengeToken = g.getResponse(challengeWidgetId); 221 if (!challengeToken) { submitBtn.disabled = false; return showError('Please complete the captcha challenge to continue.'); } 222 return submit(null, challengeToken); 223 } 224 if (CFG.captchaKey && g) { 225 g.ready(function () { 226 g.execute(CFG.captchaKey, { action: 'signup' }).then(submit, function () { submit(null); }); 227 }); 228 } else { 229 submit(null); 230 } 231 }); 232 233 // Google â same flow as the control page (SocialSignInPanel): a styled button wired 234 // through gapi.auth2.attachClickHandler, plus GSI One Tap. The backend accepts the 235 // gapi id_token via _googleSignIn exactly like the GSI credential. 236 function onGoogleAuth(authResult) { 237 var token = (authResult && authResult.credential) || 238 (authResult && authResult.getAuthResponse && authResult.getAuthResponse() && authResult.getAuthResponse().id_token); 239 if (!token) { return showError(); } 240 api('_googleSignIn', { googleToken: token, signupToken: CFG.signupToken || null, signupSource: SOURCE, signupSrc: CFG.signupSrc }) 241 .then(function (res) { handleAuthResponse(res, 'google'); }) 242 .catch(function () { showError(); }); 243 } 244 window.__gsiLoaded = function () { 245 if (!CFG.googleId || !window.google) { return; } 246 google.accounts.id.initialize({ client_id: CFG.googleId, callback: onGoogleAuth, use_fedcm_for_prompt: true, auto_select: false }); 247 google.accounts.id.prompt(); 248 }; 249 window.__gapiLoaded = function () { 250 if (!CFG.googleId || !window.gapi) { return; } 251 gapi.load('auth2', function () { 252 document.getElementById('googleSignInButton').addEventListener('click', function () { 253 gapi.auth2.authorize({ client_id: CFG.googleId, scope: 'openid email profile', response_type: 'permission id_token', include_granted_scopes: false, prompt: 'select_account' }, function (res) { 254 if (res && res.error) { if (res.error !== 'popup_closed_by_user' && res.error !== 'access_de
254nied') { showError(); } return; } 255 onGoogleAuth({ credential: res && res.id_token }); 256 }); 257 }); 258 }); 259 }; 260 261 // Apple (popup via appleid.auth.js) 262 document.getElementById('apple-btn').addEventListener('click', function () { 263 var appleAuth = window.AppleID && window.AppleID.auth; 264 if (!appleAuth) { return showError(); } 265 appleAuth.signIn().then(function (res) { 266 var idToken = res && res.authorization && res.authorization.id_token; 267 if (!idToken) { return showError(); } 268 api('_appleSignIn', { appleToken: btoa(idToken), signupToken: CFG.signupToken || null, signupSource: SOURCE, signupSrc: CFG.signupSrc }) 269 .then(function (r) { handleAuthResponse(r, 'apple'); }) 270 .catch(function () { showError(); }); 271 }, function (err) { 272 if (err && (err.error === 'popup_closed_by_user' || err.error === 'user_cancelled_authorize')) { return; } 273 showError(); 274 }); 275 }); 276 window.__appleLoaded = function () { 277 if (window.AppleID && window.AppleID.auth) { 278 window.AppleID.auth.init({ clientId: CFG.appleId, scope: 'email name', redirectURI: 'https://' + window.location.host, state: 'abc', nonce: 'NONCE', usePopup: true }); 279 } 280 }; 281 282 // Microsoft (OAuth popup; https://abacus.ai/oauth/callback delivers the code back here) 283 var msState = null; 284 window.__oauthCallbackPost = function (qs) { 285 if (qs && qs.charAt(0) === '?') { qs = qs.substring(1); } 286 var params = {}; 287 (qs || '').split('&').forEach(function (p) { 288 var i = p.indexOf('='); 289 if (i > -1) { params[p.substring(0, i)] = decodeURIComponent(p.substring(i + 1).replace(/\+/g, ' ')); } 290 }); 291 if (params.error) { return showError(params.error_description || params.error); } 292 if (!params.code || params.state !== msState) { return; } 293 api('_azureSignIn', { azureToken: params.code, signupToken: CFG.signupToken || null, signupSource: SOURCE, signupSrc: CFG.signupSrc }) 294 .then(function (res) { handleAuthResponse(res, 'azure'); }) 295 .catch(function () { showError(); }); 296 }; 297 window.addEventListener('message', function (e) { 298 if (e.data && typeof e.data.query === 'string') { window.__oauthCallbackPost(e.data.query); } 299 }); 300 document.getElementById('ms-btn').addEventListener('click', function () { 301 msState = ('' + Date.now() + Math.random().toString(36).slice(2)) + '__' + window.location.origin + '__chatweb'; 302 var url = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=' + encodeURIComponent(CFG.azureId) + 303 '&redirect_uri=' + encodeURIComponent('https://abacus.ai/oauth/callback') + 304 '&scope=User.ReadBasic.All%20offline_access%20openid%20profile&state=' + encodeURIComponent(msState) + '&response_type=code'; 305 var w = 600, h = 600; 306 var left = (window.screenX || 0) + Math.max(0, (window.innerWidth - w) / 2); 307 var top = (window.screenY || 0) + Math.max(0, (window.innerHeight - h) / 2); 308 var popup = window.open(url, '_blank', 'toolbar=0,location=0,menubar=0,height=' + h + ',width=' + w + ',top=' + top + ',left=' + left); 309 if (popup && popup.focus) { popup.focus(); } 310 }); 311 </script>
311 312
312<script src="https://accounts.google.com/gsi/client" async defer onload="__gsiLoaded()"></script>
312 313
313<script src="https://apis.google.com/js/api.js" async defer onload="__gapiLoaded()"></script>
313 314
314<script src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js" async defer onload="__appleLoaded()"></script>
vendor: 71 bytes, lines 314-316
314 315 316 <script src="https://www.google.com/recaptcha/enterprise.js?render=
3166LfkaWcsAAAAAEukrt6qU6C4HGLx3L2EX-Yxfol3
vendor: 25 bytes, lines 316-317
316" async defer></script> 317
318</body> 319</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.