');for(const n of document.getElementsByTagName("script")){if(n.dataset.astroExec==="")continue;const o=n.getAttribute("type");if(o&&o!=="module"&&o!=="text/javascript")continue;const r=document.createElement("script");r.innerHTML=n.innerHTML;for(const i of n.attributes){if(i.name==="src"){const u=new Promise(a=>{r.onload=r.onerror=a});e=e.then(()=>u)}r.setAttribute(i.name,i.value)}r.dataset.astroExec="",n.replaceWith(r)}return e}const G=(e,t,n,o,r)=>{const i=W(t,e),u=document.title;document.title=o;let a=!1;if(e.href!==location.href&&!r)if(n.history==="replace"){const c=history.state;E({...n.state,index:c.index,scrollX:c.scrollX,scrollY:c.scrollY},"",e.href)}else be({...n.state,index:++v,scrollX:0,scrollY:0},"",e.href);if(document.title=u,R=e,i||(scrollTo({left:0,top:0,behavior:"instant"}),a=!0),r)scrollTo(r.scrollX,r.scrollY);else{if(e.hash){history.scrollRestoration="auto";const c=history.state;location.href=e.href,history.state||(E(c,""),i&&window.dispatchEvent(new PopStateEvent("popstate")))}else a||scrollTo({left:0,top:0,behavior:"instant"});history.scrollRestoration="manual"}};function Ee(e){const t=[];for(const n of e.querySelectorAll("head link[rel=stylesheet]"))if(!document.querySelector(`[${H}="${n.getAttribute(H)}"], link[rel=stylesheet][href="${n.getAttribute("href")}"]`)){const o=document.createElement("link");o.setAttribute("rel","preload"),o.setAttribute("as","style"),o.setAttribute("href",n.getAttribute("href")),t.push(new Promise(r=>{["load","error"].forEach(i=>o.addEventListener(i,r)),document.head.append(o)}))}return t}async function _(e,t,n,o,r){async function i(f){function l(d){const p=d.effect;return!p||!(p instanceof KeyframeEffect)||!p.target?!1:window.getComputedStyle(p.target,p.pseudoElement).animationIterationCount==="infinite"}const s=document.getAnimations();document.documentElement.setAttribute(P,f);const b=document.getAnimations().filter(d=>!s.includes(d)&&!l(d));return Promise.allSettled(b.map(d=>d.finished))}const u=async()=>{if(r==="animate"&&!n.transitionSkipped&&!e.signal.aborted)try{await i("old")}catch{}},a=document.title,c=await ye(e,n.viewTransition,u);G(c.to,c.from,t,a,o),V(me),r==="animate"&&(!n.transitionSkipped&&!c.signal.aborted?i("new").finally(()=>n.viewTransitionFinished()):n.viewTransitionFinished())}function Se(){return m?.controller.abort(),m={controller:new AbortController}}async function z(e,t,n,o,r){const i=Se();if(!N()||location.origin!==n.origin){i===m&&(m=void 0),location.href=n.href;return}const u=r?"traverse":o.history==="replace"?"replace":"push";if(u!=="traverse"&&x({scrollX,scrollY}),W(t,n)&&!o.formData&&(e!=="back"&&n.hash||e==="back"&&t.hash)){G(n,t,o,document.title,r),i===m&&(m=void 0);return}const a=await ge(t,n,e,u,o.sourceElement,o.info,i.controller.signal,o.formData,c);if(a.defaultPrevented||a.signal.aborted){i===m&&(m=void 0),a.signal.aborted||(location.href=n.href);return}async function c(s){const h=s.to.href,b={signal:s.signal};if(s.formData){b.method="POST";const w=s.sourceElement instanceof HTMLFormElement?s.sourceElement:s.sourceElement instanceof HTMLElement&&"form"in s.sourceElement?s.sourceElement.form:s.sourceElement?.closest("form");b.body=t!==void 0&&Reflect.get(HTMLFormElement.prototype,"attributes",w).getNamedItem("enctype")?.value==="application/x-www-form-urlencoded"?new URLSearchParams(s.formData):s.formData}const d=await Te(h,b);if(d===null){s.preventDefault();return}if(d.redirected){const w=new URL(d.redirected);if(w.origin!==s.to.origin){s.preventDefault();return}s.to=w}if(C??=new DOMParser,s.newDocument=C.parseFromString(d.html,d.mediaType),s.newDocument.querySelectorAll("noscript").forEach(w=>w.remove()),!s.newDocument.querySelector('[name="astro-view-transitions-enabled"]')&&!s.formData){s.preventDefault();return}const p=Ee(s.newDocument);p.length&&!s.signal.aborted&&await Promise.all(p)}async function f(){if(g&&g.viewTransition){try{g.viewTransition.skipTransition()}catch{}try{await g.viewTransition.updateCallbackDone}catch{}}return g={transitionSkipped:!1}}const l=await f();if(a.signal.aborted){i===m&&(m=void 0);return}if(document.documentElement.setAttribute(F,a.direction),I)l.viewTransition=document.startViewTransition(async()=>await _(a,o,l,r));else{const s=(async()=>{await Promise.resolve(),await _(a,o,l,r,K())})();l.viewTransition={updateCallbackDone:s,ready:s,finished:new Promise(h=>l.viewTransitionFinished=h),skipTransition:()=>{l.transitionSkipped=!0,document.documentElement.removeAttribute(P)},types:new Set}}l.viewTransition?.updateCallbackDone.finally(async()=>{await Ae(),j(),ve()}),l.viewTransition?.finished.finally(()=>{l.viewTransition=void 0,l===g&&(g=void 0),i===m&&(m=void 0),document.documentElement.removeAttribute(F),document.documentElement.removeAttribute(P)});try{await l.viewTransition?.updateCallbackDone}catch(s){const h=s;console.log("[astro]",h.name,h.message,h.stack)}}async function X(e,t){await z("forward",R,new URL(e,location.href),t??{})}function Re(e){if(!N()&&e.state){location.reload();return}if(e.state===null)return;const t=history.state,n=t.index,o=n>v?"forward":"back";v=n,z(o,R,new URL(location.href),{},t)}const Y=()=>{history.state&&(scrollX!==history.state.scrollX||scrollY!==history.state.scrollY)&&x({scrollX,scrollY})};{if(I||K()!=="none")if(R=new URL(location.href),addEventListener("popstate",Re),addEventListener("load",j),"onscrollend"in window)addEventListener("scrollend",Y);else{let e,t,n,o;const r=()=>{if(o!==history.state?.index){clearInterval(e),e=void 0;return}if(t===scrollY&&n===scrollX){clearInterval(e),e=void 0,Y();return}else t=scrollY,n=scrollX};addEventListener("scroll",()=>{e===void 0&&(o=history.state?.index,t=scrollY,n=scrollX,e=window.setInterval(r,50))},{passive:!0})}for(const e of document.getElementsByTagName("script"))U(e),e.dataset.astroExec=""}const J=new Set,S=new WeakSet;let D,Q,B=!1;function Le(e){B||(B=!0,D??=e?.prefetchAll,Q??=e?.defaultStrategy??"hover",ke(),Pe(),De(),Ie())}function ke(){for(const e of["touchstart","mousedown"])document.body.addEventListener(e,t=>{T(t.target,"tap")&&L(t.target.href,{ignoreSlowConnection:!0})},{passive:!0})}function Pe(){let e;document.body.addEventListener("focusin",o=>{T(o.target,"hover")&&t(o)},{passive:!0}),document.body.addEventListener("focusout",n,{passive:!0}),O(()=>{for(const o of document.getElementsByTagName("a"))S.has(o)||T(o,"hover")&&(S.add(o),o.addEventListener("mouseenter",t,{passive:!0}),o.addEventListener("mouseleave",n,{passive:!0}))});function t(o){const r=o.target.href;e&&clearTimeout(e),e=setTimeout(()=>{L(r)},80)}function n(){e&&(clearTimeout(e),e=0)}}function De(){let e;O(()=>{for(const t of document.getElementsByTagName("a"))S.has(t)||T(t,"viewport")&&(S.add(t),e??=xe(),e.observe(t))})}function xe(){const e=new WeakMap;return new IntersectionObserver((t,n)=>{for(const o of t){const r=o.target,i=e.get(r);o.isIntersecting?(i&&clearTimeout(i),e.set(r,setTimeout(()=>{n.unobserve(r),e.delete(r),L(r.href)},300))):i&&(clearTimeout(i),e.delete(r))}})}function Ie(){O(()=>{for(const e of document.getElementsByTagName("a"))T(e,"load")&&L(e.href)})}function L(e,t){e=e.replace(/#.*/,"");const n=t?.ignoreSlowConnection??!1;if(Ne(e,n))if(J.add(e),document.createElement("link").relList?.supports?.("prefetch")&&t?.with!=="fetch"){const o=document.createElement("link");o.rel="prefetch",o.setAttribute("href",e),document.head.append(o)}else fetch(e,{priority:"low"})}function Ne(e,t){if(!navigator.onLine||!t&&Z())return!1;try{const n=new URL(e,location.href);return location.origin===n.origin&&(location.pathname!==n.pathname||location.search!==n.search)&&!J.has(e)}catch{}return!1}function T(e,t){if(e?.tagName!=="A")return!1;const n=e.dataset.astroPrefetch;return n==="false"?!1:t==="tap"&&(n!=null||D)&&Z()?!0:n==null&&D||n===""?t===Q:n===t}function Z(){if("connection"in navigator){const e=navigator.connection;return e.saveData||/2g/.test(e.effectiveType)}return!1}function O(e){e();let t=!1;document.addEventListener("astro:page-load",()=>{if(!t){t=!0;return}e()})}let A=null;function Oe(){const e=document.querySelector('[name="astro-view-transitions-fallback"]');return e?e.getAttribute("content"):"animate"}function $(e){return e.dataset.astroReload!==void 0}const Me=e=>e.button&&e.button!==0||e.metaKey||e.ctrlKey||e.altKey||e.shiftKey;(I||Oe()!=="none")&&(document.addEventListener("click",e=>{let t=e.target;if(A=Me(e)?t:null,e.composed&&(t=e.composedPath()[0]),t instanceof Element&&(t=t.closest("a, area")),!(t instanceof HTMLAnchorElement)&&!(t instanceof SVGAElement)&&!(t instanceof HTMLAreaElement))return;const n=t instanceof HTMLElement?t.target:t.target.baseVal,o=t instanceof HTMLElement?t.href:t.href.baseVal,r=new URL(o,location.href).origin;$(t)||t.hasAttribute("download")||!t.href||n&&n!=="_self"||r!==location.origin||A||e.defaultPrevented||(e.preventDefault(),X(o,{history:t.dataset.astroHistory==="replace"?"replace":"auto",sourceElement:t}))}),document.addEventListener("submit",e=>{let t=e.target;const n=e.submitter,o=n&&n===A;if(A=null,t.tagName!=="FORM"||e.defaultPrevented||$(t)||o)return;const r=t,i=new FormData(r,n),u=typeof r.action=="string"?r.action:r.getAttribute("action"),a=typeof r.method=="string"?r.method:r.getAttribute("method");let c=n?.getAttribute("formaction")??u??location.pathname;const f=n?.getAttribute("formmethod")??a??"get";if(f==="dialog"||location.origin!==new URL(c,location.href).origin)return;const l={sourceElement:n??r};if(f==="get"){const s=new URLSearchParams(i),h=new URL(c);h.search=s.toString(),c=h.toString()}else l.formData=i;e.preventDefault(),X(c,l)}),Le({prefetchAll:!0}));
Sunday 19 May 2024 at 15:34:08 BST | 1 min read
View project
Talangeen Talangeen UI showing list of members and transactions in Bahasa Talangeen
is an app that enables users to track shared expenses with friends, ensuring everyone gets reimbursed.
It was inspired by a real-world problem I encountered while traveling with friends. Whenever we spent money on things like food, lodging, or tickets to tourist attractions, one person would pay for everyone. At the end of the day, we would list all our expenses and split the bill.
Calculating the bills each of us owed was a painstaking process. That’s why I created Talangeen
. Now, all we have to do is enter our names and the transactions we’ve made, and Talangeen
swiftly handles the calculations, far more efficiently than manual effort.