PageSourceSearch

https://www.liveable.co.uk/_next/static/chunks/8709-c7a32f7b6ad19df9.js

js liveable.co.uk collected 2026-10-01 15:10:47 UTC 17,628 bytes, 2 lines download raw bytes

1!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="01a0f7ef-7ead-7140-890b-1da188f97384")}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8709],{8709:(e,t,r)=>{r.d(t,{O:()=>E,A:()=>S});var a=r(95155),n=r(89908),i=r(86822),s=r(12115),o=r(12553),c=r(28516),l=r(91520),u=r(82135),d=r(60080);let f="free",h={free:{rank:0,canAccessMap:!1,canAccessCrime:!1,canAccessHomes:!1,canAccessPeople:!1,canAccessSchools:!1,canAccessNoise:!1,canAccessFlood:!1,canAccessTransport:!1,canAccessLiveability:!0},pro:{rank:10,canAccessMap:!0,canAccessCrime:!0,canAccessHomes:!0,canAccessPeople:!0,canAccessSchools:!0,canAccessNoise:!0,canAccessFlood:!0,canAccessTransport:!0,canAccessLiveability:!0}};function p(e){return h[e||f]||h[f]}function m(e){return e?e instanceof Date?e:"function"==typeof e.toDate?e.toDate():"number"==typeof e.seconds?new Date(1e3*e.seconds):null:null}function g(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Date;if(!e)return f;let r=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Date;return!function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Date;if("pro"!==e.subscriptionTier)return!1;let r=e.subscriptionStatus;if(r&&!["active","trialing"].includes(r))return!1;if(e.currentPeriodEnd&&e.cancelAtPeriodEnd){let r=m(e.currentPeriodEnd);if(r&&t>r)return!1}return!0}(e,t)?f:"pro"}(e,t),a=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Date;if(!function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Date;if("active"!==e.oneTimeAccessStatus)return!1;let r=m(e.oneTimeAccessExpiresAt);return!!r&&r>t}(e,t))return f;let r=e.oneTimeAccessPlanKey||"pro";return h[r]?r:f}(e,t),n=p(r);return p(a).rank>n.rank?a:r}function y(e){let t={canAccessLiveability:!0,tier:e,planKey:"pro"===e?"pro":"free"};switch(e){case"free":default:return{...t,canAccessMap:!1,canAccessCrime:!1,canAccessHomes:!1,canAccessPeople:!1,canAccessSchools:!1,canAccessNoise:!1,canAccessFlood:!1,canAccessTransport:!1};case"pro":return{...t,canAccessMap:!0,canAccessCrime:!0,canAccessHomes:!0,canAccessPeople:!0,canAccessSchools:!0,canAccessNoise:!0,canAccessFlood:!0,canAccessTransport:!0}}}function w(e){let t=p(e),r=t.rank>0?"pro":"free";return{...t,tier:r,planKey:t.rank>0?e:"free"}}async function v(e){if(!e)return{access:y("free"),userData:null};try{let t=await (0,u.gL)(e.uid);if(!t)return{access:y("free"),userData:null};return{access:w(g(t)),userData:t}}catch(e){return console.error("Error getting user access:",e),{access:y("free"),userData:null}}}let A=(0,s.createContext)(void 0),b=e=>{try{e()}catch(e){console.error("Error tracking authentication:",e)}};function S(){let e=(0,s.useContext)(A);if(void 0===e)throw Error("useAuth must be used within an AuthProvider");return e}function E(e){let{children:t}=e,[f,h]=(0,s.useState)(null),[p,m]=(0,s.useState)(!0),[S,E]=(0,s.useState)(!1),[I,k]=(0,s.useState)(null),[P,_]=(0,s.useState)(null),[D,N]=(0,s.useState)(!1),[T,C]=(0,s.useState)(y("free")),[j,x]=(0,s.useState)(null),[O,B]=(0,s.use
1State)(!1),[F,U]=(0,s.useState)(!1),V=(0,s.useRef)(0),[H,J]=(0,s.useState)(null),R=(0,s.useRef)(null),L=!!f&&P===f.uid,W=(e,t)=>{var r;return V.current===t&&(null==(r=c.j.currentUser)?void 0:r.uid)===e.uid};(0,s.useEffect)(()=>{let e=(0,o.hg)(c.j,async e=>{var t,r;let a=++V.current;if((null==(t=R.current)?void 0:t.uid)!==(null==e?void 0:e.uid)&&(R.current=null,J(null)),_(null),N(!1),h(e),e){E(!1),k(null);let t=setTimeout(()=>{W(e,a)&&(k("Your account is taking longer than expected to load."),m(!1))},15e3);null==(r=t.unref)||r.call(t);try{if(await e.getIdToken(),!e.emailVerified&&(await e.reload(),!W(e,a)))return;let t=await M(e,a);if(!W(e,a))return;if(t){let{userData:r,hasStripeCustomer:a}=t;C(r?w(g(r)):y("free")),U(a),B(!e.emailVerified&&!a),r&&e.emailVerified&&!r.emailVerified&&Y(e.uid),k(null),E(!0)}else k("We could not load your account.")}catch(t){if(!W(e,a))return;console.error("Error setting up auth:",t),E(!1),k("We could not load your account.")}finally{clearTimeout(t)}}else E(!0),k(null),C(y("free")),B(!1),U(!1);V.current===a&&m(!1)});return()=>{++V.current,R.current=null,e()}},[]);let q=async(e,t)=>{for(let r=0;r<2;r++){try{let a=await e.getIdToken(!0);if(!W(e,t))return null;let n=await fetch("/api/stripe/create-customer",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer ".concat(a)},body:JSON.stringify({userId:e.uid,email:e.email,displayName:e.displayName})});if(n.ok)return!0;console.error("Failed to create Stripe customer (attempt ".concat(r+1,", status ").concat(n.status,")"))}catch(e){console.error("Error creating Stripe customer (attempt ".concat(r+1,"):"),e)}if(!W(e,t))return null}return!1},M=async(e,t)=>{try{let{doc:a,getDoc:n}=await Promise.resolve().then(r.bind(r,19708)),{db:i}=await Promise.resolve().then(r.bind(r,28516)),s=a(i,"users",e.uid),o=await n(s);if(!W(e,t))return null;let c=!1;if(!o.exists()&&e.email){let r=e.providerData.some(e=>"google.com"===e.providerId)?"google":"email";if(N(!1),"google"===r){if(await (0,u.Jt)(e.uid,e.email,r,e.displayName||void 0),!W(e,t))return null;b(()=>(0,d.gm)(e.uid,e.email,e.displayName,"google",{is_new_user:!0})),b(()=>(0,d.g6)("sign_up","google",!0)),_(e.emailVerified?e.uid:null)}if("google"===r){let r=await q(e,t);if(null===r)return null;c=r}return{userData:null,hasStripeCustomer:c}}if(o.exists()){let r=o.data();c=!!(null==r?void 0:r.stripeCustomerId),N(!!(null==r?void 0:r.profile)&&!!r.profile.userType),_(e.emailVerified||(null==r?void 0:r.stripeCustomerId)?e.uid:null);let a=e.providerData.some(e=>"google.com"===e.providerId)?"google":"email";b(()=>(0,d.gm)(e.uid,e.email,e.displayName,a));let n=e.providerData.some(e=>"google.com"===e.providerId);if(!(null==r?void 0:r.stripeCustomerId)&&e.email&&(e.emailVerified||n)){let r=await q(e,t);if(null===r)return null;c=r}return{userData:r,hasStripeCustomer:c}}return{userData:null,hasStripeCustomer:!1}}catch(r){if(!W(e,t))return null;return console.error("Error ensuring user document:",r),N(!1),_(null),null}},Y=async e=>{try{let{doc:t,updateDoc:a}=await Promise.resolve().then(r.bind(r,19708)),{db:n}=await Promise.resolve().then(r.bind(r,28516));await a(t(n,"users",e),{emailVerified:!0,emailVerifiedAt:new Date().toISOString()})}catch(e){console.error("Failed to sync emailVerified to Firestore:",e)}},z=async e=>{var t;if((null==(t=c.j.currentUser)?void 0:t.uid)!==e.uid)throw Error("Please sign in again");let r=R.current;if((null==r?void 0:r.uid)===e.uid&&("sending"===r.status||r.resendAvailableAt>Date.now()))throw Error("Please wait before requesting another verification email.");let a={uid:e.uid,status:"sending",resendAvailableAt:0};R.current=a,J(a);let n=()=>{var t;return R.current===a&&(null==(t=c.j.currentUser)?void 0:t.uid)===e.uid};try{await (0,l.kH)(e)}catch(t){if(n()){let r={uid:e.uid,status:"failed",message:(0,l.ch)(t),resendAvailableAt:Date.now()+6e4};R.current=r,J(r)}throw t}if(!n())throw Error("Your sign-in changed. Please sign in again.");let i={uid:e.uid,status:"sent",resendAvailableAt:Date.now()+6e4};R.current=i,J(i)},K=async(e,t,r)=>{try{x(null);let n=await (0,l.bk)(e,t,r);if(n.user.email){await (0,u.Jt)(n.user.uid,n.user.email,"email",r),b(()=>(0,d.gm)(n.user.uid,n.user.email,r||null,"email",{is_new_user:!0})),b(()=>(0,d.g6)("sign_up","email",!0));try{await z(n.user)}catch(e){var a;if((null==(a=c.j.currentUser)?void 0:a.uid)!==n.user.uid)throw e}}return n.user.uid}catch(t){let e=(0,l.ch)(t);throw x(e),Error(e)}},G=async(e,t)=>{try{x(null);let r=await (0,l.Ru)(e,t);return r.user&&b(()=>(0,d.gm)(r.user.uid,r.user.email,r.user.displayName,"email")),b(()=>(0,d.g6)("login","email",!1)),r.user.uid}catch(t){let e=(0,l.ch)(t);throw x(e),Error(e)}},X=async()=>{try{x(null);let e=await (0,l.G6)();return e.user&&b(()=>(0,d.gm)(e.user.uid,e.user.email,e.user.displayName,"google")),b(()=>(0,d.g6)("login","google",!1)),e.user.uid}catch(t){let e=(0,l.ch)(t);throw x(e),Error(e)}},$=async()=>{try{x(null),await (0,l.je)(),(0,n.aY)(),(0,i.Xh)(),h(null),b(()=>(0,d.ub)())}catch(t){let e=(0,l.ch)(t);throw x(e),Error(e)}},Q=async e=>{try{x(null),await (0,l.xw)(e)}catch(t){let e=(0,l.ch)(t);throw x(e),Error(e)}},Z=async e=>{let t=V.current;if(!f||!L||!W(f,t))throw Error("Please sign in again");if(!e.userType)throw Error("Please answer the profile questions");
1if(await (0,u.Lt)(f.uid,e),!W(f,t))throw Error("Your sign-in changed. Please sign in again");N(!0)},ee=async()=>{if(f)try{let{doc:e,getDoc:t}=await Promise.resolve().then(r.bind(r,19708)),{db:a}=await Promise.resolve().then(r.bind(r,28516)),n=e(a,"users",f.uid),i=await t(n);if(i.exists()){let e=i.data();N(!!(null==e?void 0:e.profile)&&!!e.profile.userType)}else N(!1)}catch(e){console.error("Error refreshing onboarding status:",e),N(!1)}},et=async()=>{if(f)try{let{access:e}=await v(f);C(e)}catch(e){console.error("Error refreshing user access:",e)}},er=async()=>{if(!f)throw Error("No user logged in");await z(f)},ea={user:f,loading:p,authReady:S,authError:I,onboardingReady:L,hasCompletedOnboarding:D,userAccess:T,error:j,requiresEmailVerification:O,hasStripeCustomer:F,verificationEmailState:(null==H?void 0:H.uid)===(null==f?void 0:f.uid)?H:null,signUp:K,signIn:G,signInGoogle:X,logout:$,resetUserPassword:Q,clearError:()=>x(null),refreshOnboardingStatus:ee,saveOnboardingProfile:Z,refreshUserAccess:et,resendVerificationEmail:er};return(0,a.jsx)(A.Provider,{value:ea,children:t})}},28516:(e,t,r)=>{r.d(t,{db:()=>l,j:()=>c});var a=r(52078),n=r(12553),i=r(19708);let s={apiKey:"AIzaSyBHC8HUAvSAl0KZMY_hb2PftgyeqWUO-hA",authDomain:"account.liveable.co.uk",projectId:"liveable-82268",storageBucket:"liveable-82268.firebasestorage.app",messagingSenderId:"546713610349",appId:r(95704).env.NEXT_PUBLIC_FIREBASE_APP_ID},o=0===(0,a.Dk)().length?(0,a.Wp)(s):(0,a.Sx)(),c=(0,n.xI)(o),l=(0,i.aU)(o)},82135:(e,t,r)=>{r.d(t,{CD:()=>h,E$:()=>l,HI:()=>d,Jt:()=>i,Lt:()=>o,N3:()=>g,Qu:()=>m,Si:()=>p,_q:()=>f,gL:()=>u,r7:()=>c,uf:()=>s});var a=r(19708),n=r(28516);let i=async(e,t,r,i)=>{let s=(0,a.doc)(n.db,"users",e),o={email:t,authProvider:r,accountStatus:"active",emailVerified:"google"===r,subscriptionTier:"free",createdAt:(0,a.O5)(),lastLoginAt:(0,a.O5)(),lastActiveAt:(0,a.O5)(),mapTrialStartedAt:(0,a.O5)()};i&&(o.displayName=i),await (0,a.BN)(s,o,{merge:!0})},s=async e=>{let t=(0,a.doc)(n.db,"users",e);await (0,a.BN)(t,{lastActiveAt:(0,a.O5)()},{merge:!0})},o=async(e,t)=>{let r=(0,a.doc)(n.db,"users",e);await (0,a.BN)(r,{profile:{...t,updatedAt:(0,a.O5)()},onboarding:{completedAt:(0,a.O5)()}},{merge:!0})},c=async(e,t)=>{let r=(0,a.doc)(n.db,"users",e);await (0,a.BN)(r,{profile:{...t,updatedAt:(0,a.O5)()}},{merge:!0})},l=async e=>{let t=(0,a.doc)(n.db,"users",e),r=await (0,a.getDoc)(t);return r.exists()&&r.data().profile||null},u=async e=>{let t=(0,a.doc)(n.db,"users",e),r=await (0,a.getDoc)(t);return r.exists()?r.data():null},d=async(e,t,r,i)=>{let s=(0,a.doc)(n.db,"users",e,"favourites",t);await (0,a.BN)(s,{placeId:t,placeName:r,placeType:i,addedAt:(0,a.O5)()})},f=async(e,t)=>{let r=(0,a.doc)(n.db,"users",e,"favourites",t);await (0,a.kd)(r)},h=async(e,t)=>{let r=(0,a.doc)(n.db,"users",e,"favourites",t);return(await (0,a.getDoc)(r)).exists()},p=async e=>{let t=(0,a.rJ)(n.db,"users",e,"favourites"),r=(0,a.P)(t,(0,a.My)("addedAt","desc"));return(await (0,a.GG)(r)).docs.map(e=>{let t=e.data();return{id:e.id,placeId:t.placeId,placeName:t.placeName,placeType:t.placeType,addedAt:t.addedAt}})},m=async e=>{let t=(0,a.doc)(n.db,"users",e),r=await (0,a.getDoc)(t);return r.exists()&&r.data().checklistProgress||null},g=async(e,t,r)=>{let i=(0,a.doc)(n.db,"users",e);await (0,a.BN)(i,{checklistProgress:{completedTaskIds:t,completedSubtaskIds:r,updatedAt:(0,a.O5)()}},{merge:!0})}},86822:(e,t,r)=>{r.d(t,{H2:()=>o,WI:()=>m,Xh:()=>l,mB:()=>p,mc:()=>s,nW:()=>f,zr:()=>h});let a="liveable_pending_checkout",n=["liveable_pending_plan","liveable_pending_price_id","liveable_pending_purchase_type","liveable_pending_pricing_variant"],i=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function s(e){return e&&i.test(e)?e:null}function o(){return crypto.randomUUID()}function c(){let e=[];try{e.push(localStorage)}catch(e){}try{e.push(sessionStorage)}catch(e){}return e}function l(){for(let e of c())for(let t of[a,...n])try{e.removeItem(t)}catch(e){}}function u(e){for(let t of(l(),c()))try{return t.setItem(a,JSON.stringify(e)),!0}catch(e){}return!1}function d(){for(let e of c()){let t;try{t=e.getItem(a)}catch(e){continue}if(t){try{let e=JSON.parse(t),r=Date.now()-(null==e?void 0:e.createdAt);if("string"==typeof(null==e?void 0:e.planId)&&e.planId&&"string"==typeof e.priceId&&e.priceId&&["subscription","one_time_access"].includes(e.purchaseType)&&s(e.checkoutAttemptId)&&"number"==typeof e.createdAt&&Number.isFinite(r)&&r>=0&&r<=36e5&&(void 0===e.uid||"string"==typeof e.uid&&e.uid.length>0)&&(void 0===e.promoCode||"string"==typeof e.promoCode))return e}catch(e){}l();break}}return null}function f(e,t){try{let r={...e,uid:t,checkoutAttemptId:o(),createdAt:Date.now()};return u(r)?r:null}catch(e){return l(),null}}function h(e,t){let r=d();return(!r||!t||r.checkoutAttemptId===t)&&(r&&t&&(!r.uid||r.uid===e)?u({...r,uid:e}):(l(),!1))}function p(e){let t=d();return t&&t.uid===e?t:null}function m(e){let t=p(e);if(t)return l(),t;try{let t=sessionStorage.getItem(n[0]),r=sessionStorage.getItem(n[1]),a=sessionStorage.getItem(n[2])||"subscription";if(t&&r&&["subscription","one_time_access"].includes(a))return l(),{planId:t,priceId:r,purchaseType:a,uid:e,createdAt:Date.now(),checkoutAttemptId:o()}}catch(e){}return d()||l(),null}},89908:(e,t,r)=>{r.d(t,{$4:()=>u,P6:()=>c,X9:()=>d,aY:()=>i,ej:()=>l,sc:()=>s});let a="liveable_map_auth_return";function n(){let e=[];try{e.push(localStorage)}catch(e){}try{e.push(sessionStorage)}catch(e){}return e}function i(){for(let e of n())try{e.removeItem(a)}catch(e){}}function s(e){if("string"!=typeof e||!e.startsWith("/")||e.startsWith("//")||/[\\\r\n]/.test(e))return null;try{let t=new URL(e,"https://www.liveable.co.uk");if("https://www.liveable.co.uk"!==t.origin||!["/map","/map/"].includes(t.pathname))return null;return"".concat(t.pathname).concat(t.search).concat(t.hash)}catch(e){return null}}function o(){for(let e of n()){let t;try{t=e.getItem(a)}catch(e){continue}if(t){try{let e=JSON.parse(t),r=s(null==e?void 0:e.url),a=Date.now()-(null==e?void 0:e.createdAt);if(r&&"number"==typeof e.createdAt&&Number.isFinite(a)&&a>=0&&a<=36e5&&"string"==typeof e.uid&&e.uid.length>0)return{url:r,createdAt:e.createdAt,uid:e.uid}}catch(e){}i();break}}return null}function c(e,t){i();let r=s(e);r&&t&&function(e){for(let t of(i(),n()))try{return t.setItem(a,JSON.stringify(e)),!0}catch(e){}}({url:r,uid:t,createdAt:Date.now()})}function l(e,t){let r=s(t);return r?"".concat(e,"?mapReturn=").concat(encodeURIComponent(r)):e}function u(){return null!==o()}function d(e){let t=o();return t?(i(),t.uid===e?t.url:null):null}},91520:(e,t,r)=>{r.d(t,{DN:()=>g,E7:()=>m,G6:()=>l,Ru:()=>o,_b:()=>p,bk:()=>s,ch:()=>i,i1:()=>h,je:()=>u,kH:()=>f,xw:()=>d});var a=r(12553),n=r(28516);let i=e=>{if(!(null==e?void 0:e.code))return e.message||"An error occurred";switch(e.code){case"auth/invalid-email":return"Please enter a valid email address";case"auth/user-disabled":return"This account has been disabled";case"auth/user-not-found":return"No account found with this email address";case"auth/wrong-password":return"Incorrect password";case"auth/invalid-credential":return"Invalid email or password";case"auth/email-already-in-use":return"An account with this email already exists";case"auth/weak-password":return"Password should be at least 6 characters";case"auth/too-many-requests":return"Too many failed attempts. Please try again later";case"auth/network-request-failed":return"Network error. Please check your connection";case"auth/popup-closed-by-user":return"Sign in cancelled";
1case"auth/invalid-action-code":return"This link is invalid or has already been used";case"auth/expired-action-code":return"This link has expired. Request a new one";default:return"Something went wrong. Please try again"}},s=async(e,t,r)=>{let i=await (0,a.eJ)(n.j,e,t);return r&&i.user&&await (0,a.r7)(i.user,{displayName:r}),i},o=async(e,t)=>(0,a.x9)(n.j,e,t),c=new a.HF;c.setCustomParameters({prompt:"select_account"});let l=async()=>{try{return await (0,a.df)(n.j,c)}catch(e){if("auth/popup-closed-by-user"===e.code)throw Error("Sign in cancelled");throw e}},u=async()=>(0,a.CI)(n.j),d=async e=>(0,a.J1)(n.j,e),f=async e=>{try{await (0,a.gA)(e,{url:"https://www.liveable.co.uk/verified",handleCodeInApp:!1})}catch(e){if("auth/unauthorized-continue-uri"===e.code)throw console.error("Domain not whitelisted. Add domain to Firebase Console > Authentication > Settings > Authorized domains"),Error("Email verification configuration error. Please contact support.");if("auth/too-many-requests"===e.code)throw Error("Verification emails are temporarily limited. Please wait and try again later.");if("auth/network-request-failed"===e.code)throw Error("We couldn’t confirm that the verification email was sent. Check your connection and inbox before trying again.");throw Error("We couldn’t send the verification email. Please try again later or contact support.")}},h=e=>(0,a.sv)(n.j,e),p=e=>(0,a.sB)(n.j,e),m=e=>(0,a.RE)(n.j,e),g=(e,t)=>(0,a.R4)(n.j,e,t)}}]);
2//# chunkId=01a0f7ef-7ead-7140-890b-1da188f97384

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.