1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,20955,(e,t,i)=>{var r={229:function(e){var t,i,r,n=e.exports={};function a(){throw Error("setTimeout has not been defined")}function o(){throw Error("clearTimeout has not been defined")}try{t="function"==typeof setTimeout?setTimeout:a}catch(e){t=a}try{i="function"==typeof clearTimeout?clearTimeout:o}catch(e){i=o}function s(e){if(t===setTimeout)return setTimeout(e,0);if((t===a||!t)&&setTimeout)return t=setTimeout,setTimeout(e,0);try{return t(e,0)}catch(i){try{return t.call(null,e,0)}catch(i){return t.call(this,e,0)}}}var l=[],c=!1,u=-1;function p(){c&&r&&(c=!1,r.length?l=r.concat(l):u=-1,l.length&&d())}function d(){if(!c){var e=s(p);c=!0;for(var t=l.length;t;){for(r=l,l=[];++u<t;)r&&r[u].run();u=-1,t=l.length}r=null,c=!1,function(e){if(i===clearTimeout)return clearTimeout(e);if((i===o||!i)&&clearTimeout)return i=clearTimeout,clearTimeout(e);try{i(e)}catch(t){try{return i.call(null,e)}catch(t){return i.call(this,e)}}}(e)}}function m(e,t){this.fun=e,this.array=t}function h(){}n.nextTick=function(e){var t=Array(arguments.length-1);if(arguments.length>1)for(var i=1;i<arguments.length;i++)t[i-1]=arguments[i];l.push(new m(e,t)),1!==l.length||c||s(d)},m.prototype.run=function(){this.fun.apply(null,this.array)},n.title="browser",n.browser=!0,n.env={},n.argv=[],n.version="",n.versions={},n.on=h,n.addListener=h,n.once=h,n.off=h,n.removeListener=h,n.removeAllListeners=h,n.emit=h,n.prependListener=h,n.prependOnceListener=h,n.listeners=function(e){return[]},n.binding=function(e){throw Error("process.binding is not supported")},n.cwd=function(){return"/"},n.chdir=function(e){throw Error("process.chdir is not supported")},n.umask=function(){return 0}}},n={};function a(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}},o=!0;try{r[e](i,i.exports,a),o=!1}finally{o&&delete n[e]}return i.exports}a.ab="/ROOT/node_modules/next/dist/compiled/process/",t.exports=a(229)},50461,(e,t,i)=>{"use strict";var r,n;t.exports=(null==(r=e.g.process)?void 0:r.env)&&"object"==typeof(null==(n=e.g.process)?void 0:n.env)?e.g.process:e.r(20955)},41705,(e,t,i)=>{"use strict";i._=function(e){return e&&e.__esModule?e:{default:e}}},8481,(e,t,i)=>{"use strict";var r=Symbol.for("react.transitional.element");function n(e,t,i){var n=null;if(void 0!==i&&(n=""+i),void 0!==t.key&&(n=""+t.key),"key"in t)for(var a in i={},t)"key"!==a&&(i[a]=t[a]);else i=t;return{$$typeof:r,type:e,key:n,ref:void 0!==(t=i.ref)?t:null,props:i}}i.Fragment=Symbol.for("react.fragment"),i.jsx=n,i.jsxs=n},91398,(e,t,i)=>{"use strict";t.exports=e.r(8481)},61556,(e,t,i)=>{"use strict";var r=e.i(50461),n=Symbol.for("react.transitional.element"),a=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),l=Symbol.for("react.profiler"),c=Symbol.for("react.consumer"),u=Symbol.for("react.context"),p=Symbol.for("react.forward_ref"),d=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),h=Symbol.for("react.lazy"),f=Symbol.for("react.activity"),g=Symbol.iterator,b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},v=Object.assign,y={};function w(e,t,i){this.props=e,this.context=t,this.refs=y,this.updater=i||b}function S(){}function k(e,t,i){this.props=e,this.context=t,this.refs=y,this.updater=i||b}w.prototype.isReactComponent={},w.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},w.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},S.prototype=w.prototype;var A=k.prototype=new S;A.constructor=k,v(A,w.prototype),A.isPureReactComponent=!0;var C=Array.isArray;function I(){}var x={H:null,A:null,T:null,S:null},j=Object.prototype.hasOwnProperty;function O(e,t,i){var r=i.ref;return{$$typeof:n,type:e,key:t,ref:void 0!==r?r:null,props:i}}function P(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var T=/\/+/g;function _(e,t){var i,r;return"object"==typeof e&&null!==e&&null!=e.key?(i=""+e.key,r={"=":"=0",":":"=2"},"$"+i.replace(/[=:]/g,function(e){return r[e]})):t.toString(36)}function E(e,t,i){if(null==e)return e;var r=[],o=0;return!function e(t,i,r,o,s){var l,c,u,p=typeof t;("undefined"===p||"boolean"===p)&&(t=null);var d=!1;if(null===t)d=!0;else switch(p){case"bigint":case"string":case"number":d=!0;break;case"object":switch(t.$$typeof){case n:case a:d=!0;break;case h:return e((d=t._init)(t._payload),i,r,o,s)}}if(d)return s=s(t),d=""===o?"."+_(t,0):o,C(s)?(r="",null!=d&&(r=d.replace(T,"$&/")+"/"),e(s,i,r,"",function(e){return e})):null!=s&&(P(s)&&(l=s,c=r+(null==s.key||t&&t.key===s.key?"":(""+s.key).replace(T,"$&/")+"/")+d,s=O(l.type,c,l.props)),i.push(s)),1;d=0;var m=""===o?".":o+":";if(C(t))for(var f=0;f<t.length;f++)p=m+_(o=t[f],f),d+=e(o,i,r,p,s);else if("function"==typeof(f=null===(u=t)||"object"!=typeof u?null:"function"==typeof(u=g&&u[g]||u["@@iterator"])?u:null))for(t=f.call(t),f=0;!(o=t.next()).done;)p=m+_(o=o.value,f++),d+=e(o,i,r,p,s);else if("object"===p){if("function"==typeof t.then)return e(function(e){switch(e.status){case"fulfilled":return e.value;case"rejected":throw e.reason;default:switch("string"==typeof e.status?e.then(I,I):(e.status="pending",e.then(function(t){"pending"===e.status&&(e.status="fulfilled",e.value=t)},function(t){"pending"===e.status&&(e.status="rejected",e.reason=t)})),e.status){case"fulfilled":return e.value;case"rejected":throw e.reason}}throw e}(t),i,r,o,s);throw Error("Objects are not valid as a React child (found: "+("[object Object]"===(i=String(t))?"object with keys {"+Object.keys(t).join(", ")+"}":i)+"). If you meant to render a collection of children, use an array instead.")}return d}(e,r,"","",function(e){return t.call(i,e,o++)}),r}function K(e){if(-1===e._status){var t=e._result;(t=t()).then(function(t){(0===e._status||-1===e._status)&&(e._status=1,e._result=t)},function(t){(0===e._status||-1===e._status)&&(e._status=2,e._result=t)}),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var D="function"==typeof reportError?reportError:function(e){if("object"==typeof window&&"function"==typeof window.ErrorEvent){var t=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:"object"==typeof e&&null!==e&&"string"==typeof e.message?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if("object"==typeof r.default&&"function"==typeof r.default.emit)return void r.default.emit("uncaughtException",e);console.error(e)};i.Activity=f,i.Children={map:E,forEach:function(e,t,i){E(e,function(){t.apply(this,arguments)},i)},count:function(e){var t=0;return E(e,function(){t++}),t},toArray:function(e){return E(e,function(e){return e})||[]},only:function(e){if(!P(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},i.Component=w,i.Fragment=o,i.Profiler=l,i.PureComponent=k,i.StrictMode=s,i.Suspense=
1d,i.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=x,i.__COMPILER_RUNTIME={__proto__:null,c:function(e){return x.H.useMemoCache(e)}},i.cache=function(e){return function(){return e.apply(null,arguments)}},i.cacheSignal=function(){return null},i.cloneElement=function(e,t,i){if(null==e)throw Error("The argument must be a React element, but you passed "+e+".");var r=v({},e.props),n=e.key;if(null!=t)for(a in void 0!==t.key&&(n=""+t.key),t)j.call(t,a)&&"key"!==a&&"__self"!==a&&"__source"!==a&&("ref"!==a||void 0!==t.ref)&&(r[a]=t[a]);var a=arguments.length-2;if(1===a)r.children=i;else if(1<a){for(var o=Array(a),s=0;s<a;s++)o[s]=arguments[s+2];r.children=o}return O(e.type,n,r)},i.createContext=function(e){return(e={$$typeof:u,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider=e,e.Consumer={$$typeof:c,_context:e},e},i.createElement=function(e,t,i){var r,n={},a=null;if(null!=t)for(r in void 0!==t.key&&(a=""+t.key),t)j.call(t,r)&&"key"!==r&&"__self"!==r&&"__source"!==r&&(n[r]=t[r]);var o=arguments.length-2;if(1===o)n.children=i;else if(1<o){for(var s=Array(o),l=0;l<o;l++)s[l]=arguments[l+2];n.children=s}if(e&&e.defaultProps)for(r in o=e.defaultProps)void 0===n[r]&&(n[r]=o[r]);return O(e,a,n)},i.createRef=function(){return{current:null}},i.forwardRef=function(e){return{$$typeof:p,render:e}},i.isValidElement=P,i.lazy=function(e){return{$$typeof:h,_payload:{_status:-1,_result:e},_init:K}},i.memo=function(e,t){return{$$typeof:m,type:e,compare:void 0===t?null:t}},i.startTransition=function(e){var t=x.T,i={};x.T=i;try{var r=e(),n=x.S;null!==n&&n(i,r),"object"==typeof r&&null!==r&&"function"==typeof r.then&&r.then(I,D)}catch(e){D(e)}finally{null!==t&&null!==i.types&&(t.types=i.types),x.T=t}},i.unstable_useCacheRefresh=function(){return x.H.useCacheRefresh()},i.use=function(e){return x.H.use(e)},i.useActionState=function(e,t,i){return x.H.useActionState(e,t,i)},i.useCallback=function(e,t){return x.H.useCallback(e,t)},i.useContext=function(e){return x.H.useContext(e)},i.useDebugValue=function(){},i.useDeferredValue=function(e,t){return x.H.useDeferredValue(e,t)},i.useEffect=function(e,t){return x.H.useEffect(e,t)},i.useEffectEvent=function(e){return x.H.useEffectEvent(e)},i.useId=function(){return x.H.useId()},i.useImperativeHandle=function(e,t,i){return x.H.useImperativeHandle(e,t,i)},i.useInsertionEffect=function(e,t){return x.H.useInsertionEffect(e,t)},i.useLayoutEffect=function(e,t){return x.H.useLayoutEffect(e,t)},i.useMemo=function(e,t){return x.H.useMemo(e,t)},i.useOptimistic=function(e,t){return x.H.useOptimistic(e,t)},i.useReducer=function(e,t,i){return x.H.useReducer(e,t,i)},i.useRef=function(e){return x.H.useRef(e)},i.useState=function(e){return x.H.useState(e)},i.useSyncExternalStore=function(e,t,i){return x.H.useSyncExternalStore(e,t,i)},i.useTransition=function(){return x.H.useTransition()},i.version="19.2.7"},91788,(e,t,i)=>{"use strict";t.exports=e.r(61556)},13584,(e,t,i)=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0}),Object.defineProperty(i,"HeadManagerContext",{enumerable:!0,get:function(){return r}});let r=e.r(41705)._(e.r(91788)).default.createContext({})},94470,(e,t,i)=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0}),Object.defineProperty(i,"warnOnce",{enumerable:!0,get:function(){return r}});let r=e=>{}},52456,(e,t,i)=>{"use strict";function r(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,i=new WeakMap;return(r=function(e){return e?i:t})(e)}i._=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var i=r(t);if(i&&i.has(e))return i.get(e);var n={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var s=a?Object.getOwnPropertyDescriptor(e,o):null;s&&(s.get||s.set)?Object.defineProperty(n,o,s):n[o]=e[o]}return n.default=e,i&&i.set(e,n),n}},94941,(e,t,i)=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0}),Object.defineProperty(i,"default",{enumerable:!0,get:function(){return s}});let r=e.r(91788),n="u"<typeof window,a=n?()=>{}:r.useLayoutEffect,o=n?()=>{}:r.useEffect;function s(e){let{headManager:t,reduceComponentsToState:i}=e;function s(){if(t&&t.mountedInstances){let e=r.Children.toArray(Array.from(t.mountedInstances).filter(
1Boolean));t.updateHead(i(e))}}return n&&(t?.mountedInstances?.add(e.children),s()),a(()=>(t?.mountedInstances?.add(e.children),()=>{t?.mountedInstances?.delete(e.children)})),a(()=>(t&&(t._pendingUpdate=s),()=>{t&&(t._pendingUpdate=s)})),o(()=>(t&&t._pendingUpdate&&(t._pendingUpdate(),t._pendingUpdate=null),()=>{t&&t._pendingUpdate&&(t._pendingUpdate(),t._pendingUpdate=null)})),null}},80963,(e,t,i)=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});var r={default:function(){return f},defaultHead:function(){return p}};for(var n in r)Object.defineProperty(i,n,{enumerable:!0,get:r[n]});let a=e.r(41705),o=e.r(52456),s=e.r(91398),l=o._(e.r(91788)),c=a._(e.r(94941)),u=e.r(13584);function p(){return[(0,s.jsx)("meta",{charSet:"utf-8"},"charset"),(0,s.jsx)("meta",{name:"viewport",content:"width=device-width"},"viewport")]}function d(e,t){return"string"==typeof t||"number"==typeof t?e:t.type===l.default.Fragment?e.concat(l.default.Children.toArray(t.props.children).reduce((e,t)=>"string"==typeof t||"number"==typeof t?e:e.concat(t),[])):e.concat(t)}e.r(94470);let m=["name","httpEquiv","charSet","itemProp"];function h(e){let t,i,r,n;return e.reduce(d,[]).reverse().concat(p().reverse()).filter((t=new Set,i=new Set,r=new Set,n={},e=>{let a=!0,o=!1;if(e.key&&"number"!=typeof e.key&&e.key.indexOf("$")>0){o=!0;let i=e.key.slice(e.key.indexOf("$")+1);t.has(i)?a=!1:t.add(i)}switch(e.type){case"title":case"base":i.has(e.type)?a=!1:i.add(e.type);break;case"meta":for(let t=0,i=m.length;t<i;t++){let i=m[t];if(e.props.hasOwnProperty(i))if("charSet"===i)r.has(i)?a=!1:r.add(i);else{let t=e.props[i],r=n[i]||new Set;("name"!==i||!o)&&r.has(t)?a=!1:(r.add(t),n[i]=r)}}}return a})).reverse().map((e,t)=>{let i=e.key||t;return l.default.cloneElement(e,{key:i})})}let f=function({children:e}){let t=(0,l.useContext)(u.HeadManagerContext);return(0,s.jsx)(c.default,{reduceComponentsToState:h,headManager:t,children:e})};("function"==typeof i.default||"object"==typeof i.default&&null!==i.default)&&void 0===i.default.__esModule&&(Object.defineProperty(i.default,"__esModule",{value:!0}),Object.assign(i.default,i),t.exports=i.default)},58678,(e,t,i)=>{t.exports=e.r(80963)},12117,(e,t,i)=>{t.exports=JSON.parse('{"name":"entaku","role":"Mobile App Developer","description":"iOSãªã¼ãã¨ã³ã¸ãã¢ãSwift / Kotlin / Go ã使ã£ãã¢ãã¤ã«ã¢ããªéçºã徿ãTVerã»Voicy çã§ãªã¼ãã¨ã³ã¸ãã¢ã¨ãã¦æ´»èºã","githubUsername":"entaku0818","twitterUrl":"https://twitter.com/entaku_0818","twitterId":"@entaku_0818","githubUrl":"https://github.com/entaku0818","siteUrl":"https://entaku.dev","summary":["2013å¹´ããã½ããã¦ã§ã¢éçºã«æºããã¢ãã¤ã«ã¢ããªã¨ã³ã¸ãã¢ãSIerã§ã¤ã³ãã©ã»Webéçºãçµé¨ããå¾ãiOS / Android ã«è»¸è¶³ãç§»ãã¾ããã","ç¾å¨ã¯æ ªå¼ä¼ç¤¾TVerã®iOSãªã¼ãã¨ã³ã¸ãã¢ãThe Composable Architecture ã«ããåçåºç¤ã®ãªãã¬ã¤ã¹ã¨åºå飿ºãæ
å½ãã2026å¹´ãã©ãå¬å£ãªãªã³ããã¯ã®é
ä¿¡ã«ã対å¿ãã¾ããã","åè·ã®Voicyã§ã¯ã夿³¨ä¸»ä½ã ã£ãåé²ã¢ããªã®éçºãå
製åãæ°è¦ã¢ã¸ã¥ã¼ã«ã§ãã¹ãã«ãã¬ãã¸80%以ä¸ããªãªã¼ã¹å¾ã®ä¸å
·åå ±åãç´40%忏ãã¾ããã","å人ã§ã¯ã·ã³ãã«é²é³ã»èªã¿ä¸ããã¬ã¼ã¿ã¼ã»ClipKitã»Festory ãªã©è¤æ°ã®ã¢ããªãé
ä¿¡ä¸ãã¢ããªã ãã§ãªã Go / Firebase ã®ããã¯ã¨ã³ãããªã³ããã¤ã¹AIã¾ã§ä¸äººã§ä½ã£ã¦ãã¾ãã","iOSDC JAPAN ã§4åç»å£ï¼2020ã2024ï¼ãSwiftæå¥½ä¼ã®éå¶ãDroidKaigi ã®ã¹ã¿ããã¨ãã¦ã³ãã¥ããã£ã«ãé¢ãã£ã¦ãã¾ãã"],"timeline":[{"period":"2025/01 - ç¾å¨","title":"æ ªå¼ä¼ç¤¾TVer","detail":"iOSãªã¼ãã¨ã³ã¸ãã¢ãåç»åç
1åºç¤ï¼TCAï¼ã¨åºå飿º"},{"period":"2025 - 2026","title":"å人éçºã§æ°ä½ãç¸æ¬¡ãã§ãªãªã¼ã¹","detail":"ClipKitã»Speedmeterã»Slumberã»Festory"},{"period":"2021/12 - 2024/12","title":"æ ªå¼ä¼ç¤¾Voicy","detail":"iOSã¨ã³ã¸ãã¢å
¼ãã¼ã ãªã¼ãã¼ãåé²ã¢ããªã®å
製åã¨ã¢ã¼ããã¯ãã£å·æ°"},{"period":"2019/04 - 2021/11","title":"CBCloud","detail":"ã¢ãã¤ã«ã¨ã³ã¸ã㢠â ãã¼ã ãªã¼ãã¼ãPickGo / SmaRyuTruck"},{"period":"2018/02 - 2019/03","title":"Lifesports","detail":"ã¹ãã¼ããããã³ã°ã¢ããªã®éçº"},{"period":"2013/09 - 2018/02","title":"æ ªå¼ä¼ç¤¾ã¨ã¼ãã¼ã³ãã¥ãã±ã¼ã·ã§ã³ãº","detail":"ãããã¯ã¼ã¯ã¨ã³ã¸ãã¢ããã¹ã¿ã¼ãããWebã»æ¥åã·ã¹ãã éçºã¸"}],"techStack":[{"label":"iOS","items":["Swift","SwiftUI","UIKit","TCA","Combine","CoreData / SwiftData","CloudKit","WidgetKit","Live Activities","App Intents","HealthKit"]},{"label":"Android","items":["Kotlin","Jetpack Compose","Room","WorkManager","ExoPlayer"]},{"label":"é³å£°ã»åç»","items":["AVFoundation / AVPlayer","Core Audio","Speech","Agora SDK"]},{"label":"Backend","items":["Go","Cloud Run","Firebase Functions","Firestore","Supabase","Rails","Laravel"]},{"label":"AI","items":["Gemini API","Claude API","WhisperKit","MLX Swift","Foundation Models","Claude Code"]},{"label":"CI/CDã»éç¨","items":["GitHub Actions","fastlane","Xcode Cloud","Crashlytics","RevenueCat","AdMob"]}],"specialties":["ã¢ãã¤ã«ã¢ããªã®éçºãã¢ã¼ããã¯ãã£è¨è¨","é³å£°é
ä¿¡ / ã©ã¤ãé
ä¿¡ã®ä»çµã
1¿ä½ã","äºæ¥ãã¤ã³ããæã£ããããã¯ãéçº â æè¡ã ãã§ãªãäºæ¥æé·ã®è¦ç¹ããæ½çãèããå®è¡ã§ããã¨ã³ã¸ãã¢ãç®æãã¦ãã"],"talks":[{"event":"iOSDC JAPAN 2024","title":"Core Audio","links":[{"label":"詳細","url":"https://fortee.jp/iosdc-japan-2024/proposal/8c6f01d9-8fd3-4d5e-afef-f29d561f3c39"}]},{"event":"iOSDC JAPAN 2022","title":"é³å£°é
ä¿¡ã¢ããªã«ãããiOSã使ã£ãé³å£°é
ä¿¡ã®å
¨ã¦ã¨è£å´","links":[{"label":"詳細","url":"https://fortee.jp/iosdc-japan-2022/proposal/ee2ab807-9053-4779-84f9-ec9951f7cfc0"}]},{"event":"iOSDC JAPAN 2021","title":"æ¢åã®ãã¤ãã£ãã¢ããªãFlutterã¸ãªãã¬ã¤ã¹ããæ¹æ³","links":[{"label":"詳細","url":"https://iosdc.jp/2021/"},{"label":"Speaker Deck","url":"https://speakerdeck.com/entaku/pickgo-for-partnerfalseyi-xing-fang-fa-karaxue-hu-ji-cun-falseneiteihuahuriwoflutterherihureisusurufang-fa"}]},{"event":"iOSDC JAPAN 2020","title":"DroidKaigiã®å
¬å¼ã¢ããªã§å§ããiOSã¢ããªã®OSSã³ããã¿ã¼ã¸ã®é","links":[{"label":"詳細","url":"https://fortee.jp/iosdc-japan-2020/proposal/c3c70224-08cf-48d7-b5e5-a3d4589737fa"},{"label":"Speaker Deck","url":"https://speakerdeck.com/entaku/droidkaigifalsegong-shi-ahuriteshi-meru-iosahuriosskomitutahefalsedao"}]},{"event":"Vue.js ã¢ã¼ããã¯ãã£ãªã³ã°åå¼·ä¼","title":"Vue / Vuex ã®ã¢ã¼ããã¯ãã£ãå®å
¨ã«çè§£ãã","links":[{"label":"詳細","url":"https://cw-engineers.connpass.com/event/146975/"},{"label":"Speaker Deck","url":"https://speakerdeck.com/entaku/vue-vuex-falseakitekutiyawan-quan-nili-jie-sita"}]}],"communities":[{"name":"Swiftæå¥½ä¼","role":"éå¶ã¡ã³ãã¼","url":"https://love-swift.connpass.com/","linkLabel":"connpass","description":"Swiftã¨ã³ã¸ãã¢2,200å以ä¸ãåå ããã³ãã¥ããã£ã®éå¶ã«æºãããæ1ã2åã®ãã¼ã¹ã§åå¼·ä¼ãä¼ç»ã»éå¬ï¼vol.98ã¾ã§ç¶ç¶ä¸ï¼ã"},{"name":"DroidKaigi","role":"ã¹ã¿ãã","url":"https://droidkaigi.jp/","linkLabel":"Website","description":"Androidéçºè
åãã«ã³ãã¡ã¬ã³ã¹ãDroidKaigiãã®ã¹ã¿ããã¨ãã¦éå¶ã«åå ã"}],"experiences":[{"company":"TVer","period":"2025/01 - ç¾å¨","url":"https://tver.jp/","overview":"æ¥æ¬æå¤§ç´ã®æ°æ¾å
¬å¼ãã¬ããã¼ã¿ã«ãTVerãã«ã¦ãiOSãªã¼ãã¨ã³ã¸ãã¢ã¨ãã¦åç»ãåç»åçã¾ããã®ä½é¨ã¨ããã®å¨è¾ºã®åºå飿ºã®éçºãæ
å½ãã¦ããã","highlights":[{"title":"åç»åçã¨åºååçå","points":["ã©ã¤ãé
ä¿¡ã»VODã®åæ¹ã§ãã¬ã¤ã¤ã¼æ©è½ã®éçºãæ
å½ããåçã¾ããã®åºå飿ºãå®è£
","åç»åçé¢é£ã®ã³ã¼ããTCAï¼The Composable Architectureï¼ã§ãªãã¬ã¤ã¹ããä¿å®æ§ã»ãã¹ã¿ããªãã£ãæ¹å"]},{"title":"å¤§è¦æ¨¡ã©ã¤ãã¤ãã³ãã®é
信対å¿","points":["2026å¹´ãã©ãå¬å£ãªãªã³ããã¯ã®é
ä¿¡ã«å¯¾å¿ããäºè¼ªç¹éãããç»é¢ã»ç¹éUIãæ°è¦å®è£
","å¤é¨ã«åºå®ãããç· ãåãã®ãã¨ã§ãã©ã¤ãé
ä¿¡ã¨VODã®åæ¹ãã«ãã¼ããåå©ç¨å¯è½ãªãã¬ã¤ã¤ã¼ã¢ã¸ã¥ã¼ã«ãæ§ç¯"]},{"title":"Xcode Cloudã«ãã CIç°å¢ã®æ§ç¯","points":["ãã¹ãã¯åå¨ãã¦ãããCIç°å¢ãæªæ´åã ã£ãç¶æ³ãæ¹å","Xcode Cloudãå°å
¥ããPRåä½ã§ã®èªåãã¹ãå®è¡ã¨ãã«ãæ¤è¨¼ãå®ç¾ãiOSãã¼ã å
¨ä½ã®éçºãµã¤ã¯ã«ãå®å®å"]},{"title":"ã¦ã©ã¼ã¯ã¹ã«ã¼ç»é¢ã®å·æ°","points":["æ¢åã®ãªã³ãã¼ãã£ã³ã°ããã¼ãå
¨é¢çã«è¦ç´ããã¦ã¼ã¶ã¼ãç´æçã«ã¢ããªãçè§£ã§ããUIã«æ¹å"]}],"tech":[{"label":"è¨èª","items":["Swift"]},{"label":"ãã¬ã¼ã ã¯ã¼ã¯","items":["SwiftUI","UIKit","Combine","TCA"]},{"label":"åç»åç","items":["AVFoundation","AVPlayer"]},{"label":"CI/CD","items":["Xcode Cloud"]}]},{"company":"Voicy","period":"2021/12 - 2024/12","url":"https://voicy.jp/","overview":"é³å£°é
ä¿¡ãã©ãããã©ã¼ã ãVoicyãã«ã¦ãiOSã¨ã³ã¸ãã¢å
¼ãã¼ã ãªã¼ãã¼ã¨ãã¦3å¹´éå¾äºããã¼ã½ããªãã£åãåé²ã¢ããªã®éçºè²¬ä»»è
ã¨ãã¦ã夿³¨ä¸»ä½ã ã£ãéçºä½å¶ã®å
製åããã¢ã¼ããã¯ãã£å·æ°ãæ°æ©è½éçºã¾ã§ããªã¼ãããã","highlights":[{"title":"ã¢ããªéçºã®å
製åã¨ã³ã¼ãåè³ªã®ææ¬çæ¹å","points":["嵿¥å½åãã夿³¨ã§éçºããã¦ããã¢ããªã¯UnitTestããªã
1ããã°æ¤ç¥ãæåãã¹ãã«ä¾åãã¦ãã","ãã«ãã¢ã¸ã¥ã¼ã«ã¢ã¼ããã¯ãã£ãå°å
¥ããæ°è¦ã¢ã¸ã¥ã¼ã«ã§ãã¹ãã«ãã¬ãã¸80%以ä¸ãéæ","iOS/Androidã¨ã³ã¸ãã¢4åã¨é£æºããæ©è½éçºãæ¢ããã«æ®µéçãªãªãã¡ã¯ã¿ãªã³ã°ãæ¨é²ãçµæã¨ãã¦ãªãªã¼ã¹å¾ã®ä¸å
·åå ±åãç´40%æ¸å°"]},{"title":"ã³ã©ãå鲿©è½ã®æ°è¦éçº","points":["ãã¼ã½ããªãã£å士ããªã¢ã¼ãã§åé²ã§ãããã³ã©ãåé²ãæ©è½ãè¨è¨ã»éçº","ã¢ã¸ã£ã¤ã«éçºãå°å
¥ããPdMã¨é±æ¬¡ã§ææç©ãã¬ãã¥ã¼ãéçºé䏿®µéã§ãã¼ã½ããªãã£5åã«æ¤è¨¼ååãä¾é ¼ãããã£ã¼ãããã¯ãå
ã«UIãæ¹å","ãªãªã¼ã¹å¾ãæ°ãã«100å以ä¸ã®ãã¼ã½ããªãã£ãã³ã©ãåé²ãå©ç¨ããã¼ã½ããªãã£éã®äº¤æµä¿é²ã¨ã³ã³ãã³ãã®å¤æ§åã«è²¢ç®"]},{"title":"çæ¾éæ©è½ã®éçº","points":["Agoraãæ´»ç¨ãããªã¢ã«ã¿ã¤ã é³å£°é
ä¿¡æ©è½ãiOS/Android両ãã©ãããã©ã¼ã ã§å®è£
","çæ¾éã®ä½æã»éå§ã»äºç´ç»é¢ããã«ã¹ã¯ã©ããã§éçºããé
ä¿¡åãã§ãã¯æ©è½ï¼ãããã¯ã¼ã¯ç¶æ
ã»æ¨©é確èªï¼ãå®è£
","ä½é
å»¶é
ä¿¡ã¨ãªã¹ãã¼åå æ©è½ãå®ç¾ãããã¼ã½ããªãã£ã¨ãªã¹ãã¼ã®åæ¹åã³ãã¥ãã±ã¼ã·ã§ã³ãå¯è½ã«"]},{"title":"PLéå®ã³ã¡ã³ãæ©è½ï¼Androidï¼","points":["ãã¼ã½ããªãã£éå®ã³ã¡ã³ãã®è¡¨ç¤ºã»å¶å¾¡æ©è½ãè¨è¨ã»å®è£
","æ¾é種å¥ã®åå¾ã»å¤å®ãã¸ãã¯ã追å ããé宿©è½ã®åºãåããå®ç¾"]},{"title":"Material3ç§»è¡ï¼Androidåé²ã¢ããªï¼","points":["UIã³ã³ãã¼ãã³ããMaterial3ã«çµ±ä¸ãããã¶ã¤ã³ã·ã¹ãã ã®ä¸è²«æ§ã確ä¿"]},{"title":"ããã¯ã¨ã³ãï¼Goï¼APIéçº","points":["ã³ã©ãå鲿©è½åãã«OpenAPIã§ã»ãã·ã§ã³APIãè¨è¨ã»å®è£
","Agoraãæ´»ç¨ããçæ¾éç¨DBã®æ§ç¯ã¨APIæ´å","ã¨ãã»ã³ã·ã£ã«ã«ã¼ã æ©è½ï¼åå æ¿èªã»æå¦ã»éåºï¼ã®APIéçº"]},{"title":"æ¡ç¨æ´»å","points":["ã¨ã³ã¸ãã¢æ¡ç¨ã®1次é¢è«ãæ
å½ããæè¡åã¨ã«ã«ãã£ã¼ãã£ããã®ä¸¡é¢ããåè£è
ãè©ä¾¡","3åã®æ¡ç¨ã«è²¢ç®ãããã¼ã ã®éçºä½å¶å¼·åã«å¯ä¸"]}],"tech":[{"label":"è¨èª","items":["Swift","Kotlin","Go"]},{"label":"ãã¬ã¼ã ã¯ã¼ã¯","items":["SwiftUI","UIKit","RxSwift","Jetpack Compose"]},{"label":"é³å£°ã»é
ä¿¡","items":["AVFoundation","Agora SDK","ExoPlayer"]},{"label":"ã¢ã¼ããã¯ãã£","items":["ãã«ãã¢ã¸ã¥ã¼ã«","MVVM"]},{"label":"ãã®ä»","items":["XCTest","GitHub Actions"]}]},{"company":"CBCloud","period":"2019/04 - 2021/11","url":"https://cb-cloud.com/","overview":"é
éãããã³ã°ãã©ãããã©ã¼ã ãPickGoãããã³ä¸è¬è²¨ç©ééäºæ¥è
åãSaaSãSmaRyuTruckãã®éçºã«å¾äºãã¢ãã¤ã«ã¨ã³ã¸ãã¢ãããã¼ã ãªã¼ãã¼ã¸ã¨ã¹ãããã¢ããããéçºã¨é¡§å®¢æè¡ã®ä¸¡é¢ã§è²¢ç®ã","highlights":[{"title":"SmaRyuTruckæ°è¦éçºã§ã®ãã¼ã ãªã¼ãã¼å°±ä»»","points":["ã¨ã³ã¸ãã¢ä¸å¿ã®ãã¼ã ã§éä¸ãããã¼ã ãªã¼ãã¼ã«å¿é¡","社é·ããããã¯ããªã¼ãã¼ãåããä¸ãéçºåªå
é ä½ã®èª¿æ´ã¨ã¹ãã¼ã¯ãã«ãã¼éã®æ©æ¸¡ããæ
å½","顧客å
ã¸ç´æ¥åºåããé鿥åã®ç¾å ´èª²é¡ããã¢ãªã³ã°ããã®ç¥è¦ããããã¯ãè¦ä»¶ã«åæ ããããµã¼ãã¹å°å
¥ãæ¨é²","[ä¸è¬è²¨ç©åãé
éä¾é ¼ãã¼ã¸](https://pickgo.town/)ã®æ°è¦ä½æãæ
å½"]},{"title":"PickGoãã¼ã åå»ºã¨æ©è½éçº","points":["ãã¼ã ã¡ã³ãã¼ã®éè·ãç¸æ¬¡ããéçºè
ãèªåä¸äººã¨ãªãç¶æ³ãçµé¨","çæéã§æ¢åã³ã¼ããã¼ã¹ã¨æ¥åããã¼ãææ¡ããéçºãç¶ç¶","[JALèªç©ºä¾¿é£æº](https://press.jal.co.jp/ja/release/202103/005969.html)ãè¦ä»¶å®ç¾©ãããªãªã¼ã¹ã¾ã§ä¸äººã§å®é","å£ç¯å¤åã«å¯¾å¿ããé
éæéã®åç夿´æ©è½ãå®è£
"]},{"title":"æ¡ç¨æ´»å","points":["ã¨ã³ã¸ãã¢æ¡ç¨ã®1次é¢è«ãæ
å½"]}],"deliverables":[{"name":"SmaRyuTruck","url":"https://smaryu.town/truck/","de
1scription":"ä¸è¬è²¨ç©ééäºæ¥è
åãSaaS"},{"name":"PickGo","url":"https://pickgo.town/","description":"é
éãããã³ã°ãã©ãããã©ã¼ã "},{"name":"è²·ãç©ä»£è¡ãµã¼ãã¹","url":"https://pickgo.town/consumer/shopping"}],"tech":[{"label":"ã¢ãã¤ã«","items":["Swift","Kotlin"]},{"label":"ããã³ãã¨ã³ã","items":["Nuxt.js"]},{"label":"ããã¯ã¨ã³ã","items":["Rails"]}]},{"company":"Lifesports","period":"2018/02 - 2019/03","url":"https://lifesports.jp/","overview":"ã¹ãã¼ããããã³ã°ãµã¼ãã¹ã®ã¢ãã¤ã«ã¢ããªéçºã«å¾äºãã¦ã¼ã¶ã¼ç²å¾ã«åããæ©è½æ¹åã¨ã³ãã¥ããã£æ©è½ã®æ°è¦éçºãæ
å½ã","highlights":[{"points":["ã¦ã¼ã¶ã¼æ°å¢å ãç®çã¨ããæ¢åæ©è½ã®æ¹åã¨UI/UXåä¸","ã¹ãã¼ãæå¥½è
å士ãã¤ãªãã³ãã¥ããã£æ©è½ãè¨è¨ã»å®è£
"]}],"tech":[{"label":"ã¢ãã¤ã«","items":["Swift","Kotlin"]},{"label":"ããã¯ã¨ã³ã","items":["Laravel"]}]},{"company":"æ ªå¼ä¼ç¤¾ã¨ã¼ãã¼ã³ãã¥ãã±ã¼ã·ã§ã³ãº","period":"2013/09 - 2018/02","url":"https://www.ap-com.co.jp/","overview":"ãããã¯ã¼ã¯ç³»SIerã«ã¦ãã¤ã³ãã©ããéçºã¾ã§å¹
åºãé åãçµé¨ããããã¯ã¼ã¯ã¨ã³ã¸ãã¢ã¨ãã¦ãã£ãªã¢ãã¹ã¿ã¼ãããéçºé¨éã¸ã®ç°åãçµã¦ãã«ã¹ã¿ãã¯ãªã¹ãã«ãç¿å¾ã","highlights":[{"points":["å½å
大æä¼æ¥åããããã¯ã¼ã¯èªè¨¼ã·ã¹ãã ã®éç¨ã»ä¿å®ãæ
å½","å¤§è¦æ¨¡ã·ã¹ãã ãªãã¬ã¤ã¹ããã¸ã§ã¯ãã«åç»ããã¤ã³ãã©æ§ç¯ããç§»è¡ä½æ¥ã¾ã§ãéè¡","éçºé¨éç°åå¾ãæè²äºæ¥ä¼ç¤¾ã»å¨¯æ¥½äºæ¥ã®ã·ã¹ãã ä¿å®ã»ãªãã¬ã¤ã¹ãæ
å½"]}],"tech":[{"label":"ããã¯ã¨ã³ã","items":["Java (Spring)","PHP (Laravel)"]},{"label":"ãã¼ã¿ãã¼ã¹","items":["MySQL"]},{"label":"ã¤ã³ãã©","items":["ãããã¯ã¼ã¯æ§ç¯ã»éç¨"]}]}],"sideProjects":[{"title":"ishin ã¢ãã¤ã«ã¨ã³ã¸ãã¢","period":"2025/07 - 2026/03","overview":"AIã¢ãã¿ã¼ãåå ã§ããé³å£°ãã¼ã¯ã«ã¼ã ãµã¼ãã¹ãishinãã®éçºã«åå ãã¢ãã¤ã«ã¢ããªã»ããã¯ã¨ã³ãAPIã»Web ã®3é åã«ã¾ããã£ã¦æ©è½éçºãæ
å½ããã","points":["React Nativeï¼Expo SDK 52ï¼ã§ãã¼ã¯ã«ã¼ã åå UIã»æ³¢ç´ã¢ãã¡ã¼ã·ã§ã³ã»AIã¢ãã¿ã¼é¸ææ©è½ãªã©ãå®è£
","AIã¢ãã¿ã¼ã®ããã¸è¡¨ç¤ºã»èªåå¿çããªã¬ã¼ã»ã¡ãã»ã¼ã¸è¡¨ç¤ºãã¥ã¼ã·ã¹ãã ãè¨è¨ã»éçº","ãããã«ï¼ãã©ãã¼ï¼æ©è½ã»ãããã¯æ©è½ãã¢ãã¤ã«ã¨APIã®ä¸¡å´ã§å®è£
","Firebase Analytics / BigQuery飿ºã«ãããã¼ã¯ã«ã¼ã åå ã»ä½æã¤ãã³ãã®ãã©ããã³ã°åºç¤ãæ§ç¯","App Tracking Transparencyï¼ATTï¼å¯¾å¿ã»GIFå§ç¸®ã»EASãã«ããµã¤ãºæé©åãªã©App Storeç³è«å¯¾å¿ãæ
å½","ishin-webï¼Next.jsï¼ã§OGPç»åçæãæé©åããã©ã³ããã£ãã·ã¥ã¨ã¡ã¢ãªãã£ãã·ã¥ã®å°å
¥ã«ããåå11ç§ãã1.75ç§ã¸6.6åé«éåãéæ","Goããã¯ã¨ã³ãAPIã§ãã¼ããã¼ãAPIã»BigQueryåæã»AIã¢ãã¿ã¼ç®¡çãªã©ã®ã¨ã³ããã¤ã³ããéçº"],"tech":["React Native","Expo","TypeScript","Go","Next.js","Firebase","BigQuery","Auth0","EAS"]},{"title":"linq社 iOSã¨ã³ã¸ãã¢","period":"2023/04 - 2024/04","url":"https://linq.co.jp/","siteName":"linq","overview":"ä½ç½®æ
å ±å
±æã¢ããªãwhooãã®iOSéçºã«åç»ã","points":["UIKitããSwiftUIã¸ã®æ®µéçç§»è¡ãæ¨é²","Mapä¸ã§å人ã«ã¹ã¿ã³ããéãæ©è½ãã¡ãã»ã¼ã¸æ©è½ãæ°è¦éçº","ã¦ã¼ã¶ã¼å士ã®äº¤æµãä¿é²ããã¤ã³ã¿ã©ã¯ãã£ããªã¢ãã¡ã¼ã·ã§ã³ãå®è£
"],"tech":["SwiftUI","UIKit","MapKit","CoreLocation","Core Animation"]},{"title":"SOXAI ãã«ã¹ã±ã¢ã¢ããª","period":"2022/11 - 2023/03","url":"https://soxai.co.jp/","siteName":"SOXAI","overview":"ãã«ã¹ã±ã¢ã¢ããªã®ã¢ãã¤ã«éçºã«åç»ã","points":["ãã«ããã©ãããã©ã¼ã ãã¬ã¼ã ã¯ã¼ã¯[Quasar](https://quasar.dev/)ãç¨ããéçº","ãã«ã¹ãã¼ã¿ãå¯è¦åããã°ã©ãç»é¢ã®è¨è¨ã»å®è£
"]},{"title":"nossa360 Androidã¨ã³ã¸ãã¢","period":"2020/04 - 2021/03","url":"https://lp.nossa360biz.com/","siteName":"nossa360","overview":"建ç¯ã»ä¸åç£æ¥çåã360度æ®å½±ã¢ããªãnossa360ãã®Androidç
1éçºãæ
å½ã","points":["Camera2 APIãæ´»ç¨ãã360度æ®å½±æ©è½ãå®è£
","ç»åå¦çã®æé©åã«ããã¢ããªã®ããã©ã¼ãã³ã¹ãåä¸","建ç¯ç¾å ´ã§ã®å©ç¨ã«ç¹åããUI/UXæ¹åã宿½"],"tech":["Kotlin","Camera2 API","ç»åå¦ç"]}],"personalApps":[{"name":"ã·ã³ãã«é²é³ - é³å£°ã¬ã³ã¼ãã¼","tagline":"ã¯ã³ã¿ããã§å§ã¾ãé³å£°ã¬ã³ã¼ãã¼","platform":"iOS / Android","overview":"ã¯ã³ã¿ããã§é²é³ãå§ããããé³å£°ã¬ã³ã¼ãã¼ãããã¯ã°ã©ã¦ã³ãé²é³ããã¬ã¤ãªã¹ããããã¯ç»é¢ã§ã®é²é³æé表示ãªã©ãå®è£
ããè±èªã»æ¥æ¬èªã»ä¸å½èªã»ã¹ãã¤ã³èªãªã©ã®å¤è¨èªã«å¯¾å¿ãã¦ããã","featured":true,"screenshot":"/apps/simple-recorder.webp","metrics":["App Store è©ä¾¡ 4.2 / 229ä»¶","iOSã»Android ã®ä¸¡æ¹ãå人ã§éçºã»éç¨"],"tech":["Swift","SwiftUI","AVFoundation","CloudKit","Kotlin","Android Jetpack","Room","WorkManager"],"links":[{"label":"App Store","url":"https://apps.apple.com/us/app/simple-voice-recorder-audio/id6443528409"},{"label":"Google Play","url":"https://play.google.com/store/apps/details?id=com.entaku.simpleRecord"}]},{"name":"ClipKit - ã³ãã¼å±¥æ´ç®¡ç","tagline":"ã³ãã¼ããå
容ããããã¯ã°ã©ã¦ã³ãã§ãåããã¼ããªã","platform":"iOS","overview":"ã³ãã¼ããå
容ãèªåã§ä¿åããã¯ãªãããã¼ãå±¥æ´ã¢ããªãiOS 16以éã®ããã¯ã°ã©ã¦ã³ãå¶éã Picture in Picture ã§åé¿ãã¦ã¯ãªãããã¼ããç£è¦ãç¶ããä»çµã¿ãèªä½ãããå±¥æ´ã®æ¤ç´¢ã»ãã³çãã»ããã¹ã夿ãã¦ã£ã¸ã§ããã¨ãã¼ãã¼ãæ¡å¼µããã®å¼ã³åºãã«ã対å¿ãã¦ããã","featured":true,"screenshot":"/apps/clipkit.webp","metrics":["App Storeãã¯ãªãããã¼ããæ¤ç´¢ã§3ä½","PiPã使ã£ãããã¯ã°ã©ã¦ã³ãç£è¦ãèªä½","TCA + RevenueCat ã§ãµãã¹ã¯ãªãã·ã§ã³ãå®è£
"],"tech":["Swift","SwiftUI","TCA","AVKit (PiP)","CloudKit","WidgetKit","Keyboard Extension","RevenueCat"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6759832862"}]},{"name":"èªã¿ä¸ããã¬ã¼ã¿ã¼","tagline":"æ¸ããããã¹ããããã®ã¾ã¾å£°ã«ãã","platform":"iOS","overview":"å
¥åããããã¹ããèªã¿ä¸ããé³å£°åæã¢ããªãiOSã®é³å£°ã¾ããã®APIãå®éã®ãããã¯ãã§è©¦ãããã«ä½ãããªãªã¼ã¹å¾ããã£ã¼ãããã¯ãè¦ãªããæ¹åãç¶ãã¦ããã","featured":true,"screenshot":"/apps/narrator.webp","tech":["Swift","SwiftUI","AVFoundation","Speech","Core Audio"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/èªã¿ä¸ããã¬ã¼ã¿ã¼-声ã§èªã¿ä¸ã/id6478449537"}]},{"name":"ã·ã³ãã«æåèµ·ãã","tagline":"é²é³ãä¼è°ã¡ã¢ãããã®å ´ã§ããã¹ãã«","platform":"iOS","overview":"é³å£°ãããã¹ãã«å¤æããæåèµ·ããã¢ããªããªã³ããã¤ã¹ã§é³å£°èªèãè¡ããé²é³ãã¼ã¿ãä¼è°ã¡ã¢ã®æ¸ãèµ·ããã«ä½¿ããã","metrics":["é³å£°èªèããªã³ããã¤ã¹ã§å®è¡ããé³å£°ãå¤é¨ã«éããªã"],"tech":["Swift","SwiftUI","Core ML","Speech","Natural Language"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6504149514"}]},{"name":"Slumber - ç¡ç è¨é²ã»ã¹ãã¼ãã¢ã©ã¼ã ","tagline":"ç ããã¹ã³ã¢ã«ãã¦ãæ°æã¡ããèµ·ãã","platform":"iOS","overview":"ç¡ç ã®è¨é²ã¨åæãè¡ãã¢ããªãæ¥ã®åºæå»ã»ä½åã»ç»é¢ã®æããã®3æ¡ä»¶ããèµ·åºã¿ã¤ãã³ã°ãå¤å®ããã¹ãã¼ãã¢ã©ã¼ã ãå®è£
ããAlarmKitã§ãµã¤ã¬ã³ãã¢ã¼ãã§ãé³´ãããã«ãã¦ãããæ¯æã®ç¡ç ã¹ã³ã¢ã¨é±éã¬ãã¼ããããã¯ç»é¢ã¦ã£ã¸ã§ãããæä¾ããã","metrics":["AlarmKitã§ãµã¤ã¬ã³ãã¢ã¼ãã§ãé³´ãã¢ã©ã¼ã ãå®è£
","CoreMotionã»CoreLocationã»è¼åº¦ã®3æ¡ä»¶ã§èµ·åºã¿ã¤ãã³ã°ãå¤å®"],"tech":["Swift","SwiftUI","AlarmKit","CoreMotion","CoreLocation","HealthKit","WeatherKit","WidgetKit"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6770225144"}]}
1,{"name":"Festory - ãã§ã¹ã»ã©ã¤ã忦è¨é²","tagline":"ã»ããªãã¨æ®ãã忦ã®è¨é²å¸³","platform":"iOS","overview":"ãã§ã¹ãã©ã¤ãã¸ã®åå ãè¨é²ããã¢ããªãã»ãããªã¹ããã¢ã³ã³ã¼ã«ã®è¨é²ãè¡ãããã¤ãã³ãã®ã¦ã£ãã·ã¥ãªã¹ããå½å
主è¦ãã§ã¹ã®ã©ã¤ã³ãããæ
å ±ãæ±ããiOSã¢ããªã«å ãã¦Goã®APIã¨ã©ã³ãã£ã³ã°ãã¼ã¸ãèªåã§ä½ããCloud Run 㨠Vercel ã§éç¨ãã¦ããã","metrics":["iOSã¢ããªã»Go APIã»Webã¾ã§ãä¸äººã§è¨è¨ãã¦éç¨"],"tech":["Swift","SwiftUI","Go","Cloud Run","React","Vite","Firebase"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6763427429"}]}]}')},69065,(e,t,i)=>{t.exports=JSON.parse('{"name":"entaku","role":"Senior iOS Engineer â Video Streaming & Ad Tech","description":"Senior iOS engineer specializing in video streaming and ad monetization. Currently iOS lead at TVer, one of Japan\'s largest free ad-supported streaming services.","githubUsername":"entaku0818","twitterUrl":"https://twitter.com/entaku_0818","twitterId":"@entaku_0818","githubUrl":"https://github.com/entaku0818","siteUrl":"https://entaku.dev/en","summary":["Mobile app engineer writing software since 2013. I started out on infrastructure and web systems at an SIer, then moved my focus to iOS and Android.","iOS lead at TVer, one of Japan\'s largest free ad-supported streaming services. I rebuilt the playback stack with The Composable Architecture, work on the ad integration around it, and supported streaming of the Milano Cortina 2026 Winter Olympics.","At Voicy I brought the recording app in-house from an outsourced team, reaching 80%+ test coverage on new modules and cutting post-release bug reports by roughly 40%.","On my own I ship several apps, including Simple Voice Recorder, Voice Narrator, ClipKit and Festory â along with the Go / Firebase backends and on-device AI behind them.","Four talks at iOSDC Japan (2020â2024). I help organize Swiftæå¥½ä¼ (Swift Lovers) and have volunteered as DroidKaigi staff."],"timeline":[{"period":"2025/01 - Present","title":"TVer","detail":"iOS lead â video playback (TCA) and ad integration"},{"period":"2025 - 2026","title":"New personal apps","detail":"ClipKit, Speedmeter, Slumber and Festory"},{"period":"2021/12 - 2024/12","title":"Voicy","detail":"iOS engineer & team lead â in-housing and re-architecting the recording app"},{"period":"2019/04 - 2021/11","title":"CBCloud","detail":"Mobile engineer â team lead on PickGo / SmaRyuTruck"},{"period":"2018/02 - 2019/03","title":"Lifesports","detail":"Mobile apps for a sports matching service"},{"period":"2013/09 - 2018/02","title":"AP Communications","detail":"Started as a network engineer, then moved into web and business systems"}],"techStack":[{"label":"iOS","items":["Swift","SwiftUI","UIKit","TCA","Combine","CoreData / SwiftData","CloudKit","WidgetKit","Live Activities","App Intents","HealthKit"]},{"label":"Android","items":["Kotlin","Jetpack Compose","Room","WorkManager","ExoPlayer"]},{"label":"Audio & Video","items":["AVFoundation / AVPlayer","Core Audio","Speech","Agora SDK"]},{"label":"Backend","items":["Go","Cloud Run","Firebase Functions","Firestore","Supabase","Rails","Laravel"]},{"label":"AI","items":["Gemini API","Claude API","WhisperKit","MLX Swift","Foundation Models","Claude Code"]},{"label":"CI/CD & Ops","items":["GitHub Actions","fastlane","Xcode Cloud","Crashlytics","RevenueCat","AdMob"]}],"specialties":["Video playback and ad monetization on mobile â player architecture, live and VOD","Audio and live streaming infrastructure","Product-minded engineering â deciding what to build from a business perspective, not only a technical one"],"talks":[{"event":"iOSDC Japan 2024","title":"Core Audio","links":[{"label":"Details","url":"https://fortee.jp/iosdc-japan-2024/proposal/8c6f01d9-8fd3-4d5e-afef-f29d561f3c39"}]},{"event":"iOSDC Japan 2022","title":"Everything behind audio broadcasting on iOS","links":[{"label":"Details","url":"https://fortee.jp/iosdc-japan-2022/proposal/ee2ab807-9053-4779-84f9-ec9951f7cfc0"}]},{"event":"iOSDC Japan 2021","title":"How to replace an existing native app with Flutter","links":[{"label":"Details","url":"https://iosdc.jp/2021/"},{"label":"Speaker Deck","url":"https://speakerdeck.com/entaku/pickgo-for-partnerfalseyi-xing-fang-fa-karaxue-hu-ji-cun-falseneiteihuahuriwoflutterherihureisusurufang-fa"}]},{"event":"iOSDC Japan 2020","title":"Becoming an iOS OSS contributor through the DroidKaigi official app","links":[{"label":"Details","url":"https://fortee.jp/iosdc-japan-2020/proposal/c3c70224-08cf-48d7-b5e5-a3d4589737fa"},{"label":"Speaker Deck","url":"https://speakerdeck.com/entaku/droidkaigifalsegong-shi-ahuriteshi-meru-iosahuriosskomitutahefalsedao"}]},{"event":"Vue.js Architecting Meetup","title":"Understanding Vue / Vuex architecture, completely","links":[{"label":"Details","url":"https://cw-engineers.connpass.com/event/146975/"},{"label":"Speaker Deck","url":"https://speakerdeck.com/entaku/vue-vuex-falseakitekutiyawan-quan-nili-jie-sita"}]}],"communities":[{"name":"Swiftæå¥½ä¼ (Swift Lovers)","role":"Organizer","url":"https://love-swift.connpass.com/","linkLabel":"connpass","description":"Organizer of a Japanese Swift community with 2,200+ engineers, running meetups once or twice a month (98 editions and counting)."},{"name":"DroidKaigi","role":"Staff","url":"https://droidkaigi.jp/","linkLabel":"Website","description":"Staff member of DroidKaigi, the largest Android developer conference in Japan."}],"experiences":[{"company":"TVer","period":"Jan 2025 - Present","url":"https://tver.jp/","overview":"iOS lead engineer at TVer, one of Japan\'s largest free ad-supported streaming services, working on the video playback experience and the ad integration around it.","highlights":[{"title":"Video playback and ad monetization","points":["Work on player features for both live and on-demand streaming, including the ad integration layer around playback","Replaced playback-related code with The Composable Architecture, improving maintainability and testability"]},{"title":"Large-scale live event delivery","points":["Delivered the streaming experience for the Milano Cortina 2026 Winter Olympics, including a dedicated top screen and event UI","Built reusable player modules covering both live and VOD playback under a hard, externally fixed deadline"]},{"title":"CI with Xcode Cloud","points":["Tests existed but there was no CI. Introduced Xcode Cloud so every pull request runs automated tests and build verification","Stabilized the development cycle for the whole iOS team"]},{"title":"Onboarding redesign","points":["Rebuilt the walkthrough flow so new users understand the app immediately"]}],"tech":[{"label":"Language","items":["Swift"]}
1,{"label":"Frameworks","items":["SwiftUI","UIKit","Combine","TCA"]},{"label":"Playback","items":["AVFoundation","AVPlayer"]},{"label":"CI/CD","items":["Xcode Cloud"]}]},{"company":"Voicy","period":"Dec 2021 - Dec 2024","url":"https://voicy.jp/","overview":"iOS engineer and team lead at Voicy, an audio streaming platform. As the owner of the recording app for creators, I led the move from outsourced development to an in-house team, the architecture overhaul, and new feature development.","highlights":[{"title":"In-housing development and rebuilding code quality","points":["The app had been outsourced since the company\'s founding, had no unit tests, and relied on manual QA to catch bugs","Introduced a multi-module architecture and reached 80%+ test coverage on new modules","Drove incremental refactoring with four iOS/Android engineers without pausing feature work, cutting post-release bug reports by about 40%"]},{"title":"Collaborative recording","points":["Designed and built a feature that lets creators record together remotely","Introduced agile practices, reviewing increments weekly with the PdM and running mid-development validation with five creators","100+ creators adopted collaborative recording after launch"]},{"title":"Live broadcasting","points":["Implemented real-time audio broadcasting on both iOS and Android using Agora","Built the creation, start and scheduling screens from scratch, including pre-broadcast checks for network state and permissions","Enabled low-latency delivery and listener participation for two-way communication"]},{"title":"Backend (Go) API development","points":["Designed and implemented the session API for collaborative recording with OpenAPI","Built the live broadcasting database and its APIs around Agora","Developed the APIs for room admission, rejection and exit flows"]},{"title":"Android work","points":["Designed and implemented creator-only comment display and control, including broadcast-type detection","Migrated the Android recording app\'s UI components to Material 3"]},{"title":"Hiring","points":["Ran first-round engineering interviews, assessing both technical skill and culture fit","Contributed to three hires that strengthened the team"]}],"tech":[{"label":"Languages","items":["Swift","Kotlin","Go"]},{"label":"Frameworks","items":["SwiftUI","UIKit","RxSwift","Jetpack Compose"]},{"label":"Audio & streaming","items":["AVFoundation","Agora SDK","ExoPlayer"]},{"label":"Architecture","items":["Multi-module","MVVM"]},{"label":"Other","items":["XCTest","GitHub Actions"]}]},{"company":"CBCloud","period":"Apr 2019 - Nov 2021","url":"https://cb-cloud.com/","overview":"Worked on PickGo, a delivery matching platform, and SmaRyuTruck, a SaaS for freight carriers. Moved from mobile engineer to team lead, contributing on both development and customer-facing work.","highlights":[{"title":"Team lead on the SmaRyuTruck launch","points":["Volunteered to take over as team lead partway through the project","Coordinated development priorities and bridged stakeholders while the CEO acted as product owner","Visited customers directly to understand real logistics operations and fed those findings into product requirements","Built the [freight delivery request page](https://pickgo.town/)"]},{"title":"Rebuilding the PickGo team","points":["After a wave of departures I was the only remaining developer on the product","Got up to speed on the existing codebase and business flows quickly enough to keep shipping","Delivered the [JAL air freight integration](https://press.jal.co.jp/ja/release/202103/005969.html) alone, from requirements to release","Implemented dynamic delivery pricing that responds to seasonal demand"]},{"title":"Hiring","points":["Ran first-round engineering interviews"]}],"deliverables":[{"name":"SmaRyuTruck","url":"https://smaryu.town/truck/","description":"SaaS for freight carriers"},{"name":"PickGo","url":"https://pickgo.town/","description":"Delivery matching platform"},{"name":"Shopping proxy service","url":"https://pickgo.town/consumer/shopping"}],"tech":[{"label":"Mobile","items":["Swift","Kotlin"]},{"label":"Frontend","items":["Nuxt.js"]},{"label":"Backend","items":["Rails"]}]},{"company":"Lifesports","period":"Feb 2018 - Mar 2019","url":"https://lifesports.jp/","overview":"Mobile app development for a sports matching service, focused on feature improvements for user growth and a new community feature.","highlights":[{"points":["Improved existing features and UI/UX to grow the user base","Designed and implemented a community feature connecting sports enthusiasts"]}
1],"tech":[{"label":"Mobile","items":["Swift","Kotlin"]},{"label":"Backend","items":["Laravel"]}]},{"company":"AP Communications","period":"Sep 2013 - Feb 2018","url":"https://www.ap-com.co.jp/","overview":"Started my career at a network-focused SIer, covering everything from infrastructure to application development after moving to the development division.","highlights":[{"points":["Operated and maintained a network authentication system for a major Japanese enterprise","Joined a large-scale system replacement project, handling infrastructure setup through migration","After moving to the development division, maintained and replaced systems for education and entertainment businesses"]}],"tech":[{"label":"Backend","items":["Java (Spring)","PHP (Laravel)"]},{"label":"Database","items":["MySQL"]},{"label":"Infrastructure","items":["Network design & operations"]}]}],"sideProjects":[{"title":"ishin â Mobile Engineer","period":"Jul 2025 - Mar 2026","overview":"Contributed to ishin, a voice talk room service where AI avatars can join conversations. Worked across three areas: the mobile app, the backend API and the web front end.","points":["Built talk room join UI, ripple animations and AI avatar selection in React Native (Expo SDK 52)","Designed AI avatar badges, auto-response triggers and a message display queue system","Implemented follow and block features on both the mobile app and the API","Built event tracking for room joins and creations via Firebase Analytics and BigQuery","Handled App Store submission work: App Tracking Transparency, GIF compression and EAS build size optimization","Optimized OGP image generation in ishin-web (Next.js): 6.6x faster (11s â 1.75s) via font and memory caching","Developed heartbeat, BigQuery sync and AI avatar management endpoints in the Go backend"],"tech":["React Native","Expo","TypeScript","Go","Next.js","Firebase","BigQuery","Auth0","EAS"]},{"title":"linq â iOS Engineer","period":"Apr 2023 - Apr 2024","url":"https://linq.co.jp/","siteName":"linq","overview":"Joined iOS development for whoo, a location sharing app.","points":["Drove the incremental migration from UIKit to SwiftUI","Built new features for sending stamps to friends on the map, and messaging","Implemented interactive animations that encourage user-to-user interaction"],"tech":["SwiftUI","UIKit","MapKit","CoreLocation","Core Animation"]},{"title":"SOXAI Healthcare App","period":"Nov 2022 - Mar 2023","url":"https://soxai.co.jp/","siteName":"SOXAI","overview":"Joined mobile development for a healthcare app.","points":["Developed with [Quasar](https://quasar.dev/), a cross-platform framework","Designed and implemented the graph screens visualizing health data"]},{"title":"nossa360 â Android Engineer","period":"Apr 2020 - Mar 2021","url":"https://lp.nossa360biz.com/","siteName":"nossa360","overview":"Android development for nossa360, a 360-degree camera app for the construction and real estate industries.","points":["Implemented 360-degree capture using the Camera2 API","Improved app performance through image processing optimization","Refined the UI/UX for use on construction sites"],"tech":["Kotlin","Camera2 API","Image processing"]}],"personalApps":[{"name":"Simple Voice Recorder","tagline":"A voice recorder that starts with one tap","platform":"iOS / Android","overview":"A voice recorder built around one-tap recording. It supports background recording, playlists and recording time on the lock screen, and ships in English, Japanese, Chinese and Spanish among others.","featured":true,"screenshot":"/apps/simple-recorder.webp","metrics":["Rated 4.2 from 229 App Store reviews","Both the iOS and Android apps built and maintained solo"],"tech":["Swift","SwiftUI","AVFoundation","CloudKit","Kotlin","Android Jetpack","Room","WorkManager"],"links":[{"label":"App Store","url":"https://apps.apple.com/us/app/simple-voice-recorder-audio/id6443528409"},{"label":"Google Play","url":"https://play.google.com/store/apps/details?id=com.entaku.simpleRecord"}]},{"name":"ClipKit â Clipboard Manager","tagline":"Keeps watching the clipboard, even in the background","platform":"iOS","overview":"A clipboard manager that saves what you copy automatically. To keep watching the clipboard under the background limits introduced in iOS 16, I built the monitoring on top of Picture in Picture. It also covers search, pinning and text conversion, reachable from a widget and a keyboard extension.","featured":true,"screenshot":"/apps/clipkit.webp","metrics":["Ranks 3rd for âclipboardâ on the Japanese App Store","Backgroun
1d monitoring built on Picture in Picture","Subscriptions with TCA and RevenueCat"],"tech":["Swift","SwiftUI","TCA","AVKit (PiP)","CloudKit","WidgetKit","Keyboard Extension","RevenueCat"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6759832862"}]},{"name":"Voice Narrator","tagline":"Turns whatever you type into speech","platform":"iOS","overview":"A text-to-speech app. I built it to try the iOS audio and speech APIs on a real product, and keep improving it based on user feedback.","featured":true,"screenshot":"/apps/narrator.webp","tech":["Swift","SwiftUI","AVFoundation","Speech","Core Audio"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/èªã¿ä¸ããã¬ã¼ã¿ã¼-声ã§èªã¿ä¸ã/id6478449537"}]},{"name":"Simple Transcription","tagline":"Recordings and meeting notes, as text","platform":"iOS","overview":"A transcription app that turns speech into text. Recognition runs on device, which makes it practical for recordings and meeting notes.","metrics":["Speech recognition runs on device, so audio never leaves it"],"tech":["Swift","SwiftUI","Core ML","Speech","Natural Language"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6504149514"}]},{"name":"Slumber â Sleep & Alarm","tagline":"Scores your sleep so you wake up well","platform":"iOS","overview":"A sleep tracking app. Its smart alarm picks a wake-up moment from three signals â sunrise time, body movement and screen brightness â and AlarmKit makes it ring even in silent mode. It reports a sleep score each morning, a weekly trend and a lock screen widget.","metrics":["AlarmKit alarms that ring through silent mode","Wake-up timing from CoreMotion, CoreLocation and screen brightness"],"tech":["Swift","SwiftUI","AlarmKit","CoreMotion","CoreLocation","HealthKit","WeatherKit","WidgetKit"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6770225144"}]},{"name":"Festory â Concert & Setlist Log","tagline":"A log of every festival, setlist included","platform":"iOS","overview":"An app for logging the festivals and concerts you attend, with setlists, encores, a wishlist of upcoming events and lineups for major Japanese festivals. Alongside the iOS app I built the Go API and the landing page, running on Cloud Run and Vercel.","metrics":["iOS app, Go API and web all designed and operated solo"],"tech":["Swift","SwiftUI","Go","Cloud Run","React","Vite","Firebase"],"links":[{"label":"App Store","url":"https://apps.apple.com/jp/app/id6763427429"}]}]}')},69711,1860,64711,e=>{"use strict";var t=e.i(91398);let i={ja:{overview:"æ¦è¦",technicalBackground:"æè¡ç¥æ´",timeline:"年表",specialties:"徿ãªãã¨",talks:"ç»å£æ´",communities:"ã³ãã¥ããã£æ´»å",experience:"è·æ´",sideProjects:"Side Projects",personalApps:"å人éçº",projectOverview:"ããã¸ã§ã¯ãæ¦è¦",achievements:"å®ç¸¾ã»åãçµã¿",deliverables:"ä¸»ãªææç©",tech:"å©ç¨æè¡",website:"Website",personalEyebrow:"About Me",personalTitle:"Personal",articlesTitle:"Articles",articlesCount:e=>`${e}ä»¶`,switchLangLabel:"English",nav:{apps:"å人éçº",about:"ã§ãããã¨",contact:"ãç¸è«",home:"Home",personal:"Personal",articles:"Articles"},hero:{headline:"å°ããã¨ãéå
·ã«ãæ¥å¸¸ãã¨ã³ã¿ã¡ã«ã",stack:"iOS ã» Android ã» Go",lead:"ä¼ç»ããè¨è¨ã»å®è£
ãã¹ãã¢ç³è«ããªãªã¼ã¹å¾ã®éç¨ã¾ã§ãä»äºã§ã¯iOSã®ãªã¼ãã¨ã³ã¸ãã¢ã¨ãã¦ãå人ã§ã¯ãããå
¨é¨ã²ã¨ãã§ãã£ã¦ãã¾ãã",primaryCta:"éçºã®ãç¸è«",secondaryCta:"å人éçºãè¦ã",stats:e=>[{value:e,suffix:"æ¬",label:"é
ä¿¡ä¸ã®å人éçºã¢ããª"},{value:4.2,decimals:1,label:"ã·ã³ãã«é²é³ã® App Store è©ä¾¡ï¼229ä»¶ï¼"},{value:10,suffix:"å¹´+",label:"ã½ããã¦ã§ã¢éçºæ´"}]}
1,apps:{eyebrow:"Personal Apps",title:"å人éçº",lead:"ä»äºã¨ã¯å¥ã«ãèªåã§ä¼ç»ã㦠App Store / Google Play ã«åºãã¦ããã¢ããªã§ãã",unreleased:"æªé
ä¿¡",highlights:"è¦ã©ãã",placeholder:"ã¹ãã¢æªé
ä¿¡"},about:{eyebrow:"About",title:"ã§ãããã¨"},more:{eyebrow:"More",title:"ããã¾ã§ã®ä»äº",lead:"è·æ´ã»ç»å£ã»ã³ãã¥ããã£æ´»åã¯ãè¦ãããã®ã ãéãã¦ãã ããã"},contact:{eyebrow:"Contact",title:"éçºã®ãç¸è«",lead:"iOS / Android ã¢ããªã®æ°è¦éçºãæ¢åã¢ããªã®æ¹åãæè¡ç¸è«ãªã©ãã¾ãã¯ãã£ããããå
å®¹ã§æ§ãã¾ããã",name:"ãåå",namePlaceholder:"å±±ç° å¤ªé",email:"é£çµ¡å
ã¡ã¼ã«ã¢ãã¬ã¹",emailPlaceholder:"[email protected]",budget:"ãäºç®æ",budgetPlaceholder:"æªå® / ã50ä¸å / 50ã150ä¸å ãªã©",message:"ãç¸è«å
容",messagePlaceholder:"ã¤ãããããã®ãç¾å¨ã®ç¶æ³ã叿ã¹ã±ã¸ã¥ã¼ã«ãªã©ããæ¸ããã ããã",required:"å¿
é ",optional:"ä»»æ",submit:"éä¿¡ãã",submitting:"éä¿¡ä¸â¦",success:"éä¿¡ãã¾ããããããã¨ããããã¾ãã",successDetail:"2å¶æ¥æ¥ä»¥å
ã«ãè¿ä¿¡ãã¾ãã",invalid:"å
¥åå
容ãã確èªãã ããã",error:"éä¿¡ã«å¤±æãã¾ãããæéãããã¦ããä¸åº¦ã試ããã ããã",notConfigured:"ãã ãã¾ãã©ã¼ã ããã®éä¿¡ãæºåä¸ã§ãããææ°ã§ãã X ã¾ã㯠GitHub ãããé£çµ¡ãã ããã",rateLimited:"çæéã«éä¿¡ãç¶ãã¦ãã¾ãããã°ããæéãããã¦ããã試ããã ããã",privacy:"ããã ããå
容ã¯ããç¸è«ã¸ã®è¿ä¿¡ã«ã®ã¿å©ç¨ãã¾ãã",honeypot:"ãã®æ¬ã¯å
¥åããªãã§ãã ãã",fieldError:e=>({required:"å
¥åãã¦ãã ããã",invalid_email:"ã¡ã¼ã«ã¢ãã¬ã¹ã®å½¢å¼ã§å
¥åãã¦ãã ããã",too_long:"æåæ°ãå¤ããã¾ãã"})[e]},footerNote:"ã¢ãã¤ã«ã¢ããªéçºã®ãç¸è«ã¯ãã¤ã§ãã©ããã"},en:{overview:"Overview",technicalBackground:"Tech stack",timeline:"Timeline",specialties:"What I do best",talks:"Talks",communities:"Community",experience:"Experience",sideProjects:"Side Projects",personalApps:"Personal Ap
1ps",projectOverview:"Project overview",achievements:"Highlights",deliverables:"Deliverables",tech:"Tech stack",website:"Website",personalEyebrow:"About Me",personalTitle:"Personal",articlesTitle:"Articles",articlesCount:e=>`${e} articles`,articlesNote:"The posts themselves are written in Japanese.",switchLangLabel:"æ¥æ¬èª",nav:{apps:"Apps",about:"About",contact:"Contact",home:"Home",personal:"Personal",articles:"Articles"},hero:{headline:"Problems into tools. Days into entertainment.",stack:"iOS · Android · Go",lead:"From the first idea through architecture, implementation, App Store review and everything that comes after release. I lead iOS by day and do all of it myself on the side.",primaryCta:"Start a project",secondaryCta:"See the apps",stats:e=>[{value:e,label:"Personal apps on the stores"},{value:4.2,decimals:1,label:"App Store rating, Simple Voice Recorder (229 reviews)"},{value:10,suffix:"+",label:"Years building software"}]},apps:{eyebrow:"Personal Apps",title:"Apps I ship",lead:"Apps I design and publish to the App Store and Google Play on my own, outside of work.",unreleased:"Not published",highlights:"Highlights",placeholder:"Not on the store"},about:{eyebrow:"About",title:"What I can do for you"},more:{eyebrow:"More",title:"Work so far",lead:"Experience, talks and community work â open whichever you want to read."},contact:{eyebrow:"Contact",title:"Start a project",lead:"New iOS or Android apps, improving an app you already have, or just a technical question. A rough outline is enough to start.",name:"Your name",namePlaceholder:"Jane Doe",email:"Email",emailPlaceholder:"[email protected]",budget:"Budget",budgetPlaceholder:"Not decided / under $5k / $5kâ15k â¦",message:"What would you like to build?",messagePlaceholder:"Tell me what you have in mind, where the project stands today and the timeline you are hoping for.",required:"Required",optional:"Optional",submit:"Send",submitting:"Sendingâ¦",success:"Thanks â your message is on its way.",successDetail:"I'll get back to you within two business days.",invalid:"Please check the fields above.",error:"Sending failed. Please try again in a moment.",notConfigured:"The form is not accepting messages yet. Please reach me on X or GitHub in the meantime.",rateLimited:"Too many messages in a row. Please try again a bit later.",privacy:"I use what you send only to reply to your enquiry.",honeypot:"Leave this field empty",fieldError:e=>({required:"This field is required.",invalid_email:"Please enter a valid email address.",too_long:"This is too long."})[e]},footerNote:"Always happy to talk about a mobile app."}};e.s(["default",0,i],1860);var r=e.i(91788);let n="text-sm text-muted hover:text-ink transition-colors",a=(e,t)=>"en"===e?`/en${t}`:t||"/";e.s(["default",0,({lang:e="ja",path:o="",sections:s=[],ctaHref:l,ctaLabel:c})=>{let u=i[e],p="ja"===e?"en":"ja",d=(e=>{let[t,i]=(0,r.useState)(null),n=e.join(",");return(0,r.useEffect)(()=>{if("u"<typeof IntersectionObserver)return;let e=n.split(",").map(e=>document.getElementById(e)).filter(e=>null!==e);if(0===e.length)return;let t=new Set,r=new IntersectionObserver(r=>{for(let e of r)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);let n=e.find(e=>t.has(e.id));i(n?.id??null)},{rootMargin:"-45% 0px -45% 0px"});for(let t of e)r.observe(t);return()=>r.disconnect()},[n]),t})(s.map(e=>e.id)),m=((e=12)=>{let[t,i]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{let t=()=>i(window.scrollY>e);return t(),window.addEventListener("scroll",t,{passive:!0}),()=>window.removeEventListener("scroll",t)},[e]),t})();return(0,t.jsx)("header",{className:`fixed top-0 z-50 w-full transition-all duration-300 ${m?"border-b border-hairline/70 bg-white/80 py-2.5 backdrop-blur-xl":"border-b border-transparent bg-white/70 py-4 backdrop-blur-xl"}`,children:(0,t.jsxs)("div",{className:"container mx-auto flex items-center gap-4 px-6",children:[(0,t.jsx)("a",{href:a(e,""),className:"text-base font-semibold tracking-[0.18em] text-ink transition-colors hover:text-accent",children:"ENTAKU"}),(0,t.jsxs)("nav",{className:"ml-auto hidden items-center gap-7 md:flex",children:[s.map(e=>(0,t.jsxs)("a",{href:`#${e.id}`,"aria-current":d===e.id?"true":void 0,className:`relative text-sm transition-colors ${d===e.id?"font-medium text-ink":"text-muted hover:text-ink"}`,children:[e.label,(0,t.jsx)("span",{"aria-hidden":"true",className:`absolute -bottom-2 left-0 h-px bg-ink transition-all duration-300 ${d===e.id?"w-full":"w-0"}`})]},e.id)),s.length>0&&(0,t.jsx)("span",{"aria-hidden":"true",className:"h-3.5 w-px bg-hairline"}),(0,t.jsx)("a",{href:a(e,"/personal"),className:n,children:u.nav.personal}),(0,t.jsx)("a",{href:a(e,"/articles"),className:n,children:u.nav.articles}),(0,t.jsx)("a",{href:a(p,o),className:"text-sm text-accent transition-colors hover:text-accent-hover",children:u.switchLangLabel})]}),(0,t.jsxs)("div",{className:"ml-auto flex items-center gap-3 md:ml-0 md:hidden",children:[!l&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("a",{href:a(e,"/personal"),className:"text-xs text-muted transition-colors hover:text-ink",children:u.nav.personal}),(0,t.jsx)("a",{href:a(e,"/articles"),className:"text-xs text-muted transition-colors hover:text-ink",children:u.nav.articles})]}),(0,t.jsx)("a",{href:a(p,o),className:"text-xs text-accent transition-colors hover:text-accent-hover",children:u.switchLangLabel}),l&&c&&(0,t.jsx)("a",{href:l,className:"rounded-full bg-accent px-4 py-1.5 text-xs font-medium text-white transition-colors hover:bg-accent-hover",children:c})]}),l&&c&&(0,t.jsx)("a",{href:l,className:"hidden rounded-full bg-accent px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-accent-hover md:inline-block",children:c})]})})}],69711);var o=e.i(12117),s=e.i(69065);let l=o.default,c=s.default;e.s(["featuredApps",0,e=>e.personalApps.filter(e=>e.featured),"profiles",0,{ja:l,en:c}],64711)}]);
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.