-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdb.json
1 lines (1 loc) · 118 KB
/
db.json
1
{"meta":{"version":1,"warehouse":"5.0.1"},"models":{"Asset":[{"_id":"node_modules/hexo-theme-icarus/source/css/cyberpunk.styl","path":"css/cyberpunk.styl","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/favicon.png","path":"img/favicon.png","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/css/default.styl","path":"css/default.styl","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/css/night.styl","path":"css/night.styl","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/css/style.styl","path":"css/style.styl","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/logo.png","path":"img/logo.png","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/me.MP.jpg","path":"img/me.MP.jpg","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/og_image.png","path":"img/og_image.png","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/razor-bottom-black.svg","path":"img/razor-bottom-black.svg","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/razor-top-black.svg","path":"img/razor-top-black.svg","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/js/animation.js","path":"js/animation.js","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/js/back_to_top.js","path":"js/back_to_top.js","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/js/column.js","path":"js/column.js","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/js/main.js","path":"js/main.js","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/js/pjax.js","path":"js/pjax.js","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/js/imaegoo/night.js","path":"js/imaegoo/night.js","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/js/imaegoo/universe.js","path":"js/imaegoo/universe.js","modified":0,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Bio-Large.jpg","path":"img/author_images/Lei-Bio-Large.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Bio-Medium.jpg","path":"img/author_images/Lei-Bio-Medium.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Bio.jpg","path":"img/author_images/Lei-Bio.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Smoky_Mountain.JPG","path":"img/author_images/Lei-Smoky_Mountain.JPG","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei.jpg","path":"img/author_images/Lei.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei_Raw.jpg","path":"img/author_images/Lei_Raw.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Optimized-Lei-Smoky_Mountain.JPG","path":"img/author_images/Optimized-Lei-Smoky_Mountain.JPG","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Optimized-website_teaser.jpg","path":"img/author_images/Optimized-website_teaser.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/leimao_chinese.png","path":"img/author_images/leimao_chinese.png","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/tiny_website_teaser.jpg","path":"img/author_images/tiny_website_teaser.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/leimao_chinese_cropped.png","path":"img/author_images/leimao_chinese_cropped.png","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/website_teaser.jpg","path":"img/author_images/website_teaser.jpg","modified":1,"renderable":1},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/website_teaser_2.jpg","path":"img/author_images/website_teaser_2.jpg","modified":1,"renderable":1}],"Cache":[{"_id":"source/_posts/posix.md","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735436566152},{"_id":"source/_posts/extending_autodoc.rst","hash":"d9d65a6f9fa62f23aa9f215d1c4308b927884ecd","modified":1723609564179},{"_id":"source/_posts/craftsman_guide.md","hash":"cacd2b40aa2ec3fdcdf9e59b64c669fe7ee845ab","modified":1735818622466},{"_id":"source/_posts/hello-world.md","hash":"6d32d528cf04cc2d4a78909c54d86d0ea7165275","modified":1735818622467},{"_id":"source/_posts/lua.md","hash":"e37406540dbe5d4ed3a45ff8abbaab73efaa3dc3","modified":1734352777252},{"_id":"source/_posts/rejection.md","hash":"0b1e4be5fb7209d33fa9c77d43aee7a566c109c3","modified":1735820597246},{"_id":"source/_posts/npm_install.md","hash":"d36ac0ffe3d7e5a1082ac8773f703d6b00c3b201","modified":1735818622467},{"_id":"source/_posts/semaphores.md","hash":"cb0c52e434d151ab83b8fcf31b14284eff01ad61","modified":1735818622469},{"_id":"node_modules/hexo-theme-icarus/layout/misc/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439706},{"_id":"node_modules/hexo-theme-icarus/layout/donate/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439705},{"_id":"node_modules/hexo-theme-icarus/layout/comment/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439704},{"_id":"node_modules/hexo-theme-icarus/layout/share/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439708},{"_id":"node_modules/hexo-theme-icarus/layout/search/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439707},{"_id":"node_modules/hexo-theme-icarus/include/schema/donate/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439699},{"_id":"node_modules/hexo-theme-icarus/include/schema/comment/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439697},{"_id":"node_modules/hexo-theme-icarus/include/schema/misc/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439700},{"_id":"node_modules/hexo-theme-icarus/include/schema/share/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439702},{"_id":"node_modules/hexo-theme-icarus/include/schema/search/.gitkeep","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1735820439701},{"_id":"node_modules/hexo-theme-icarus/package.json","hash":"f5bf0acf4fee3b57046e0be507d2d324e2b8805f","modified":1735820439815},{"_id":"node_modules/hexo-theme-icarus/LICENSE","hash":"86037e5335a49321fa73b7815cab542057fac944","modified":1735820439709},{"_id":"node_modules/hexo-theme-icarus/CONTRIBUTING.md","hash":"70254c6778c1e41bb2ff222bbf3a70b2239b9bc1","modified":1735820439853},{"_id":"node_modules/hexo-theme-icarus/README.md","hash":"32f9f4fc8cd7ec60b30544bd2e558b593519ae5d","modified":1735820439854},{"_id":"node_modules/hexo-theme-icarus/include/dependency.js","hash":"e02471f80db87db43aa7d527176e195b60dc4b99","modified":1735820439774},{"_id":"node_modules/hexo-theme-icarus/include/config.js","hash":"4b8a3096137e0d879fb17972a69630bde38d8212","modified":1735820439773},{"_id":"node_modules/hexo-theme-icarus/include/register.js","hash":"040fed1d0d7e4d8003446d1541bc15a2c4b4e500","modified":1735820439780},{"_id":"node_modules/hexo-theme-icarus/layout/archive.jsx","hash":"daf8eca64197709a9dc4a4792c403a32d78bdfae","modified":1735820439829},{"_id":"node_modules/hexo-theme-icarus/layout/category.jsx","hash":"06bca1e38dda8df4574cc74c6848107c818cc5aa","modified":1735821313350},{"_id":"node_modules/hexo-theme-icarus/layout/layout.jsx","hash":"7a84dee4a63784420c1d3b5bc38258c936e7aff1","modified":1735821702776},{"_id":"node_modules/hexo-theme-icarus/layout/categories.jsx","hash":"b8ad43e28a4990d222bfbb95b032f88555492347","modified":1735820439832},{"_id":"node_modules/hexo-theme-icarus/layout/index.jsx","hash":"0a84a2348394fa9fc5080dd396bd28d357594f47","modified":1735820439834},{"_id":"node_modules/hexo-theme-icarus/layout/page.jsx","hash":"d26c2db57e5a88d6483a03aeb51cda9d191d8cea","modified":1735820439836},{"_id":"node_modules/hexo-theme-icarus/layout/post.jsx","hash":"d26c2db57e5a88d6483a03aeb51cda9d191d8cea","modified":1735820439837},{"_id":"node_modules/hexo-theme-icarus/layout/tag.jsx","hash":"a9a08c9f3eec8994d37149d1ab19f2b5b8f4cd2f","modified":1735820439842},{"_id":"node_modules/hexo-theme-icarus/languages/de.yml","hash":"78421f09961ca0b24756a0688fb2cb2e2696e25f","modified":1735820439914},{"_id":"node_modules/hexo-theme-icarus/layout/tags.jsx","hash":"2c42cb64778235dd220c563a27a92108ddc50cc4","modified":1735820439851},{"_id":"node_modules/hexo-theme-icarus/languages/en.yml","hash":"3d674204d9f723c829226da745afddd180c1131d","modified":1735820439914},{"_id":"node_modules/hexo-theme-icarus/languages/fr.yml","hash":"b992b68705f5050a99de926525b3cb40d95c4769","modified":1735820439916},{"_id":"node_modules/hexo-theme-icarus/languages/es.yml","hash":"38579b8fad4b6997362acc770615bcd85ff20f68","modified":1735820439915},{"_id":"node_modules/hexo-theme-icarus/languages/id.yml","hash":"5e48b1d62378cadeb64b88349477726a5c1bae47","modified":1735820439916},{"_id":"node_modules/hexo-theme-icarus/languages/it.yml","hash":"b76999994cda6b08b53d34c3dd67947f164de655","modified":1735820439917},{"_id":"node_modules/hexo-theme-icarus/languages/ko.yml","hash":"e3374265377809c1518114cf352b595840c0b416","modified":1735820439918},{"_id":"node_modules/hexo-theme-icarus/languages/ja.yml","hash":"801d9930fef48d6a3f80470d5bed4f3eb78147e6","modified":1735820439917},{"_id":"node_modules/hexo-theme-icarus/languages/pl.yml","hash":"2e7debb44cd91096f30efc87bf8d6b1d0d0214c9","modified":1735820439919},{"_id":"node_modules/hexo-theme-icarus/languages/pt-BR.yml","hash":"ee8f73350e4c6e2f63b7fc72b34472a6b1e21244","modified":1735820439921},{"_id":"node_modules/hexo-theme-icarus/languages/ru.yml","hash":"9d91358c2acbe7a0f2a25daf7f65b999ff32d068","modified":1735820439922},{"_id":"node_modules/hexo-theme-icarus/languages/tk.yml","hash":"ca583168bd2025124a1cd0e977da475d7a7496fd","modified":1735820439925},{"_id":"node_modules/hexo-theme-icarus/languages/tr.yml","hash":"dd0a7bfe14848d6e1aa229198fe1db03e08e305e","modified":1735820439926},{"_id":"node_modules/hexo-theme-icarus/languages/vn.yml","hash":"5f2fffa642110c81d8f529949711c9d19ad6bbbe","modified":1735820439939},{"_id":"node_modules/hexo-theme-icarus/scripts/index.js","hash":"93a79969c7eb47cfac097893cda36368db56902c","modified":1735820439777},{"_id":"node_modules/hexo-theme-icarus/languages/zh-TW.yml","hash":"a6826e0c8cdb9ad286324b682b466a9e2ad78e6f","modified":1735820439948},{"_id":"node_modules/hexo-theme-icarus/languages/sv.yml","hash":"b12eee168c52aac855ffce9f78fe5fd5d6e3970c","modified":1735820439923},{"_id":"node_modules/hexo-theme-icarus/include/migration/v2_v3.js","hash":"a46da71c20fa9d73c1bac26fda77717abae1b308","modified":1735820439781},{"_id":"node_modules/hexo-theme-icarus/include/migration/head.js","hash":"7189efe33d18927d3790e8afb06642fb293b8603","modified":1735820439775},{"_id":"node_modules/hexo-theme-icarus/include/migration/v5_v5.1.js","hash":"073f22bd16e34b56f016633b1676dab2e7d8843d","modified":1735820439782},{"_id":"node_modules/hexo-theme-icarus/languages/zh-CN.yml","hash":"02475ba14afc70dfeaf5678467cee307835e4efa","modified":1735820439939},{"_id":"node_modules/hexo-theme-icarus/include/migration/v4_v5.js","hash":"6342310892d113763b5544789b45d44c0ccf2854","modified":1735820439781},{"_id":"node_modules/hexo-theme-icarus/include/migration/v3_v4.js","hash":"9faf2184d7fe87debfbe007f3fc9079dcbcafcfe","modified":1735820439781},{"_id":"node_modules/hexo-theme-icarus/include/util/console.js","hash":"59cf9d277d3ac85a496689bd811b1c316001641d","modified":1735820439773},{"_id":"node_modules/hexo-theme-icarus/include/schema/config.json","hash":"3186ad55b3b4592abac10252ce383c275d878700","modified":1735820439805},{"_id":"node_modules/hexo-theme-icarus/include/style/article.styl","hash":"df75fd5e20b0d241d051b3a430719888a4c87420","modified":1735821313379},{"_id":"node_modules/hexo-theme-icarus/include/style/card.styl","hash":"e184afb74bccd0c6c97ff26552bd1b23f391de3a","modified":1735821313381},{"_id":"node_modules/hexo-theme-icarus/include/style/base.styl","hash":"ecc29661089b4bf5900784c415995f97d2533c7c","modified":1735821313380},{"_id":"node_modules/hexo-theme-icarus/include/style/button.styl","hash":"0fb35b4786be1b387c751fa2849bc71523fcedd4","modified":1735820439898},{"_id":"node_modules/hexo-theme-icarus/include/style/donate.styl","hash":"8d0af00628c13134b5f30a558608e7bebf18c2ec","modified":1735820439902},{"_id":"node_modules/hexo-theme-icarus/include/style/footer.styl","hash":"a4ad715dee38b249538ac6cce94efc9b355a904b","modified":1735820439903},{"_id":"node_modules/hexo-theme-icarus/include/style/helper.styl","hash":"1293ff35ffa8e5a2116b1acf771a77d598e68a6a","modified":1735821313384},{"_id":"node_modules/hexo-theme-icarus/include/style/codeblock.styl","hash":"ec54dc24eb4d9802d8fefc44c210558bc1641109","modified":1735820439900},{"_id":"node_modules/hexo-theme-icarus/include/style/navbar.styl","hash":"867c1dbe859a7b68ec293c812f5a09227bec6a10","modified":1735821313385},{"_id":"node_modules/hexo-theme-icarus/include/style/plugin.styl","hash":"b1022893278a25b928ce78ecd85be5d4a510bb6b","modified":1735821313387},{"_id":"node_modules/hexo-theme-icarus/include/style/pagination.styl","hash":"b81bcd7ff915b4e9299533addc01bc4575ec35e3","modified":1735820439907},{"_id":"node_modules/hexo-theme-icarus/include/style/search.styl","hash":"416737e1da4e7e907bd03609b0fee9e2aacfe56c","modified":1735820439909},{"_id":"node_modules/hexo-theme-icarus/include/style/responsive.styl","hash":"8aa466b17165e6a61ce840d18bda295e950b7bb2","modified":1735821313387},{"_id":"node_modules/hexo-theme-icarus/include/style/widget.styl","hash":"f0c33c2cbc9207ac8db3c2d6f796e96c2483fce6","modified":1735821313391},{"_id":"node_modules/hexo-theme-icarus/include/style/timeline.styl","hash":"ea61798a09bffdda07efb93c2ff800b63bddc4c4","modified":1735820439910},{"_id":"node_modules/hexo-theme-icarus/layout/common/article.jsx","hash":"49220889c2a0eee63ae20fc5df1f36eab8554d89","modified":1735821313348},{"_id":"node_modules/hexo-theme-icarus/layout/common/footer.jsx","hash":"59ec3829b84fd1a6a4ec452acde9472c874aba6b","modified":1735820439833},{"_id":"node_modules/hexo-theme-icarus/layout/common/comment.jsx","hash":"76ee7c6687e96e6262985323665d6273a37e54c5","modified":1735820439832},{"_id":"node_modules/hexo-theme-icarus/layout/common/donates.jsx","hash":"297e4e21769e7fa1319bff259f582cbf9e17d2f6","modified":1735821313351},{"_id":"node_modules/hexo-theme-icarus/layout/common/head.jsx","hash":"f8c3d0dd46cb249412876336d5c4f49412e912b4","modified":1735821313353},{"_id":"node_modules/hexo-theme-icarus/layout/common/plugins.jsx","hash":"2e27800b2a8a87112c96778db858c3419d890b79","modified":1735820439837},{"_id":"node_modules/hexo-theme-icarus/layout/common/navbar.jsx","hash":"3e6914991b4332bb0a164cae5bf53b7962008acc","modified":1735820439836},{"_id":"node_modules/hexo-theme-icarus/layout/common/search.jsx","hash":"1409627d98a92b4f5b2ab829f8e6b50b75d60e53","modified":1735820439839},{"_id":"node_modules/hexo-theme-icarus/layout/common/widgets.jsx","hash":"eaf32a6f51cdaaac66e8772c1515e2dbc085ef7b","modified":1735821313360},{"_id":"node_modules/hexo-theme-icarus/layout/common/scripts.jsx","hash":"5d07312406b401e8d4e9584b4d41ed7377993935","modified":1735820439838},{"_id":"node_modules/hexo-theme-icarus/layout/plugin/animejs.jsx","hash":"e2aa27c3501a58ef1e91e511557b77395c2c02aa","modified":1735820439828},{"_id":"node_modules/hexo-theme-icarus/layout/common/share.jsx","hash":"0fad6f8a91bb5cf678b9ff2d66d2162d61625074","modified":1735820439841},{"_id":"node_modules/hexo-theme-icarus/layout/plugin/back_to_top.jsx","hash":"f86a0bae3a92bc07bd674f03a046fb1b6c1b48af","modified":1735820439831},{"_id":"node_modules/hexo-theme-icarus/layout/widget/archives.jsx","hash":"458352029b6dab692b909db689e3d579f20b0bdf","modified":1735820439830},{"_id":"node_modules/hexo-theme-icarus/layout/plugin/pjax.jsx","hash":"65956102d5faabcedaaafb14b0201548f15e60ce","modified":1735820439836},{"_id":"node_modules/hexo-theme-icarus/layout/widget/categories.jsx","hash":"93ed6963c6df21b11bdcbfc49d59d2163c6456bf","modified":1735820439832},{"_id":"node_modules/hexo-theme-icarus/layout/widget/tags.jsx","hash":"e4229bc66b80d5565c4af3c4be5a5b5fa9e835d9","modified":1735820439851},{"_id":"node_modules/hexo-theme-icarus/source/css/cyberpunk.styl","hash":"1dc053f599e0dca26fa30adb49d332dc46c42398","modified":1735821313382},{"_id":"node_modules/hexo-theme-icarus/layout/widget/profile.jsx","hash":"30b1e2fddebf735d3377a40e3e68902c9c240ea0","modified":1735821313357},{"_id":"node_modules/hexo-theme-icarus/source/css/default.styl","hash":"b01da3028e5a1267a40aaae5c86a11187a2259e3","modified":1735820439902},{"_id":"node_modules/hexo-theme-icarus/source/img/favicon.png","hash":"cad785cdc11fcdd88afb1ae19cb001543f3bf3f5","modified":1735820439854},{"_id":"node_modules/hexo-theme-icarus/source/css/night.styl","hash":"261d3208183dc387c0ee2627ea0fd7b0eb417b4d","modified":1735820439906},{"_id":"node_modules/hexo-theme-icarus/source/css/style.styl","hash":"efd5bdae679ec0bc6555d70d17b8770ae11b98a4","modified":1735820439910},{"_id":"node_modules/hexo-theme-icarus/source/img/razor-top-black.svg","hash":"201f1171a43ce667a39091fe47c0f278857f18f0","modified":1735820439913},{"_id":"node_modules/hexo-theme-icarus/source/img/razor-bottom-black.svg","hash":"a3eda07b1c605b456da9cdf335a1075db5e5d72c","modified":1735820439912},{"_id":"node_modules/hexo-theme-icarus/source/img/og_image.png","hash":"b03f163096ca9c350ec962feee9836277b5c2509","modified":1735820439861},{"_id":"node_modules/hexo-theme-icarus/source/js/main.js","hash":"bb33f2467141afc2a5fad35b553e90782e2bcacd","modified":1735821313315},{"_id":"node_modules/hexo-theme-icarus/source/js/animation.js","hash":"e91b4ddf4ac788a3de8fcab4c8bb75f8c3e0bbd8","modified":1735821313309},{"_id":"node_modules/hexo-theme-icarus/source/js/back_to_top.js","hash":"d91f10c08c726135a13dfa1f422c49d8764ef03f","modified":1735820439771},{"_id":"node_modules/hexo-theme-icarus/source/js/column.js","hash":"0baee024ab67474c073a4c41b495f3e7f0df4505","modified":1735820439772},{"_id":"node_modules/hexo-theme-icarus/source/js/pjax.js","hash":"1c9921d4bd07795adc1d01a12c0fddf7d1124ca2","modified":1735820439779},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/comment.json","hash":"265120b80df9808358df3ff7c4eada8a66512a4b","modified":1735820439803},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/donates.json","hash":"ae86e6f177bedf4afbe638502c12635027539305","modified":1735820439806},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/article.json","hash":"e2502c39045c6a26ccd8e880858f93e78c7bda35","modified":1735820439798},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/footer.json","hash":"e85c9d7f2579805beb252a1b6345d5a668a13baa","modified":1735820439810},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/head.json","hash":"98889f059c635e6bdbd51effd04cf1cf44968a66","modified":1735820439813},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/navbar.json","hash":"6691e587284c4cf450e0288680d5ff0f3565f090","modified":1735820439814},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/search.json","hash":"985fbcbf47054af714ead1a124869d54f2a8b607","modified":1735820439824},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/providers.json","hash":"97ec953d497fb53594227ae98acaef8a8baa91da","modified":1735820439823},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/plugins.json","hash":"04c0738dc0a3ed89aecae2aee4ab60173f09e66b","modified":1735820439818},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/sidebar.json","hash":"eb241beaec4c73e3085dfb3139ce72e827e20549","modified":1735820439827},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/widgets.json","hash":"cadd9dc942740ecd5037d3943e72f8b6a8399bbe","modified":1735820439827},{"_id":"node_modules/hexo-theme-icarus/include/schema/common/share.json","hash":"cf4f9ff4fb27c3541b35f57db355c228fa6873e4","modified":1735820439825},{"_id":"node_modules/hexo-theme-icarus/include/schema/plugin/animejs.json","hash":"e62ab6e20bd8862efa1ed32e7c0db0f8acbcfdec","modified":1735820439795},{"_id":"node_modules/hexo-theme-icarus/include/schema/plugin/pjax.json","hash":"1f6218016569eb9cd354a06a9537c7110efb5f17","modified":1735820439816},{"_id":"node_modules/hexo-theme-icarus/include/schema/widget/profile.json","hash":"690ee1b0791cab47ea03cf42b5b4932ed2aa5675","modified":1735820439823},{"_id":"node_modules/hexo-theme-icarus/include/schema/plugin/back_to_top.json","hash":"dc0febab7e7b67075d0ad3f80f5ec8b798b68dea","modified":1735820439798},{"_id":"node_modules/hexo-theme-icarus/source/js/imaegoo/night.js","hash":"ee9267b31315bd80a58a80cda99b1e4d0d49d0f9","modified":1735820439779},{"_id":"node_modules/hexo-theme-icarus/source/js/imaegoo/universe.js","hash":"8dc3bd0b57cd84f01943a9992ebd11b3649340df","modified":1735820439780},{"_id":"node_modules/hexo-theme-icarus/source/img/logo.png","hash":"d40e9a4a865f1358e98b49554f33b73378197f71","modified":1735820439858},{"_id":"node_modules/hexo-theme-icarus/source/img/me.MP.jpg","hash":"09ab0abf391a1db046feace08f3e8ea6c93c8368","modified":1735820439767},{"_id":"public/js/algolia.js","hash":"a8df0c0abeeb4ee1d2d720161f3aea7339380704","modified":1735820455767},{"_id":"public/js/google_cse.js","hash":"1a9881669dfdeb2b3214074eee0d3e01e52db2c4","modified":1735820455767},{"_id":"public/js/insight.js","hash":"86bbdb7305d9bf19ad62d2ca2cf169fc8d9f9d31","modified":1735820455767},{"_id":"public/js/toc.js","hash":"da6fb757a1b083b8ed138bf29aad3a7bf8ec4f11","modified":1735820455767},{"_id":"public/content.json","hash":"a344d72254bc6e08502352d29cffb1facd6978d5","modified":1735820602632},{"_id":"public/manifest.json","hash":"af662fb1f47a081376182ae79d81110a8c172dcb","modified":1735820455767},{"_id":"public/2025/01/02/rejection/index.html","hash":"27a238ffa2f97c4ac255ffad04786ad8979f94e2","modified":1735820455767},{"_id":"public/2024/12/30/craftsman_guide/index.html","hash":"5c6c8b5ae5b55fabe3ef15eab74c0a7d4ad9b200","modified":1735821729294},{"_id":"public/2024/12/29/posix/index.html","hash":"ec6add5cf26e6f07045eef98deba3a9d711b53d7","modified":1735821729294},{"_id":"public/2024/12/30/npm_install/index.html","hash":"c39dc8bbc09fbb116f1ddc328818b649b2aa29d4","modified":1735821729294},{"_id":"public/2024/12/15/lua/index.html","hash":"2f5dadae31527aa9881838f43418ad1dd545b2c9","modified":1735821729294},{"_id":"public/2024/10/15/hello-world/index.html","hash":"bbbbff1fdac3bac96104d649444f148f90b2f192","modified":1735821729294},{"_id":"public/2024/10/15/semaphores/index.html","hash":"4cb1bf4e818dd33a2ffb82b030a65e7293cd8ac0","modified":1735821729294},{"_id":"public/categories/research/index.html","hash":"154ea2e33137b6ba303002e51e173f376b65bd48","modified":1735821729294},{"_id":"public/categories/implementation/index.html","hash":"4b33e3a77c77b23968e10e9251dfe1e30cad5fc4","modified":1735821729294},{"_id":"public/archives/index.html","hash":"a9adc029df35df6a5918a5ef1cb362a33aaa504f","modified":1735821729294},{"_id":"public/categories/research/books/index.html","hash":"f7d064b7ddd185a7192abf2d25980a78c33ee2e7","modified":1735821729294},{"_id":"public/archives/2024/index.html","hash":"189c48678d02f19d15359c23329efcd96d6fcd8b","modified":1735821729294},{"_id":"public/archives/2025/index.html","hash":"bd2c4372cbb22bd7de3e607da45d6f5cb308e08d","modified":1735820455767},{"_id":"public/archives/2024/10/index.html","hash":"987df040deb327ba80dafd764616d68174ebe952","modified":1735821729294},{"_id":"public/archives/2024/12/index.html","hash":"22d81275ad30442411526fcb7d2238efe1039c1a","modified":1735821729294},{"_id":"public/archives/2025/01/index.html","hash":"bfdda1959b9992e3ab9d10a3ae784f603111992f","modified":1735820455767},{"_id":"public/tags/lua/index.html","hash":"df5c566c08c1e6f52542641b12962a56fdaa5ea5","modified":1735821729294},{"_id":"public/tags/scripting/index.html","hash":"ee851d833c7f65d9d09ebf6f207c1e742e6693c1","modified":1735821729294},{"_id":"public/tags/programming/index.html","hash":"e582c8b1ed9cb76dadd494cf165e0fcd13e09d68","modified":1735821729294},{"_id":"public/tags/craftsman/index.html","hash":"1cd268aee7ac706c2678bd8e69d712b25dddf6dc","modified":1735821729294},{"_id":"public/tags/npm/index.html","hash":"a50ae5e4b0dcfeb1e33e184b1de986522698d303","modified":1735821729294},{"_id":"public/tags/A-Life-Engineered/index.html","hash":"9da562c5fc2cc32c63b19124bb22d0557c77e4dc","modified":1735821729294},{"_id":"public/tags/docker/index.html","hash":"06b4fe3c8d8ad20e0da6ef3028a4dd585996f7f8","modified":1735821729294},{"_id":"public/tags/devops/index.html","hash":"d4e0c596e54a4e034d90fa07a42f3631b793ed8b","modified":1735821729294},{"_id":"public/tags/concurrency/index.html","hash":"23f75e3659a4e3407642ef794cb8be3aa0adaf45","modified":1735821729294},{"_id":"public/tags/synchronization/index.html","hash":"80c8f494d3101a8e27d2a8ca87936b1d1e4b8ad6","modified":1735821729294},{"_id":"public/tags/low-level/index.html","hash":"10c0fbb9506a9f0f6abe87b0585450cac4fb7c62","modified":1735821729294},{"_id":"public/tags/c/index.html","hash":"fb3a7b7378f06c918d843e56f682a01e80b75d9c","modified":1735821729294},{"_id":"public/tags/posix/index.html","hash":"e3eca443a868dcae1f287192217b886484befeb4","modified":1735821729294},{"_id":"public/index.html","hash":"62702b40032edf704e379e64aa0922f706a45a44","modified":1735821729294},{"_id":"public/categories/index.html","hash":"9a99e0966f26c4bf184321a269f51f5736987507","modified":1735821729294},{"_id":"public/tags/linux/index.html","hash":"066821d1118a6067fbe510015c6bd929d1d045f1","modified":1735821729294},{"_id":"public/tags/macos/index.html","hash":"302e9b0b9f4d9ffb03984eb6be18304617b16314","modified":1735821729294},{"_id":"public/tags/index.html","hash":"1cc2ad23cc8315b50552daf77216f5bb54a2fcc6","modified":1735821729294},{"_id":"public/img/favicon.png","hash":"cad785cdc11fcdd88afb1ae19cb001543f3bf3f5","modified":1735820455767},{"_id":"public/img/razor-bottom-black.svg","hash":"a3eda07b1c605b456da9cdf335a1075db5e5d72c","modified":1735820455767},{"_id":"public/img/razor-top-black.svg","hash":"201f1171a43ce667a39091fe47c0f278857f18f0","modified":1735820455767},{"_id":"public/img/og_image.png","hash":"b03f163096ca9c350ec962feee9836277b5c2509","modified":1735820455767},{"_id":"public/img/logo.png","hash":"d40e9a4a865f1358e98b49554f33b73378197f71","modified":1735820455767},{"_id":"public/css/cyberpunk.css","hash":"4b33f24a5f5b69b3185add8ed5439157f1d7c065","modified":1735821318673},{"_id":"public/css/default.css","hash":"b09de99d46125d4a78d07e75826f1903b22b903a","modified":1735820455767},{"_id":"public/css/night.css","hash":"bee8a361e43d5589036e5d05633172dca584c039","modified":1735820455767},{"_id":"public/css/style.css","hash":"b09de99d46125d4a78d07e75826f1903b22b903a","modified":1735820455767},{"_id":"public/js/animation.js","hash":"e91b4ddf4ac788a3de8fcab4c8bb75f8c3e0bbd8","modified":1735821318673},{"_id":"public/js/column.js","hash":"0baee024ab67474c073a4c41b495f3e7f0df4505","modified":1735820455767},{"_id":"public/js/main.js","hash":"bb33f2467141afc2a5fad35b553e90782e2bcacd","modified":1735821318673},{"_id":"public/js/back_to_top.js","hash":"d91f10c08c726135a13dfa1f422c49d8764ef03f","modified":1735820455767},{"_id":"public/js/imaegoo/universe.js","hash":"8dc3bd0b57cd84f01943a9992ebd11b3649340df","modified":1735820455767},{"_id":"public/js/pjax.js","hash":"1c9921d4bd07795adc1d01a12c0fddf7d1124ca2","modified":1735820455767},{"_id":"public/js/imaegoo/night.js","hash":"ee9267b31315bd80a58a80cda99b1e4d0d49d0f9","modified":1735820455767},{"_id":"public/img/me.MP.jpg","hash":"09ab0abf391a1db046feace08f3e8ea6c93c8368","modified":1735820455767},{"_id":"public/2024/12/31/rejection/index.html","hash":"bcf51238580a75b3e6a8daf1aa5175cba9db7385","modified":1735821729294},{"_id":"public/categories/research/life/index.html","hash":"05fa8e424b4d4adf8f1f36ddc71b09df25349161","modified":1735821729294},{"_id":"public/tags/rejection/index.html","hash":"cae10124280ab121bdde5d2996dfe26f94a2bdb4","modified":1735821729294},{"_id":"public/tags/life/index.html","hash":"68f0160fccdb7a01c831268d38b652353fdb00ef","modified":1735821729294},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Bio-Large.jpg","hash":"5ab6f1546dd429874d0f8ab38aa33ae3dcff26ba","modified":1735821702156},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/leimao_chinese.png","hash":"d528d4a4c8b09485cd1fad9851ea629557ed1997","modified":1735821702787},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/leimao_chinese_cropped.png","hash":"d39038926d7b61e1d7530b4be8f7e64ac34e9bb7","modified":1735821702786},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Bio.jpg","hash":"24772541ab59817457e9682be207da8a21e8cc9b","modified":1735821702265},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Bio-Medium.jpg","hash":"7b8bc5237c264f9c66cd10b51810048a0ce496e6","modified":1735821702160},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei.jpg","hash":"61a6cfe5612e2003ad42be02accd283531180803","modified":1735821702427},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei_Raw.jpg","hash":"e74c5fcafac31f22803fb77cb8363a43c6202673","modified":1735821702148},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/tiny_website_teaser.jpg","hash":"2291e462420480d39f06c63b50e7c5514a714fe3","modified":1735821702627},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Optimized-Lei-Smoky_Mountain.JPG","hash":"6eb52554fb97d5c4b4832d0d7da27c80d0a4eb17","modified":1735821702542},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Optimized-website_teaser.jpg","hash":"d3eb78fee438cad8deebd4387ea50944f563f52c","modified":1735821702580},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/website_teaser_2.jpg","hash":"7ac4e7d17d4e6c8ff49d7a1572d9f937fc0b73dd","modified":1735821702692},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/website_teaser.jpg","hash":"c9b7efd00feedd7f7ab3a9683020baf601b8e457","modified":1735821702729},{"_id":"node_modules/hexo-theme-icarus/source/img/author_images/Lei-Smoky_Mountain.JPG","hash":"9d1118128c0e87618af7af5badd317f3ae51ab03","modified":1735821702353},{"_id":"public/img/author_images/Lei-Bio-Large.jpg","hash":"5ab6f1546dd429874d0f8ab38aa33ae3dcff26ba","modified":1735821729294},{"_id":"public/img/author_images/leimao_chinese_cropped.png","hash":"d39038926d7b61e1d7530b4be8f7e64ac34e9bb7","modified":1735821729294},{"_id":"public/img/author_images/leimao_chinese.png","hash":"d528d4a4c8b09485cd1fad9851ea629557ed1997","modified":1735821729294},{"_id":"public/img/author_images/Lei_Raw.jpg","hash":"e74c5fcafac31f22803fb77cb8363a43c6202673","modified":1735821729294},{"_id":"public/img/author_images/Lei-Bio-Medium.jpg","hash":"7b8bc5237c264f9c66cd10b51810048a0ce496e6","modified":1735821729294},{"_id":"public/img/author_images/Lei.jpg","hash":"61a6cfe5612e2003ad42be02accd283531180803","modified":1735821729294},{"_id":"public/img/author_images/Lei-Bio.jpg","hash":"24772541ab59817457e9682be207da8a21e8cc9b","modified":1735821729294},{"_id":"public/img/author_images/tiny_website_teaser.jpg","hash":"2291e462420480d39f06c63b50e7c5514a714fe3","modified":1735821729294},{"_id":"public/img/author_images/Optimized-Lei-Smoky_Mountain.JPG","hash":"6eb52554fb97d5c4b4832d0d7da27c80d0a4eb17","modified":1735821729294},{"_id":"public/img/author_images/Optimized-website_teaser.jpg","hash":"d3eb78fee438cad8deebd4387ea50944f563f52c","modified":1735821729294},{"_id":"public/img/author_images/website_teaser.jpg","hash":"c9b7efd00feedd7f7ab3a9683020baf601b8e457","modified":1735821729294},{"_id":"public/img/author_images/website_teaser_2.jpg","hash":"7ac4e7d17d4e6c8ff49d7a1572d9f937fc0b73dd","modified":1735821729294},{"_id":"public/img/author_images/Lei-Smoky_Mountain.JPG","hash":"9d1118128c0e87618af7af5badd317f3ae51ab03","modified":1735821729294}],"Category":[{"name":"research","_id":"cm5faokhr0006gwovd75k07p1"},{"name":"implementation","_id":"cm5faokhs0008gwov1j1g5vak"},{"name":"books","parent":"cm5faokhr0006gwovd75k07p1","_id":"cm5faokht000agwovay5cg29l"},{"name":"life","parent":"cm5faokhr0006gwovd75k07p1","_id":"cm5farprc0001hkovgjl1dfdq"}],"Data":[],"Page":[],"Post":[{"title":"Hello World","date":"2024-10-15T15:00:00.000Z","_content":"\nWelcome to my website! This is my first post, and it's going to be about how I set up this website: how I got the dependencies and how I was able to publish to github pages.\n\nGetting this website up and running required one night's worth of work. So, if you want to dot the same for your github page, here's how you can do it:\n\n## Getting dependencies and development container\n\n0. [hexo-icarus-theme](https://github.com/ppoffice/hexo-theme-icarus) is the main dependency of this site. To avoid accidentally breaking your website should the theme be updated *AND* for future customization-ility, we are going to fork the theme repo on Github and pull it locally.\n```\n# dont forget to fork on GH first\ngh repo clone <your-gh-username>/hexo-icarus-theme\n```\n\n1. Let's create a new repo to hold the website source tree. This will be the repo that you will push to Github Pages.\n```\nmkdir $USER.github.io\ncd $USER.github.io\ngit init\n```\nYou might want to change `$USER` to your Github user or organization name.\n\n2. Next is a Dockerfile that will build your site locally in a \"controlled environment\": no polluting your machine with node stuff, development isolation, etc\n```Dockerfile\n# Dockerfile\n\n## Base and dependencies\nFROM node:22.5.1-alpine3.19 AS base\nWORKDIR /workspace\nRUN npm install -g hexo-cli\n\n## Copy sources for build\nFROM base AS build\nCOPY . /workspace\nRUN hexo generate\n\n## Deploy\nFROM nginx:1.21.3-alpine\nCOPY --from=build /workspace/dist /usr/share/nginx/html\nEXPOSE 80\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n```\n\n3. Add a .devcontainer for development purposes (things might break and you might want to debug why)\n\n```yaml\n# .devcontainer/compose.yml\nservices:\n web:\n build:\n context: .\n dockerfile: Dockerfile\n image: my-website-server\n ports:\n - \"80:80\"\n```\n\n4. You can now init the site, add icarus theme as a submodule, and start the server\n\n```bash\ndocker compose -f ./devcontainer/compose.yml up -d --build\ndocker compose -f ./devcontainer/compose.yml exec hexo init .\ngit submodule add https://github.com/<your-gh-username>/hexo-icarus-theme themes/icarus\n# you might need to run `npm install <some-packages>` to get things working\n# dont forget to set icarus as the theme in _config.yml\ndocker compose -f ./devcontainer/compose.yml exec hexo server\n```\n\n5. Get the [experimental dark theme](https://github.com/ppoffice/hexo-theme-icarus/issues/564) and apply it\n\n```bash\ncd themes/icarus\ngit checkout night4\ngit remote add imaegoo https://github.com/imaegoo/hexo-theme-icarus.git\ngit fetch imaegoo\ngit merge imaegoo/night4\n```\n\n6. add .gitignore for things like `node_modules` etc\n\n7. fix the `_config.yml` and `_config.icarus.yml` to your liking.\n\nMake sure to follow [icarus docs](https://ppoffice.github.io/hexo-theme-icarus/). For more information.\n\n## Deploying to Github Pages\n\nThe easiest way to deploy to Github pages is to follow the example from [deploy-pages action](https://github.com/actions/deploy-pages).\nCheckout my [workflow](https://github.com/wgkassem/wgkassem.github.io/blob/main/.github/workflows/pages.yml) for this website.\n\n","source":"_posts/hello-world.md","raw":"---\ntitle: Hello World\ndate: 2024-10-16\n---\n\nWelcome to my website! This is my first post, and it's going to be about how I set up this website: how I got the dependencies and how I was able to publish to github pages.\n\nGetting this website up and running required one night's worth of work. So, if you want to dot the same for your github page, here's how you can do it:\n\n## Getting dependencies and development container\n\n0. [hexo-icarus-theme](https://github.com/ppoffice/hexo-theme-icarus) is the main dependency of this site. To avoid accidentally breaking your website should the theme be updated *AND* for future customization-ility, we are going to fork the theme repo on Github and pull it locally.\n```\n# dont forget to fork on GH first\ngh repo clone <your-gh-username>/hexo-icarus-theme\n```\n\n1. Let's create a new repo to hold the website source tree. This will be the repo that you will push to Github Pages.\n```\nmkdir $USER.github.io\ncd $USER.github.io\ngit init\n```\nYou might want to change `$USER` to your Github user or organization name.\n\n2. Next is a Dockerfile that will build your site locally in a \"controlled environment\": no polluting your machine with node stuff, development isolation, etc\n```Dockerfile\n# Dockerfile\n\n## Base and dependencies\nFROM node:22.5.1-alpine3.19 AS base\nWORKDIR /workspace\nRUN npm install -g hexo-cli\n\n## Copy sources for build\nFROM base AS build\nCOPY . /workspace\nRUN hexo generate\n\n## Deploy\nFROM nginx:1.21.3-alpine\nCOPY --from=build /workspace/dist /usr/share/nginx/html\nEXPOSE 80\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n```\n\n3. Add a .devcontainer for development purposes (things might break and you might want to debug why)\n\n```yaml\n# .devcontainer/compose.yml\nservices:\n web:\n build:\n context: .\n dockerfile: Dockerfile\n image: my-website-server\n ports:\n - \"80:80\"\n```\n\n4. You can now init the site, add icarus theme as a submodule, and start the server\n\n```bash\ndocker compose -f ./devcontainer/compose.yml up -d --build\ndocker compose -f ./devcontainer/compose.yml exec hexo init .\ngit submodule add https://github.com/<your-gh-username>/hexo-icarus-theme themes/icarus\n# you might need to run `npm install <some-packages>` to get things working\n# dont forget to set icarus as the theme in _config.yml\ndocker compose -f ./devcontainer/compose.yml exec hexo server\n```\n\n5. Get the [experimental dark theme](https://github.com/ppoffice/hexo-theme-icarus/issues/564) and apply it\n\n```bash\ncd themes/icarus\ngit checkout night4\ngit remote add imaegoo https://github.com/imaegoo/hexo-theme-icarus.git\ngit fetch imaegoo\ngit merge imaegoo/night4\n```\n\n6. add .gitignore for things like `node_modules` etc\n\n7. fix the `_config.yml` and `_config.icarus.yml` to your liking.\n\nMake sure to follow [icarus docs](https://ppoffice.github.io/hexo-theme-icarus/). For more information.\n\n## Deploying to Github Pages\n\nThe easiest way to deploy to Github pages is to follow the example from [deploy-pages action](https://github.com/actions/deploy-pages).\nCheckout my [workflow](https://github.com/wgkassem/wgkassem.github.io/blob/main/.github/workflows/pages.yml) for this website.\n\n","slug":"hello-world","published":1,"updated":"2025-01-02T11:50:22.467Z","comments":1,"layout":"post","photos":[],"_id":"cm5faokhi0000gwovcsxh3dhm","content":"<p>Welcome to my website! This is my first post, and it’s going to be about how I set up this website: how I got the dependencies and how I was able to publish to github pages.</p>\n<p>Getting this website up and running required one night’s worth of work. So, if you want to dot the same for your github page, here’s how you can do it:</p>\n<h2 id=\"Getting-dependencies-and-development-container\"><a href=\"#Getting-dependencies-and-development-container\" class=\"headerlink\" title=\"Getting dependencies and development container\"></a>Getting dependencies and development container</h2><ol start=\"0\">\n<li><p><a href=\"https://github.com/ppoffice/hexo-theme-icarus\">hexo-icarus-theme</a> is the main dependency of this site. To avoid accidentally breaking your website should the theme be updated <em>AND</em> for future customization-ility, we are going to fork the theme repo on Github and pull it locally.</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"># dont forget to fork on GH first</span><br><span class=\"line\">gh repo clone <your-gh-username>/hexo-icarus-theme</span><br></pre></td></tr></table></figure>\n</li>\n<li><p>Let’s create a new repo to hold the website source tree. This will be the repo that you will push to Github Pages.</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br></pre></td><td class=\"code\"><pre><span class=\"line\">mkdir $USER.github.io</span><br><span class=\"line\">cd $USER.github.io</span><br><span class=\"line\">git init</span><br></pre></td></tr></table></figure>\n<p>You might want to change <code>$USER</code> to your Github user or organization name.</p>\n</li>\n<li><p>Next is a Dockerfile that will build your site locally in a “controlled environment”: no polluting your machine with node stuff, development isolation, etc</p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\"># Dockerfile</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">## Base and dependencies</span></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> node:<span class=\"number\">22.5</span>.<span class=\"number\">1</span>-alpine3.<span class=\"number\">19</span> AS base</span><br><span class=\"line\"><span class=\"keyword\">WORKDIR</span><span class=\"language-bash\"> /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm install -g hexo-cli</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">## Copy sources for build</span></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> base AS build</span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> . /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> hexo generate</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">## Deploy</span></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> nginx:<span class=\"number\">1.21</span>.<span class=\"number\">3</span>-alpine</span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> --from=build /workspace/dist /usr/share/nginx/html</span></span><br><span class=\"line\"><span class=\"keyword\">EXPOSE</span> <span class=\"number\">80</span></span><br><span class=\"line\"><span class=\"keyword\">CMD</span><span class=\"language-bash\"> [<span class=\"string\">"nginx"</span>, <span class=\"string\">"-g"</span>, <span class=\"string\">"daemon off;"</span>]</span></span><br></pre></td></tr></table></figure>\n</li>\n<li><p>Add a .devcontainer for development purposes (things might break and you might want to debug why)</p>\n</li>\n</ol>\n<figure class=\"highlight yaml\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\"># .devcontainer/compose.yml</span></span><br><span class=\"line\"><span class=\"attr\">services:</span></span><br><span class=\"line\"> <span class=\"attr\">web:</span></span><br><span class=\"line\"> <span class=\"attr\">build:</span></span><br><span class=\"line\"> <span class=\"attr\">context:</span> <span class=\"string\">.</span></span><br><span class=\"line\"> <span class=\"attr\">dockerfile:</span> <span class=\"string\">Dockerfile</span></span><br><span class=\"line\"> <span class=\"attr\">image:</span> <span class=\"string\">my-website-server</span></span><br><span class=\"line\"> <span class=\"attr\">ports:</span></span><br><span class=\"line\"> <span class=\"bullet\">-</span> <span class=\"string\">"80:80"</span></span><br></pre></td></tr></table></figure>\n\n<ol start=\"4\">\n<li>You can now init the site, add icarus theme as a submodule, and start the server</li>\n</ol>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br></pre></td><td class=\"code\"><pre><span class=\"line\">docker compose -f ./devcontainer/compose.yml up -d --build</span><br><span class=\"line\">docker compose -f ./devcontainer/compose.yml <span class=\"built_in\">exec</span> hexo init .</span><br><span class=\"line\">git submodule add https://github.com/<your-gh-username>/hexo-icarus-theme themes/icarus</span><br><span class=\"line\"><span class=\"comment\"># you might need to run `npm install <some-packages>` to get things working</span></span><br><span class=\"line\"><span class=\"comment\"># dont forget to set icarus as the theme in _config.yml</span></span><br><span class=\"line\">docker compose -f ./devcontainer/compose.yml <span class=\"built_in\">exec</span> hexo server</span><br></pre></td></tr></table></figure>\n\n<ol start=\"5\">\n<li>Get the <a href=\"https://github.com/ppoffice/hexo-theme-icarus/issues/564\">experimental dark theme</a> and apply it</li>\n</ol>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">cd</span> themes/icarus</span><br><span class=\"line\">git checkout night4</span><br><span class=\"line\">git remote add imaegoo https://github.com/imaegoo/hexo-theme-icarus.git</span><br><span class=\"line\">git fetch imaegoo</span><br><span class=\"line\">git merge imaegoo/night4</span><br></pre></td></tr></table></figure>\n\n<ol start=\"6\">\n<li><p>add .gitignore for things like <code>node_modules</code> etc</p>\n</li>\n<li><p>fix the <code>_config.yml</code> and <code>_config.icarus.yml</code> to your liking.</p>\n</li>\n</ol>\n<p>Make sure to follow <a href=\"https://ppoffice.github.io/hexo-theme-icarus/\">icarus docs</a>. For more information.</p>\n<h2 id=\"Deploying-to-Github-Pages\"><a href=\"#Deploying-to-Github-Pages\" class=\"headerlink\" title=\"Deploying to Github Pages\"></a>Deploying to Github Pages</h2><p>The easiest way to deploy to Github pages is to follow the example from <a href=\"https://github.com/actions/deploy-pages\">deploy-pages action</a>.<br>Checkout my <a href=\"https://github.com/wgkassem/wgkassem.github.io/blob/main/.github/workflows/pages.yml\">workflow</a> for this website.</p>\n","excerpt":"","more":"<p>Welcome to my website! This is my first post, and it’s going to be about how I set up this website: how I got the dependencies and how I was able to publish to github pages.</p>\n<p>Getting this website up and running required one night’s worth of work. So, if you want to dot the same for your github page, here’s how you can do it:</p>\n<h2 id=\"Getting-dependencies-and-development-container\"><a href=\"#Getting-dependencies-and-development-container\" class=\"headerlink\" title=\"Getting dependencies and development container\"></a>Getting dependencies and development container</h2><ol start=\"0\">\n<li><p><a href=\"https://github.com/ppoffice/hexo-theme-icarus\">hexo-icarus-theme</a> is the main dependency of this site. To avoid accidentally breaking your website should the theme be updated <em>AND</em> for future customization-ility, we are going to fork the theme repo on Github and pull it locally.</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"># dont forget to fork on GH first</span><br><span class=\"line\">gh repo clone <your-gh-username>/hexo-icarus-theme</span><br></pre></td></tr></table></figure>\n</li>\n<li><p>Let’s create a new repo to hold the website source tree. This will be the repo that you will push to Github Pages.</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br></pre></td><td class=\"code\"><pre><span class=\"line\">mkdir $USER.github.io</span><br><span class=\"line\">cd $USER.github.io</span><br><span class=\"line\">git init</span><br></pre></td></tr></table></figure>\n<p>You might want to change <code>$USER</code> to your Github user or organization name.</p>\n</li>\n<li><p>Next is a Dockerfile that will build your site locally in a “controlled environment”: no polluting your machine with node stuff, development isolation, etc</p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\"># Dockerfile</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">## Base and dependencies</span></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> node:<span class=\"number\">22.5</span>.<span class=\"number\">1</span>-alpine3.<span class=\"number\">19</span> AS base</span><br><span class=\"line\"><span class=\"keyword\">WORKDIR</span><span class=\"language-bash\"> /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm install -g hexo-cli</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">## Copy sources for build</span></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> base AS build</span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> . /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> hexo generate</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">## Deploy</span></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> nginx:<span class=\"number\">1.21</span>.<span class=\"number\">3</span>-alpine</span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> --from=build /workspace/dist /usr/share/nginx/html</span></span><br><span class=\"line\"><span class=\"keyword\">EXPOSE</span> <span class=\"number\">80</span></span><br><span class=\"line\"><span class=\"keyword\">CMD</span><span class=\"language-bash\"> [<span class=\"string\">"nginx"</span>, <span class=\"string\">"-g"</span>, <span class=\"string\">"daemon off;"</span>]</span></span><br></pre></td></tr></table></figure>\n</li>\n<li><p>Add a .devcontainer for development purposes (things might break and you might want to debug why)</p>\n</li>\n</ol>\n<figure class=\"highlight yaml\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\"># .devcontainer/compose.yml</span></span><br><span class=\"line\"><span class=\"attr\">services:</span></span><br><span class=\"line\"> <span class=\"attr\">web:</span></span><br><span class=\"line\"> <span class=\"attr\">build:</span></span><br><span class=\"line\"> <span class=\"attr\">context:</span> <span class=\"string\">.</span></span><br><span class=\"line\"> <span class=\"attr\">dockerfile:</span> <span class=\"string\">Dockerfile</span></span><br><span class=\"line\"> <span class=\"attr\">image:</span> <span class=\"string\">my-website-server</span></span><br><span class=\"line\"> <span class=\"attr\">ports:</span></span><br><span class=\"line\"> <span class=\"bullet\">-</span> <span class=\"string\">"80:80"</span></span><br></pre></td></tr></table></figure>\n\n<ol start=\"4\">\n<li>You can now init the site, add icarus theme as a submodule, and start the server</li>\n</ol>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br></pre></td><td class=\"code\"><pre><span class=\"line\">docker compose -f ./devcontainer/compose.yml up -d --build</span><br><span class=\"line\">docker compose -f ./devcontainer/compose.yml <span class=\"built_in\">exec</span> hexo init .</span><br><span class=\"line\">git submodule add https://github.com/<your-gh-username>/hexo-icarus-theme themes/icarus</span><br><span class=\"line\"><span class=\"comment\"># you might need to run `npm install <some-packages>` to get things working</span></span><br><span class=\"line\"><span class=\"comment\"># dont forget to set icarus as the theme in _config.yml</span></span><br><span class=\"line\">docker compose -f ./devcontainer/compose.yml <span class=\"built_in\">exec</span> hexo server</span><br></pre></td></tr></table></figure>\n\n<ol start=\"5\">\n<li>Get the <a href=\"https://github.com/ppoffice/hexo-theme-icarus/issues/564\">experimental dark theme</a> and apply it</li>\n</ol>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"built_in\">cd</span> themes/icarus</span><br><span class=\"line\">git checkout night4</span><br><span class=\"line\">git remote add imaegoo https://github.com/imaegoo/hexo-theme-icarus.git</span><br><span class=\"line\">git fetch imaegoo</span><br><span class=\"line\">git merge imaegoo/night4</span><br></pre></td></tr></table></figure>\n\n<ol start=\"6\">\n<li><p>add .gitignore for things like <code>node_modules</code> etc</p>\n</li>\n<li><p>fix the <code>_config.yml</code> and <code>_config.icarus.yml</code> to your liking.</p>\n</li>\n</ol>\n<p>Make sure to follow <a href=\"https://ppoffice.github.io/hexo-theme-icarus/\">icarus docs</a>. For more information.</p>\n<h2 id=\"Deploying-to-Github-Pages\"><a href=\"#Deploying-to-Github-Pages\" class=\"headerlink\" title=\"Deploying to Github Pages\"></a>Deploying to Github Pages</h2><p>The easiest way to deploy to Github pages is to follow the example from <a href=\"https://github.com/actions/deploy-pages\">deploy-pages action</a>.<br>Checkout my <a href=\"https://github.com/wgkassem/wgkassem.github.io/blob/main/.github/workflows/pages.yml\">workflow</a> for this website.</p>\n"},{"_content":"","source":"_posts/posix.md","raw":"","slug":"posix","published":1,"date":"2024-12-29T01:42:46.152Z","updated":"2024-12-29T01:42:46.152Z","title":"","comments":1,"layout":"post","photos":[],"_id":"cm5faokhm0001gwovfkdh86mr","content":"","excerpt":"","more":""},{"title":"dotfiles with Lua","date":"2024-12-15T15:00:00.000Z","_content":"\n## Why learn lua?\n\n1. Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications.\n2. Lua is very integrable with C and C++.\n3. Some major projects that use Lua include World of Warcraft, Adobe Lightroom, and Redis.\n4. Interesting history: Lua was created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes at the Pontifical Catholic University of Rio de Janeiro, Brazil because they needed a language that was powerful but also lightweight and *they could not import software*.\n5. It's functional, imperative, and object-oriented.\n6. I want to contribute and become a better neovim user.\n7. *Main reason*: improve installation of my [dotfiles](https://github.com/wgkassem/dotfiles) scripts.\n\n## Useful things:\n\n### Strings\n\n- Strings are immutable in Lua. Once a string is created, it cannot be changed.\n- Get the length of a string variable `var` with `#var`.\n- Concatenate strings with `..`. Example: `str1 = \"Hello\" .. \" \" .. \"World\"`.\n- Long strings can be created with double square brackets `[[ ]]`. This is useful for multi-line strings.\n","source":"_posts/lua.md","raw":"---\ntitle: dotfiles with Lua\ndate: 2024-12-16\ntags: [lua, scripting, programming]\n---\n\n## Why learn lua?\n\n1. Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications.\n2. Lua is very integrable with C and C++.\n3. Some major projects that use Lua include World of Warcraft, Adobe Lightroom, and Redis.\n4. Interesting history: Lua was created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes at the Pontifical Catholic University of Rio de Janeiro, Brazil because they needed a language that was powerful but also lightweight and *they could not import software*.\n5. It's functional, imperative, and object-oriented.\n6. I want to contribute and become a better neovim user.\n7. *Main reason*: improve installation of my [dotfiles](https://github.com/wgkassem/dotfiles) scripts.\n\n## Useful things:\n\n### Strings\n\n- Strings are immutable in Lua. Once a string is created, it cannot be changed.\n- Get the length of a string variable `var` with `#var`.\n- Concatenate strings with `..`. Example: `str1 = \"Hello\" .. \" \" .. \"World\"`.\n- Long strings can be created with double square brackets `[[ ]]`. This is useful for multi-line strings.\n","slug":"lua","published":1,"updated":"2024-12-16T12:39:37.252Z","comments":1,"layout":"post","photos":[],"_id":"cm5faokho0002gwovactb6ztb","content":"<h2 id=\"Why-learn-lua\"><a href=\"#Why-learn-lua\" class=\"headerlink\" title=\"Why learn lua?\"></a>Why learn lua?</h2><ol>\n<li>Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications.</li>\n<li>Lua is very integrable with C and C++.</li>\n<li>Some major projects that use Lua include World of Warcraft, Adobe Lightroom, and Redis.</li>\n<li>Interesting history: Lua was created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes at the Pontifical Catholic University of Rio de Janeiro, Brazil because they needed a language that was powerful but also lightweight and <em>they could not import software</em>.</li>\n<li>It’s functional, imperative, and object-oriented.</li>\n<li>I want to contribute and become a better neovim user.</li>\n<li><em>Main reason</em>: improve installation of my <a href=\"https://github.com/wgkassem/dotfiles\">dotfiles</a> scripts.</li>\n</ol>\n<h2 id=\"Useful-things\"><a href=\"#Useful-things\" class=\"headerlink\" title=\"Useful things:\"></a>Useful things:</h2><h3 id=\"Strings\"><a href=\"#Strings\" class=\"headerlink\" title=\"Strings\"></a>Strings</h3><ul>\n<li>Strings are immutable in Lua. Once a string is created, it cannot be changed.</li>\n<li>Get the length of a string variable <code>var</code> with <code>#var</code>.</li>\n<li>Concatenate strings with <code>..</code>. Example: <code>str1 = "Hello" .. " " .. "World"</code>.</li>\n<li>Long strings can be created with double square brackets <code>[[ ]]</code>. This is useful for multi-line strings.</li>\n</ul>\n","excerpt":"","more":"<h2 id=\"Why-learn-lua\"><a href=\"#Why-learn-lua\" class=\"headerlink\" title=\"Why learn lua?\"></a>Why learn lua?</h2><ol>\n<li>Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications.</li>\n<li>Lua is very integrable with C and C++.</li>\n<li>Some major projects that use Lua include World of Warcraft, Adobe Lightroom, and Redis.</li>\n<li>Interesting history: Lua was created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes at the Pontifical Catholic University of Rio de Janeiro, Brazil because they needed a language that was powerful but also lightweight and <em>they could not import software</em>.</li>\n<li>It’s functional, imperative, and object-oriented.</li>\n<li>I want to contribute and become a better neovim user.</li>\n<li><em>Main reason</em>: improve installation of my <a href=\"https://github.com/wgkassem/dotfiles\">dotfiles</a> scripts.</li>\n</ol>\n<h2 id=\"Useful-things\"><a href=\"#Useful-things\" class=\"headerlink\" title=\"Useful things:\"></a>Useful things:</h2><h3 id=\"Strings\"><a href=\"#Strings\" class=\"headerlink\" title=\"Strings\"></a>Strings</h3><ul>\n<li>Strings are immutable in Lua. Once a string is created, it cannot be changed.</li>\n<li>Get the length of a string variable <code>var</code> with <code>#var</code>.</li>\n<li>Concatenate strings with <code>..</code>. Example: <code>str1 = "Hello" .. " " .. "World"</code>.</li>\n<li>Long strings can be created with double square brackets <code>[[ ]]</code>. This is useful for multi-line strings.</li>\n</ul>\n"},{"title":"Craftsman Guide","Description":"Kickstart a craftsman's approach to software development","date":"2024-12-30T15:00:00.000Z","_content":"\n[A Life Engineered](https://www.youtube.com/@ALifeEngineered) lists [So Good They Can't Ignore You](https://www.calnewport.com/books/so-good/) as a great inspiration in his video description.\n\nHaving read some of it, I've been inspired to take a craftsman's approach to a career in software engineering.\n\nThe \"craftsman's approach\" focuses on maximizing the value you can offer to the world as opposed to following your passion in your job.\n\nHaving rare value to offer will lead to valuable job opportunities and the prototypical elements of what makes \"dream jobs\": autonomy, creativity, impactful, and rewarding (financially and emotionally).\n\n## The 4 areas of a software engineer\n\nTo complement this, I am going to categorize my blog posts into the 4 main areas I believe a software engineer operates in.\n\n1. Research: this includes any posts related to how to become a better learner, researcher, etc in software engineering and life.\n1. Design: design and architecture problems and posts.\n2. Implementation: posts related to implementations e.g. DS&A, libraries, etc.\n3. Testing and debugging: posts related to testing, CI/CD, debugging, and tooling related to that.\n4. Stakeholder management: posts related to communication, project management, and other soft skills.\n","source":"_posts/craftsman_guide.md","raw":"---\ntitle: Craftsman Guide\nDescription: Kickstart a craftsman's approach to software development\ndate: 2024-12-31\ntags:\n - craftsman\n - A Life Engineered\ncategories:\n - [research, books]\n---\n\n[A Life Engineered](https://www.youtube.com/@ALifeEngineered) lists [So Good They Can't Ignore You](https://www.calnewport.com/books/so-good/) as a great inspiration in his video description.\n\nHaving read some of it, I've been inspired to take a craftsman's approach to a career in software engineering.\n\nThe \"craftsman's approach\" focuses on maximizing the value you can offer to the world as opposed to following your passion in your job.\n\nHaving rare value to offer will lead to valuable job opportunities and the prototypical elements of what makes \"dream jobs\": autonomy, creativity, impactful, and rewarding (financially and emotionally).\n\n## The 4 areas of a software engineer\n\nTo complement this, I am going to categorize my blog posts into the 4 main areas I believe a software engineer operates in.\n\n1. Research: this includes any posts related to how to become a better learner, researcher, etc in software engineering and life.\n1. Design: design and architecture problems and posts.\n2. Implementation: posts related to implementations e.g. DS&A, libraries, etc.\n3. Testing and debugging: posts related to testing, CI/CD, debugging, and tooling related to that.\n4. Stakeholder management: posts related to communication, project management, and other soft skills.\n","slug":"craftsman_guide","published":1,"updated":"2025-01-02T11:50:22.466Z","comments":1,"layout":"post","photos":[],"_id":"cm5faokho0003gwov5yn41v3d","content":"<p><a href=\"https://www.youtube.com/@ALifeEngineered\">A Life Engineered</a> lists <a href=\"https://www.calnewport.com/books/so-good/\">So Good They Can’t Ignore You</a> as a great inspiration in his video description.</p>\n<p>Having read some of it, I’ve been inspired to take a craftsman’s approach to a career in software engineering.</p>\n<p>The “craftsman’s approach” focuses on maximizing the value you can offer to the world as opposed to following your passion in your job.</p>\n<p>Having rare value to offer will lead to valuable job opportunities and the prototypical elements of what makes “dream jobs”: autonomy, creativity, impactful, and rewarding (financially and emotionally).</p>\n<h2 id=\"The-4-areas-of-a-software-engineer\"><a href=\"#The-4-areas-of-a-software-engineer\" class=\"headerlink\" title=\"The 4 areas of a software engineer\"></a>The 4 areas of a software engineer</h2><p>To complement this, I am going to categorize my blog posts into the 4 main areas I believe a software engineer operates in.</p>\n<ol>\n<li>Research: this includes any posts related to how to become a better learner, researcher, etc in software engineering and life.</li>\n<li>Design: design and architecture problems and posts.</li>\n<li>Implementation: posts related to implementations e.g. DS&A, libraries, etc.</li>\n<li>Testing and debugging: posts related to testing, CI/CD, debugging, and tooling related to that.</li>\n<li>Stakeholder management: posts related to communication, project management, and other soft skills.</li>\n</ol>\n","excerpt":"","more":"<p><a href=\"https://www.youtube.com/@ALifeEngineered\">A Life Engineered</a> lists <a href=\"https://www.calnewport.com/books/so-good/\">So Good They Can’t Ignore You</a> as a great inspiration in his video description.</p>\n<p>Having read some of it, I’ve been inspired to take a craftsman’s approach to a career in software engineering.</p>\n<p>The “craftsman’s approach” focuses on maximizing the value you can offer to the world as opposed to following your passion in your job.</p>\n<p>Having rare value to offer will lead to valuable job opportunities and the prototypical elements of what makes “dream jobs”: autonomy, creativity, impactful, and rewarding (financially and emotionally).</p>\n<h2 id=\"The-4-areas-of-a-software-engineer\"><a href=\"#The-4-areas-of-a-software-engineer\" class=\"headerlink\" title=\"The 4 areas of a software engineer\"></a>The 4 areas of a software engineer</h2><p>To complement this, I am going to categorize my blog posts into the 4 main areas I believe a software engineer operates in.</p>\n<ol>\n<li>Research: this includes any posts related to how to become a better learner, researcher, etc in software engineering and life.</li>\n<li>Design: design and architecture problems and posts.</li>\n<li>Implementation: posts related to implementations e.g. DS&A, libraries, etc.</li>\n<li>Testing and debugging: posts related to testing, CI/CD, debugging, and tooling related to that.</li>\n<li>Stakeholder management: posts related to communication, project management, and other soft skills.</li>\n</ol>\n"},{"title":"Reproducible builds with npm","description":"Fixing npm installs for Blog","date":"2024-12-30T15:00:00.000Z","_content":"\n## Background\n\nPreviously, we've been using a combination of `git submodule`, `npm install`, and `npm install --force` to build the blog. This has led to non-reproducible builds and a lot of confusion. Here's how we can fix it.\n\n## One: switch from `git submodule` to `npm` for theme package\n\nPreviously, we used `git submodule` to add the theme to the blog.\nThis caused some issues, as the theme was also a npm package with its own dependencies and build process. `hexo generate` would build them concurrently.\n\nWe added the theme [git repo to package.json](https://github.com/wgkassem/wgkassem.github.io/blob/main/package.json).\n\n\n## Two: switch from `npm install` to `npm ci` in base target\n\nCurrent blog is packaged with npm [1]: <https://docs.npmjs.com/about-packages-and-modules>. The base needs to provide the necessary dependencies for the blog to build.\n\nTwo files are important here:\n\n1. package.json: specifies the package name, version, and dependencies.\n2. package-lock.json\n\nWe *do not* want to use `npm install` here because:\n\n1. it does not delete `node_modules` tree.\n2. it modifies `package.json` if a new package is added.\n3. it generates `package-lock.json` to describe the exact tree that was generated.\n\nLeading to **non-reproducible** builds.\n\nFor instance, consider calling the following problematic Dockerfile \n\n```dockerfile\nFROM node:22.5.1-alpine3.19 AS base\n\nCOPY package.json package-lock.json /workspace/\nRUN npm install\n\nFROM base AS build\n\nCOPY . /workspace # package*.json overwrite\nRUN npm run build\n```\n\nA correct `base` [Dockerfile](https://github.com/wgkassem/wgkassem.github.io/blob/main/Dockerfile) target is:\n\n```dockerfile\nFROM node:22.5.1-alpine3.19 AS base\n\nRUN apk add --no-cache git\nWORKDIR /workspace\nCOPY package.json /workspace/\nRUN npm ci\n```\n\n`npm ci` installs the exact dependencies listed in `package-lock.json` and does not modify `package.json` or `package-lock.json`.\n\n## Just build\n\nThe build target should not contain any `npm install` or `npm ci` commands. It should only contain the build command as everything *should* be installed in the base target.\n\n```dockerfile\nFROM base AS build\n\nCOPY . /workspace\nRUN npm run build\n```\n\n## Three: handling updates to `package.json` and `package-lock.json`\n\nThis required a little bit of creativity. Here's what we want to accomplish:\n\n1. A dev env a.k.a \"change, build, test\" workflow in \"real-time\".\n1. Avoid maintain two separate Dockerfiles.\n1. Allow changes to `package.json` and `package-lock.json` to git-commit.\n\n### The `dev` service\n\nFrom the `base` target, **mount** the source tree (instead of `COPY`). Ergo, the dev can/must run `npm install` / `npm ci` to update dependencies or node modules.\n\nThen `npm run build` to build the site with any new changes.\n\nThe service runs a persistent shell process.\n\n> [!NOTE]\n\nIf you wanted to use `docker` to re-build then you should probably use the prod target of the main Dockerfile instead.\n\n\n### The `serve` service\n\nSince we cannot now serve (i.e. run `nginx`) from the same container we are goingto use a separate service for that.\n\nThe serice as such binds to the source tree where `public/` is generated by `dev` service and runs nginx with default args.\n\n## Notes:\n\n1. `npm ci` disregards `node_modules`. Hence, using devcontainer will not affect production builds unless `package*.json` is/are updated.\n","source":"_posts/npm_install.md","raw":"---\ntitle: Reproducible builds with npm\ndescription: Fixing npm installs for Blog\ndate: 2024-12-31\ntags: [\"npm\", \"devops\", \"docker\"]\ncategories: [\"implementation\"]\n---\n\n## Background\n\nPreviously, we've been using a combination of `git submodule`, `npm install`, and `npm install --force` to build the blog. This has led to non-reproducible builds and a lot of confusion. Here's how we can fix it.\n\n## One: switch from `git submodule` to `npm` for theme package\n\nPreviously, we used `git submodule` to add the theme to the blog.\nThis caused some issues, as the theme was also a npm package with its own dependencies and build process. `hexo generate` would build them concurrently.\n\nWe added the theme [git repo to package.json](https://github.com/wgkassem/wgkassem.github.io/blob/main/package.json).\n\n\n## Two: switch from `npm install` to `npm ci` in base target\n\nCurrent blog is packaged with npm [1]: <https://docs.npmjs.com/about-packages-and-modules>. The base needs to provide the necessary dependencies for the blog to build.\n\nTwo files are important here:\n\n1. package.json: specifies the package name, version, and dependencies.\n2. package-lock.json\n\nWe *do not* want to use `npm install` here because:\n\n1. it does not delete `node_modules` tree.\n2. it modifies `package.json` if a new package is added.\n3. it generates `package-lock.json` to describe the exact tree that was generated.\n\nLeading to **non-reproducible** builds.\n\nFor instance, consider calling the following problematic Dockerfile \n\n```dockerfile\nFROM node:22.5.1-alpine3.19 AS base\n\nCOPY package.json package-lock.json /workspace/\nRUN npm install\n\nFROM base AS build\n\nCOPY . /workspace # package*.json overwrite\nRUN npm run build\n```\n\nA correct `base` [Dockerfile](https://github.com/wgkassem/wgkassem.github.io/blob/main/Dockerfile) target is:\n\n```dockerfile\nFROM node:22.5.1-alpine3.19 AS base\n\nRUN apk add --no-cache git\nWORKDIR /workspace\nCOPY package.json /workspace/\nRUN npm ci\n```\n\n`npm ci` installs the exact dependencies listed in `package-lock.json` and does not modify `package.json` or `package-lock.json`.\n\n## Just build\n\nThe build target should not contain any `npm install` or `npm ci` commands. It should only contain the build command as everything *should* be installed in the base target.\n\n```dockerfile\nFROM base AS build\n\nCOPY . /workspace\nRUN npm run build\n```\n\n## Three: handling updates to `package.json` and `package-lock.json`\n\nThis required a little bit of creativity. Here's what we want to accomplish:\n\n1. A dev env a.k.a \"change, build, test\" workflow in \"real-time\".\n1. Avoid maintain two separate Dockerfiles.\n1. Allow changes to `package.json` and `package-lock.json` to git-commit.\n\n### The `dev` service\n\nFrom the `base` target, **mount** the source tree (instead of `COPY`). Ergo, the dev can/must run `npm install` / `npm ci` to update dependencies or node modules.\n\nThen `npm run build` to build the site with any new changes.\n\nThe service runs a persistent shell process.\n\n> [!NOTE]\n\nIf you wanted to use `docker` to re-build then you should probably use the prod target of the main Dockerfile instead.\n\n\n### The `serve` service\n\nSince we cannot now serve (i.e. run `nginx`) from the same container we are goingto use a separate service for that.\n\nThe serice as such binds to the source tree where `public/` is generated by `dev` service and runs nginx with default args.\n\n## Notes:\n\n1. `npm ci` disregards `node_modules`. Hence, using devcontainer will not affect production builds unless `package*.json` is/are updated.\n","slug":"npm_install","published":1,"updated":"2025-01-02T11:50:22.467Z","comments":1,"layout":"post","photos":[],"_id":"cm5faokhr0005gwovf5tn5beb","content":"<h2 id=\"Background\"><a href=\"#Background\" class=\"headerlink\" title=\"Background\"></a>Background</h2><p>Previously, we’ve been using a combination of <code>git submodule</code>, <code>npm install</code>, and <code>npm install --force</code> to build the blog. This has led to non-reproducible builds and a lot of confusion. Here’s how we can fix it.</p>\n<h2 id=\"One-switch-from-git-submodule-to-npm-for-theme-package\"><a href=\"#One-switch-from-git-submodule-to-npm-for-theme-package\" class=\"headerlink\" title=\"One: switch from git submodule to npm for theme package\"></a>One: switch from <code>git submodule</code> to <code>npm</code> for theme package</h2><p>Previously, we used <code>git submodule</code> to add the theme to the blog.<br>This caused some issues, as the theme was also a npm package with its own dependencies and build process. <code>hexo generate</code> would build them concurrently.</p>\n<p>We added the theme <a href=\"https://github.com/wgkassem/wgkassem.github.io/blob/main/package.json\">git repo to package.json</a>.</p>\n<h2 id=\"Two-switch-from-npm-install-to-npm-ci-in-base-target\"><a href=\"#Two-switch-from-npm-install-to-npm-ci-in-base-target\" class=\"headerlink\" title=\"Two: switch from npm install to npm ci in base target\"></a>Two: switch from <code>npm install</code> to <code>npm ci</code> in base target</h2><p>Current blog is packaged with npm [1]: <a href=\"https://docs.npmjs.com/about-packages-and-modules\">https://docs.npmjs.com/about-packages-and-modules</a>. The base needs to provide the necessary dependencies for the blog to build.</p>\n<p>Two files are important here:</p>\n<ol>\n<li>package.json: specifies the package name, version, and dependencies.</li>\n<li>package-lock.json</li>\n</ol>\n<p>We <em>do not</em> want to use <code>npm install</code> here because:</p>\n<ol>\n<li>it does not delete <code>node_modules</code> tree.</li>\n<li>it modifies <code>package.json</code> if a new package is added.</li>\n<li>it generates <code>package-lock.json</code> to describe the exact tree that was generated.</li>\n</ol>\n<p>Leading to <strong>non-reproducible</strong> builds.</p>\n<p>For instance, consider calling the following problematic Dockerfile </p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">FROM</span> node:<span class=\"number\">22.5</span>.<span class=\"number\">1</span>-alpine3.<span class=\"number\">19</span> AS base</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> package.json package-lock.json /workspace/</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm install</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> base AS build</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> . /workspace <span class=\"comment\"># package*.json overwrite</span></span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm run build</span></span><br></pre></td></tr></table></figure>\n\n<p>A correct <code>base</code> <a href=\"https://github.com/wgkassem/wgkassem.github.io/blob/main/Dockerfile\">Dockerfile</a> target is:</p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">FROM</span> node:<span class=\"number\">22.5</span>.<span class=\"number\">1</span>-alpine3.<span class=\"number\">19</span> AS base</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> apk add --no-cache git</span></span><br><span class=\"line\"><span class=\"keyword\">WORKDIR</span><span class=\"language-bash\"> /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> package.json /workspace/</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm ci</span></span><br></pre></td></tr></table></figure>\n\n<p><code>npm ci</code> installs the exact dependencies listed in <code>package-lock.json</code> and does not modify <code>package.json</code> or <code>package-lock.json</code>.</p>\n<h2 id=\"Just-build\"><a href=\"#Just-build\" class=\"headerlink\" title=\"Just build\"></a>Just build</h2><p>The build target should not contain any <code>npm install</code> or <code>npm ci</code> commands. It should only contain the build command as everything <em>should</em> be installed in the base target.</p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">FROM</span> base AS build</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> . /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm run build</span></span><br></pre></td></tr></table></figure>\n\n<h2 id=\"Three-handling-updates-to-package-json-and-package-lock-json\"><a href=\"#Three-handling-updates-to-package-json-and-package-lock-json\" class=\"headerlink\" title=\"Three: handling updates to package.json and package-lock.json\"></a>Three: handling updates to <code>package.json</code> and <code>package-lock.json</code></h2><p>This required a little bit of creativity. Here’s what we want to accomplish:</p>\n<ol>\n<li>A dev env a.k.a “change, build, test” workflow in “real-time”.</li>\n<li>Avoid maintain two separate Dockerfiles.</li>\n<li>Allow changes to <code>package.json</code> and <code>package-lock.json</code> to git-commit.</li>\n</ol>\n<h3 id=\"The-dev-service\"><a href=\"#The-dev-service\" class=\"headerlink\" title=\"The dev service\"></a>The <code>dev</code> service</h3><p>From the <code>base</code> target, <strong>mount</strong> the source tree (instead of <code>COPY</code>). Ergo, the dev can/must run <code>npm install</code> / <code>npm ci</code> to update dependencies or node modules.</p>\n<p>Then <code>npm run build</code> to build the site with any new changes.</p>\n<p>The service runs a persistent shell process.</p>\n<blockquote>\n<p>[!NOTE]</p>\n</blockquote>\n<p>If you wanted to use <code>docker</code> to re-build then you should probably use the prod target of the main Dockerfile instead.</p>\n<h3 id=\"The-serve-service\"><a href=\"#The-serve-service\" class=\"headerlink\" title=\"The serve service\"></a>The <code>serve</code> service</h3><p>Since we cannot now serve (i.e. run <code>nginx</code>) from the same container we are goingto use a separate service for that.</p>\n<p>The serice as such binds to the source tree where <code>public/</code> is generated by <code>dev</code> service and runs nginx with default args.</p>\n<h2 id=\"Notes\"><a href=\"#Notes\" class=\"headerlink\" title=\"Notes:\"></a>Notes:</h2><ol>\n<li><code>npm ci</code> disregards <code>node_modules</code>. Hence, using devcontainer will not affect production builds unless <code>package*.json</code> is/are updated.</li>\n</ol>\n","excerpt":"","more":"<h2 id=\"Background\"><a href=\"#Background\" class=\"headerlink\" title=\"Background\"></a>Background</h2><p>Previously, we’ve been using a combination of <code>git submodule</code>, <code>npm install</code>, and <code>npm install --force</code> to build the blog. This has led to non-reproducible builds and a lot of confusion. Here’s how we can fix it.</p>\n<h2 id=\"One-switch-from-git-submodule-to-npm-for-theme-package\"><a href=\"#One-switch-from-git-submodule-to-npm-for-theme-package\" class=\"headerlink\" title=\"One: switch from git submodule to npm for theme package\"></a>One: switch from <code>git submodule</code> to <code>npm</code> for theme package</h2><p>Previously, we used <code>git submodule</code> to add the theme to the blog.<br>This caused some issues, as the theme was also a npm package with its own dependencies and build process. <code>hexo generate</code> would build them concurrently.</p>\n<p>We added the theme <a href=\"https://github.com/wgkassem/wgkassem.github.io/blob/main/package.json\">git repo to package.json</a>.</p>\n<h2 id=\"Two-switch-from-npm-install-to-npm-ci-in-base-target\"><a href=\"#Two-switch-from-npm-install-to-npm-ci-in-base-target\" class=\"headerlink\" title=\"Two: switch from npm install to npm ci in base target\"></a>Two: switch from <code>npm install</code> to <code>npm ci</code> in base target</h2><p>Current blog is packaged with npm [1]: <a href=\"https://docs.npmjs.com/about-packages-and-modules\">https://docs.npmjs.com/about-packages-and-modules</a>. The base needs to provide the necessary dependencies for the blog to build.</p>\n<p>Two files are important here:</p>\n<ol>\n<li>package.json: specifies the package name, version, and dependencies.</li>\n<li>package-lock.json</li>\n</ol>\n<p>We <em>do not</em> want to use <code>npm install</code> here because:</p>\n<ol>\n<li>it does not delete <code>node_modules</code> tree.</li>\n<li>it modifies <code>package.json</code> if a new package is added.</li>\n<li>it generates <code>package-lock.json</code> to describe the exact tree that was generated.</li>\n</ol>\n<p>Leading to <strong>non-reproducible</strong> builds.</p>\n<p>For instance, consider calling the following problematic Dockerfile </p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">FROM</span> node:<span class=\"number\">22.5</span>.<span class=\"number\">1</span>-alpine3.<span class=\"number\">19</span> AS base</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> package.json package-lock.json /workspace/</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm install</span></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">FROM</span> base AS build</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> . /workspace <span class=\"comment\"># package*.json overwrite</span></span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm run build</span></span><br></pre></td></tr></table></figure>\n\n<p>A correct <code>base</code> <a href=\"https://github.com/wgkassem/wgkassem.github.io/blob/main/Dockerfile\">Dockerfile</a> target is:</p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">FROM</span> node:<span class=\"number\">22.5</span>.<span class=\"number\">1</span>-alpine3.<span class=\"number\">19</span> AS base</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> apk add --no-cache git</span></span><br><span class=\"line\"><span class=\"keyword\">WORKDIR</span><span class=\"language-bash\"> /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> package.json /workspace/</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm ci</span></span><br></pre></td></tr></table></figure>\n\n<p><code>npm ci</code> installs the exact dependencies listed in <code>package-lock.json</code> and does not modify <code>package.json</code> or <code>package-lock.json</code>.</p>\n<h2 id=\"Just-build\"><a href=\"#Just-build\" class=\"headerlink\" title=\"Just build\"></a>Just build</h2><p>The build target should not contain any <code>npm install</code> or <code>npm ci</code> commands. It should only contain the build command as everything <em>should</em> be installed in the base target.</p>\n<figure class=\"highlight dockerfile\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br></pre></td><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">FROM</span> base AS build</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">COPY</span><span class=\"language-bash\"> . /workspace</span></span><br><span class=\"line\"><span class=\"keyword\">RUN</span><span class=\"language-bash\"> npm run build</span></span><br></pre></td></tr></table></figure>\n\n<h2 id=\"Three-handling-updates-to-package-json-and-package-lock-json\"><a href=\"#Three-handling-updates-to-package-json-and-package-lock-json\" class=\"headerlink\" title=\"Three: handling updates to package.json and package-lock.json\"></a>Three: handling updates to <code>package.json</code> and <code>package-lock.json</code></h2><p>This required a little bit of creativity. Here’s what we want to accomplish:</p>\n<ol>\n<li>A dev env a.k.a “change, build, test” workflow in “real-time”.</li>\n<li>Avoid maintain two separate Dockerfiles.</li>\n<li>Allow changes to <code>package.json</code> and <code>package-lock.json</code> to git-commit.</li>\n</ol>\n<h3 id=\"The-dev-service\"><a href=\"#The-dev-service\" class=\"headerlink\" title=\"The dev service\"></a>The <code>dev</code> service</h3><p>From the <code>base</code> target, <strong>mount</strong> the source tree (instead of <code>COPY</code>). Ergo, the dev can/must run <code>npm install</code> / <code>npm ci</code> to update dependencies or node modules.</p>\n<p>Then <code>npm run build</code> to build the site with any new changes.</p>\n<p>The service runs a persistent shell process.</p>\n<blockquote>\n<p>[!NOTE]</p>\n</blockquote>\n<p>If you wanted to use <code>docker</code> to re-build then you should probably use the prod target of the main Dockerfile instead.</p>\n<h3 id=\"The-serve-service\"><a href=\"#The-serve-service\" class=\"headerlink\" title=\"The serve service\"></a>The <code>serve</code> service</h3><p>Since we cannot now serve (i.e. run <code>nginx</code>) from the same container we are goingto use a separate service for that.</p>\n<p>The serice as such binds to the source tree where <code>public/</code> is generated by <code>dev</code> service and runs nginx with default args.</p>\n<h2 id=\"Notes\"><a href=\"#Notes\" class=\"headerlink\" title=\"Notes:\"></a>Notes:</h2><ol>\n<li><code>npm ci</code> disregards <code>node_modules</code>. Hence, using devcontainer will not affect production builds unless <code>package*.json</code> is/are updated.</li>\n</ol>\n"},{"title":"Rejection from Amazon","description":"How to deal with rejection","date":"2024-12-31T15:00:00.000Z","_content":"\nOne of the most important skills I've had to learn, the hard way, is how to deal with rejection.\n\nIt's not a great start of the year, but I recently applied and was rejected from Amazon. It's difficult not to associate \"assessment\" with \"worth\" as the two are highly correlated. However, there's an important point to be made:\n\n> Your value as a person is not determined by the outcome of a job application.\n\n> The value you can bring to a role is the outcome of the craft you've honed over the years.\n\n> FAANG is not the reason your \"job sucks\", happiness in your job and life is not found in a company or a pay check.\n\nWhile I would have loved to start the year with a bang! I haven't been a software engineer for that long, and even for the time that I've been one the experience I've had was varied and not as deep as I would have liked.\n\nAll to say that I need to push forward with the craftsman mentality and keep working hard on improving.\n\nFor example, one of the most important lessons of the experience is the work I had to put in preparing for the assessment as well as the experience of going through the process.\n\nI did the Amazon leetcode path which showed me how much I enjoy problem-solving and optimizing. It showed me how much I enjoy and need to improve in C/C++. I also watched a few videos on the work simulation and culture fit assessment that introduced to some valuable life lessons.\n\nHere's what I decided to do next:\n\n1. Try and probe the recruiter for feedback on the rejection to help me understand what I could have done better.\n2. Keep doing leetcode while keeping a log of the problems I've solved to improve my DS&A skills.\n3. Keep applying, keep blogging, and keep learning.\n","source":"_posts/rejection.md","raw":"---\ntitle: Rejection from Amazon\ndescription: How to deal with rejection\ndate: 2025-01-01\ntags: [rejection, life]\ncategories:\n- [research, life]\n---\n\nOne of the most important skills I've had to learn, the hard way, is how to deal with rejection.\n\nIt's not a great start of the year, but I recently applied and was rejected from Amazon. It's difficult not to associate \"assessment\" with \"worth\" as the two are highly correlated. However, there's an important point to be made:\n\n> Your value as a person is not determined by the outcome of a job application.\n\n> The value you can bring to a role is the outcome of the craft you've honed over the years.\n\n> FAANG is not the reason your \"job sucks\", happiness in your job and life is not found in a company or a pay check.\n\nWhile I would have loved to start the year with a bang! I haven't been a software engineer for that long, and even for the time that I've been one the experience I've had was varied and not as deep as I would have liked.\n\nAll to say that I need to push forward with the craftsman mentality and keep working hard on improving.\n\nFor example, one of the most important lessons of the experience is the work I had to put in preparing for the assessment as well as the experience of going through the process.\n\nI did the Amazon leetcode path which showed me how much I enjoy problem-solving and optimizing. It showed me how much I enjoy and need to improve in C/C++. I also watched a few videos on the work simulation and culture fit assessment that introduced to some valuable life lessons.\n\nHere's what I decided to do next:\n\n1. Try and probe the recruiter for feedback on the rejection to help me understand what I could have done better.\n2. Keep doing leetcode while keeping a log of the problems I've solved to improve my DS&A skills.\n3. Keep applying, keep blogging, and keep learning.\n","slug":"rejection","published":1,"updated":"2025-01-02T12:23:17.246Z","_id":"cm5faoki0000rgwovdoge7ja6","comments":1,"layout":"post","photos":[],"content":"<p>One of the most important skills I’ve had to learn, the hard way, is how to deal with rejection.</p>\n<p>It’s not a great start of the year, but I recently applied and was rejected from Amazon. It’s difficult not to associate “assessment” with “worth” as the two are highly correlated. However, there’s an important point to be made:</p>\n<blockquote>\n<p>Your value as a person is not determined by the outcome of a job application.</p>\n</blockquote>\n<blockquote>\n<p>The value you can bring to a role is the outcome of the craft you’ve honed over the years.</p>\n</blockquote>\n<blockquote>\n<p>FAANG is not the reason your “job sucks”, happiness in your job and life is not found in a company or a pay check.</p>\n</blockquote>\n<p>While I would have loved to start the year with a bang! I haven’t been a software engineer for that long, and even for the time that I’ve been one the experience I’ve had was varied and not as deep as I would have liked.</p>\n<p>All to say that I need to push forward with the craftsman mentality and keep working hard on improving.</p>\n<p>For example, one of the most important lessons of the experience is the work I had to put in preparing for the assessment as well as the experience of going through the process.</p>\n<p>I did the Amazon leetcode path which showed me how much I enjoy problem-solving and optimizing. It showed me how much I enjoy and need to improve in C/C++. I also watched a few videos on the work simulation and culture fit assessment that introduced to some valuable life lessons.</p>\n<p>Here’s what I decided to do next:</p>\n<ol>\n<li>Try and probe the recruiter for feedback on the rejection to help me understand what I could have done better.</li>\n<li>Keep doing leetcode while keeping a log of the problems I’ve solved to improve my DS&A skills.</li>\n<li>Keep applying, keep blogging, and keep learning.</li>\n</ol>\n","excerpt":"","more":"<p>One of the most important skills I’ve had to learn, the hard way, is how to deal with rejection.</p>\n<p>It’s not a great start of the year, but I recently applied and was rejected from Amazon. It’s difficult not to associate “assessment” with “worth” as the two are highly correlated. However, there’s an important point to be made:</p>\n<blockquote>\n<p>Your value as a person is not determined by the outcome of a job application.</p>\n</blockquote>\n<blockquote>\n<p>The value you can bring to a role is the outcome of the craft you’ve honed over the years.</p>\n</blockquote>\n<blockquote>\n<p>FAANG is not the reason your “job sucks”, happiness in your job and life is not found in a company or a pay check.</p>\n</blockquote>\n<p>While I would have loved to start the year with a bang! I haven’t been a software engineer for that long, and even for the time that I’ve been one the experience I’ve had was varied and not as deep as I would have liked.</p>\n<p>All to say that I need to push forward with the craftsman mentality and keep working hard on improving.</p>\n<p>For example, one of the most important lessons of the experience is the work I had to put in preparing for the assessment as well as the experience of going through the process.</p>\n<p>I did the Amazon leetcode path which showed me how much I enjoy problem-solving and optimizing. It showed me how much I enjoy and need to improve in C/C++. I also watched a few videos on the work simulation and culture fit assessment that introduced to some valuable life lessons.</p>\n<p>Here’s what I decided to do next:</p>\n<ol>\n<li>Try and probe the recruiter for feedback on the rejection to help me understand what I could have done better.</li>\n<li>Keep doing leetcode while keeping a log of the problems I’ve solved to improve my DS&A skills.</li>\n<li>Keep applying, keep blogging, and keep learning.</li>\n</ol>\n"},{"title":"Semaphores","date":"2024-10-15T15:00:00.000Z","_content":"\n# Introduction\n\nSemaphores are a synchronization primitive that can be used to protect shared resources. They are used to control access to shared resources by multiple threads or processes.\n\n# Application\n\nA resource shared across threads or across processes, e.g. a shared memory space, a file (descriptor), or a network socket, and you need to ensure that no more\nthan 1-n threads (or processes) should access at a time. This is where [semaphores](https://en.wikipedia.org/wiki/Semaphore_%28programming%29) come in.\n\n# Mutex or Semaphore?\n\nA mutex on the other hand is there to ensure that no more than one thread can access (to read or write) a shared resource at a time. It is akin to a binary semaphore.\n\nHere's a comparison between the two as provided by ChatGPT:\n\n| Feature | Semaphore | Mutex |\n|------------------------|------------------------------------------------------|-------------------------------------------------------|\n| **Purpose** | Controls access to resources, allowing multiple threads to access (counting semaphore) or one (binary semaphore). | Ensures mutual exclusion, allowing only one thread to access a critical section. |\n| **Counter** | Maintains a count to track available resources. | Binary state: locked or unlocked (no counter). |\n| **Ownership** | No ownership; any thread can signal (release) a semaphore. | Ownership is enforced; only the thread that locks it can unlock it. |\n| **Concurrency** | Allows multiple threads to proceed if the counter is greater than 1 (in a counting semaphore). | Only one thread can proceed at a time. |\n| **Blocking Behavior** | Threads block if the counter is zero (no available resources). | Threads block if the mutex is locked. |\n| **Use Cases** | - Managing a pool of resources (e.g., thread pools, connection pools).<br>- Synchronizing producer-consumer workflows. | - Protecting critical sections.<br>- Ensuring exclusive access to shared data. |\n| **Types** | - Binary semaphore (similar to a mutex).<br>- Counting semaphore (allows multiple threads). | Only one type (binary lock). |\n| **Risk of Deadlock** | Higher risk if not used carefully (e.g., incorrect signaling order). | Lower risk due to strict ownership and locking rules. |\n| **Performance** | Slightly slower due to additional counter operations and flexibility. | Slightly faster because it enforces strict mutual exclusion. |\n| **Platform Support** | Available in most operating systems and threading libraries. | Available in most operating systems and threading libraries. |\n\n\nFor a very nice introduction to semaphores and their usage, [this post by Vikram Shukla](http://m.blog.chinaunix.net/uid-20341830-id-1701941.html) is a must-read.\n\n\n# POSIX Semaphores\n\n## Semaphore routines\n\nAn [overview of POSIX semaphore routines](https://man7.org/linux/man-pages/man7/sem_overview.7.html) is available via linux man pages.\n\n## Linux vs MacOS\n\nInterestingly, macOS does not support unnamed semaphores, [quora](https://www.quora.com/Why-does-OS-X-not-support-unnamed-semaphores).\nSo, if you are writing code that wants to comply with POSIX portability, you will need to use named semaphores.\n\n","source":"_posts/semaphores.md","raw":"---\ntitle: Semaphores\ndate: 2024-10-16\ntags: [concurrency, synchronization, low-level, c, c++, posix, linux, macos]\ncategories: [research]\n---\n\n# Introduction\n\nSemaphores are a synchronization primitive that can be used to protect shared resources. They are used to control access to shared resources by multiple threads or processes.\n\n# Application\n\nA resource shared across threads or across processes, e.g. a shared memory space, a file (descriptor), or a network socket, and you need to ensure that no more\nthan 1-n threads (or processes) should access at a time. This is where [semaphores](https://en.wikipedia.org/wiki/Semaphore_%28programming%29) come in.\n\n# Mutex or Semaphore?\n\nA mutex on the other hand is there to ensure that no more than one thread can access (to read or write) a shared resource at a time. It is akin to a binary semaphore.\n\nHere's a comparison between the two as provided by ChatGPT:\n\n| Feature | Semaphore | Mutex |\n|------------------------|------------------------------------------------------|-------------------------------------------------------|\n| **Purpose** | Controls access to resources, allowing multiple threads to access (counting semaphore) or one (binary semaphore). | Ensures mutual exclusion, allowing only one thread to access a critical section. |\n| **Counter** | Maintains a count to track available resources. | Binary state: locked or unlocked (no counter). |\n| **Ownership** | No ownership; any thread can signal (release) a semaphore. | Ownership is enforced; only the thread that locks it can unlock it. |\n| **Concurrency** | Allows multiple threads to proceed if the counter is greater than 1 (in a counting semaphore). | Only one thread can proceed at a time. |\n| **Blocking Behavior** | Threads block if the counter is zero (no available resources). | Threads block if the mutex is locked. |\n| **Use Cases** | - Managing a pool of resources (e.g., thread pools, connection pools).<br>- Synchronizing producer-consumer workflows. | - Protecting critical sections.<br>- Ensuring exclusive access to shared data. |\n| **Types** | - Binary semaphore (similar to a mutex).<br>- Counting semaphore (allows multiple threads). | Only one type (binary lock). |\n| **Risk of Deadlock** | Higher risk if not used carefully (e.g., incorrect signaling order). | Lower risk due to strict ownership and locking rules. |\n| **Performance** | Slightly slower due to additional counter operations and flexibility. | Slightly faster because it enforces strict mutual exclusion. |\n| **Platform Support** | Available in most operating systems and threading libraries. | Available in most operating systems and threading libraries. |\n\n\nFor a very nice introduction to semaphores and their usage, [this post by Vikram Shukla](http://m.blog.chinaunix.net/uid-20341830-id-1701941.html) is a must-read.\n\n\n# POSIX Semaphores\n\n## Semaphore routines\n\nAn [overview of POSIX semaphore routines](https://man7.org/linux/man-pages/man7/sem_overview.7.html) is available via linux man pages.\n\n## Linux vs MacOS\n\nInterestingly, macOS does not support unnamed semaphores, [quora](https://www.quora.com/Why-does-OS-X-not-support-unnamed-semaphores).\nSo, if you are writing code that wants to comply with POSIX portability, you will need to use named semaphores.\n\n","slug":"semaphores","published":1,"updated":"2025-01-02T11:50:22.469Z","comments":1,"layout":"post","photos":[],"_id":"cm5faoki1000sgwovhxfcats0","content":"<h1 id=\"Introduction\"><a href=\"#Introduction\" class=\"headerlink\" title=\"Introduction\"></a>Introduction</h1><p>Semaphores are a synchronization primitive that can be used to protect shared resources. They are used to control access to shared resources by multiple threads or processes.</p>\n<h1 id=\"Application\"><a href=\"#Application\" class=\"headerlink\" title=\"Application\"></a>Application</h1><p>A resource shared across threads or across processes, e.g. a shared memory space, a file (descriptor), or a network socket, and you need to ensure that no more<br>than 1-n threads (or processes) should access at a time. This is where <a href=\"https://en.wikipedia.org/wiki/Semaphore_%28programming%29\">semaphores</a> come in.</p>\n<h1 id=\"Mutex-or-Semaphore\"><a href=\"#Mutex-or-Semaphore\" class=\"headerlink\" title=\"Mutex or Semaphore?\"></a>Mutex or Semaphore?</h1><p>A mutex on the other hand is there to ensure that no more than one thread can access (to read or write) a shared resource at a time. It is akin to a binary semaphore.</p>\n<p>Here’s a comparison between the two as provided by ChatGPT:</p>\n<table>\n<thead>\n<tr>\n<th>Feature</th>\n<th>Semaphore</th>\n<th>Mutex</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><strong>Purpose</strong></td>\n<td>Controls access to resources, allowing multiple threads to access (counting semaphore) or one (binary semaphore).</td>\n<td>Ensures mutual exclusion, allowing only one thread to access a critical section.</td>\n</tr>\n<tr>\n<td><strong>Counter</strong></td>\n<td>Maintains a count to track available resources.</td>\n<td>Binary state: locked or unlocked (no counter).</td>\n</tr>\n<tr>\n<td><strong>Ownership</strong></td>\n<td>No ownership; any thread can signal (release) a semaphore.</td>\n<td>Ownership is enforced; only the thread that locks it can unlock it.</td>\n</tr>\n<tr>\n<td><strong>Concurrency</strong></td>\n<td>Allows multiple threads to proceed if the counter is greater than 1 (in a counting semaphore).</td>\n<td>Only one thread can proceed at a time.</td>\n</tr>\n<tr>\n<td><strong>Blocking Behavior</strong></td>\n<td>Threads block if the counter is zero (no available resources).</td>\n<td>Threads block if the mutex is locked.</td>\n</tr>\n<tr>\n<td><strong>Use Cases</strong></td>\n<td>- Managing a pool of resources (e.g., thread pools, connection pools).<br>- Synchronizing producer-consumer workflows.</td>\n<td>- Protecting critical sections.<br>- Ensuring exclusive access to shared data.</td>\n</tr>\n<tr>\n<td><strong>Types</strong></td>\n<td>- Binary semaphore (similar to a mutex).<br>- Counting semaphore (allows multiple threads).</td>\n<td>Only one type (binary lock).</td>\n</tr>\n<tr>\n<td><strong>Risk of Deadlock</strong></td>\n<td>Higher risk if not used carefully (e.g., incorrect signaling order).</td>\n<td>Lower risk due to strict ownership and locking rules.</td>\n</tr>\n<tr>\n<td><strong>Performance</strong></td>\n<td>Slightly slower due to additional counter operations and flexibility.</td>\n<td>Slightly faster because it enforces strict mutual exclusion.</td>\n</tr>\n<tr>\n<td><strong>Platform Support</strong></td>\n<td>Available in most operating systems and threading libraries.</td>\n<td>Available in most operating systems and threading libraries.</td>\n</tr>\n</tbody></table>\n<p>For a very nice introduction to semaphores and their usage, <a href=\"http://m.blog.chinaunix.net/uid-20341830-id-1701941.html\">this post by Vikram Shukla</a> is a must-read.</p>\n<h1 id=\"POSIX-Semaphores\"><a href=\"#POSIX-Semaphores\" class=\"headerlink\" title=\"POSIX Semaphores\"></a>POSIX Semaphores</h1><h2 id=\"Semaphore-routines\"><a href=\"#Semaphore-routines\" class=\"headerlink\" title=\"Semaphore routines\"></a>Semaphore routines</h2><p>An <a href=\"https://man7.org/linux/man-pages/man7/sem_overview.7.html\">overview of POSIX semaphore routines</a> is available via linux man pages.</p>\n<h2 id=\"Linux-vs-MacOS\"><a href=\"#Linux-vs-MacOS\" class=\"headerlink\" title=\"Linux vs MacOS\"></a>Linux vs MacOS</h2><p>Interestingly, macOS does not support unnamed semaphores, <a href=\"https://www.quora.com/Why-does-OS-X-not-support-unnamed-semaphores\">quora</a>.<br>So, if you are writing code that wants to comply with POSIX portability, you will need to use named semaphores.</p>\n","excerpt":"","more":"<h1 id=\"Introduction\"><a href=\"#Introduction\" class=\"headerlink\" title=\"Introduction\"></a>Introduction</h1><p>Semaphores are a synchronization primitive that can be used to protect shared resources. They are used to control access to shared resources by multiple threads or processes.</p>\n<h1 id=\"Application\"><a href=\"#Application\" class=\"headerlink\" title=\"Application\"></a>Application</h1><p>A resource shared across threads or across processes, e.g. a shared memory space, a file (descriptor), or a network socket, and you need to ensure that no more<br>than 1-n threads (or processes) should access at a time. This is where <a href=\"https://en.wikipedia.org/wiki/Semaphore_%28programming%29\">semaphores</a> come in.</p>\n<h1 id=\"Mutex-or-Semaphore\"><a href=\"#Mutex-or-Semaphore\" class=\"headerlink\" title=\"Mutex or Semaphore?\"></a>Mutex or Semaphore?</h1><p>A mutex on the other hand is there to ensure that no more than one thread can access (to read or write) a shared resource at a time. It is akin to a binary semaphore.</p>\n<p>Here’s a comparison between the two as provided by ChatGPT:</p>\n<table>\n<thead>\n<tr>\n<th>Feature</th>\n<th>Semaphore</th>\n<th>Mutex</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><strong>Purpose</strong></td>\n<td>Controls access to resources, allowing multiple threads to access (counting semaphore) or one (binary semaphore).</td>\n<td>Ensures mutual exclusion, allowing only one thread to access a critical section.</td>\n</tr>\n<tr>\n<td><strong>Counter</strong></td>\n<td>Maintains a count to track available resources.</td>\n<td>Binary state: locked or unlocked (no counter).</td>\n</tr>\n<tr>\n<td><strong>Ownership</strong></td>\n<td>No ownership; any thread can signal (release) a semaphore.</td>\n<td>Ownership is enforced; only the thread that locks it can unlock it.</td>\n</tr>\n<tr>\n<td><strong>Concurrency</strong></td>\n<td>Allows multiple threads to proceed if the counter is greater than 1 (in a counting semaphore).</td>\n<td>Only one thread can proceed at a time.</td>\n</tr>\n<tr>\n<td><strong>Blocking Behavior</strong></td>\n<td>Threads block if the counter is zero (no available resources).</td>\n<td>Threads block if the mutex is locked.</td>\n</tr>\n<tr>\n<td><strong>Use Cases</strong></td>\n<td>- Managing a pool of resources (e.g., thread pools, connection pools).<br>- Synchronizing producer-consumer workflows.</td>\n<td>- Protecting critical sections.<br>- Ensuring exclusive access to shared data.</td>\n</tr>\n<tr>\n<td><strong>Types</strong></td>\n<td>- Binary semaphore (similar to a mutex).<br>- Counting semaphore (allows multiple threads).</td>\n<td>Only one type (binary lock).</td>\n</tr>\n<tr>\n<td><strong>Risk of Deadlock</strong></td>\n<td>Higher risk if not used carefully (e.g., incorrect signaling order).</td>\n<td>Lower risk due to strict ownership and locking rules.</td>\n</tr>\n<tr>\n<td><strong>Performance</strong></td>\n<td>Slightly slower due to additional counter operations and flexibility.</td>\n<td>Slightly faster because it enforces strict mutual exclusion.</td>\n</tr>\n<tr>\n<td><strong>Platform Support</strong></td>\n<td>Available in most operating systems and threading libraries.</td>\n<td>Available in most operating systems and threading libraries.</td>\n</tr>\n</tbody></table>\n<p>For a very nice introduction to semaphores and their usage, <a href=\"http://m.blog.chinaunix.net/uid-20341830-id-1701941.html\">this post by Vikram Shukla</a> is a must-read.</p>\n<h1 id=\"POSIX-Semaphores\"><a href=\"#POSIX-Semaphores\" class=\"headerlink\" title=\"POSIX Semaphores\"></a>POSIX Semaphores</h1><h2 id=\"Semaphore-routines\"><a href=\"#Semaphore-routines\" class=\"headerlink\" title=\"Semaphore routines\"></a>Semaphore routines</h2><p>An <a href=\"https://man7.org/linux/man-pages/man7/sem_overview.7.html\">overview of POSIX semaphore routines</a> is available via linux man pages.</p>\n<h2 id=\"Linux-vs-MacOS\"><a href=\"#Linux-vs-MacOS\" class=\"headerlink\" title=\"Linux vs MacOS\"></a>Linux vs MacOS</h2><p>Interestingly, macOS does not support unnamed semaphores, <a href=\"https://www.quora.com/Why-does-OS-X-not-support-unnamed-semaphores\">quora</a>.<br>So, if you are writing code that wants to comply with POSIX portability, you will need to use named semaphores.</p>\n"}],"PostAsset":[],"PostCategory":[{"post_id":"cm5faokhr0005gwovf5tn5beb","category_id":"cm5faokhs0008gwov1j1g5vak","_id":"cm5faokht000dgwov1scxahq0"},{"post_id":"cm5faokho0003gwov5yn41v3d","category_id":"cm5faokhr0006gwovd75k07p1","_id":"cm5faokhu000hgwov4pjkd1py"},{"post_id":"cm5faokho0003gwov5yn41v3d","category_id":"cm5faokht000agwovay5cg29l","_id":"cm5faokhu000jgwov79tp0mvc"},{"post_id":"cm5faoki1000sgwovhxfcats0","category_id":"cm5faokhr0006gwovd75k07p1","_id":"cm5faoki2000ugwov5reu411g"},{"post_id":"cm5faoki0000rgwovdoge7ja6","category_id":"cm5faokhr0006gwovd75k07p1","_id":"cm5farprd0004hkovacz64y3f"},{"post_id":"cm5faoki0000rgwovdoge7ja6","category_id":"cm5farprc0001hkovgjl1dfdq","_id":"cm5farpre0006hkov9hncbqvz"}],"PostTag":[{"post_id":"cm5faokho0002gwovactb6ztb","tag_id":"cm5faokhp0004gwovbsz7hqfs","_id":"cm5faokht000cgwov2putg2o7"},{"post_id":"cm5faokho0002gwovactb6ztb","tag_id":"cm5faokhs0007gwovgqbec97k","_id":"cm5faokht000egwov60o735y9"},{"post_id":"cm5faokho0002gwovactb6ztb","tag_id":"cm5faokhs0009gwov5uwmg71v","_id":"cm5faokht000ggwovfyml52j5"},{"post_id":"cm5faokho0003gwov5yn41v3d","tag_id":"cm5faokht000bgwov9py440au","_id":"cm5faokhu000kgwovei0uewfg"},{"post_id":"cm5faokho0003gwov5yn41v3d","tag_id":"cm5faokht000fgwova0l01iix","_id":"cm5faokhu000lgwovetzwhhh9"},{"post_id":"cm5faokhr0005gwovf5tn5beb","tag_id":"cm5faokhu000igwov8qpm3e53","_id":"cm5faokhu000ogwovhdws42dh"},{"post_id":"cm5faokhr0005gwovf5tn5beb","tag_id":"cm5faokhu000mgwovhh9i7hpo","_id":"cm5faokhu000pgwov551hapfe"},{"post_id":"cm5faokhr0005gwovf5tn5beb","tag_id":"cm5faokhu000ngwov64kc6xag","_id":"cm5faokhv000qgwov2ngg0mac"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki2000tgwov2ucf8uu5","_id":"cm5faoki30012gwovhuu4eo2f"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki2000vgwov1g0y4uv8","_id":"cm5faoki30013gwovhto57eeb"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki2000wgwov0xlifh36","_id":"cm5faoki30014gwov494xbcax"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki2000xgwov486g2ze0","_id":"cm5faoki30015gwovegva5wfm"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki2000ygwov2q70gwb6","_id":"cm5faoki30016gwovg7as93in"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki2000zgwov4mlgd9m0","_id":"cm5faoki30017gwov1x2e2a69"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki30010gwovcqw1f0ic","_id":"cm5faoki30018gwovem268pyd"},{"post_id":"cm5faoki1000sgwovhxfcats0","tag_id":"cm5faoki30011gwov35lngtt3","_id":"cm5faoki30019gwov3gcuef7a"},{"post_id":"cm5faoki0000rgwovdoge7ja6","tag_id":"cm5farpra0000hkov4748cgrz","_id":"cm5farprd0003hkov67s54eh0"},{"post_id":"cm5faoki0000rgwovdoge7ja6","tag_id":"cm5farprd0002hkovhq4g2tgi","_id":"cm5farpre0005hkov2nvf7b6o"}],"Tag":[{"name":"lua","_id":"cm5faokhp0004gwovbsz7hqfs"},{"name":"scripting","_id":"cm5faokhs0007gwovgqbec97k"},{"name":"programming","_id":"cm5faokhs0009gwov5uwmg71v"},{"name":"craftsman","_id":"cm5faokht000bgwov9py440au"},{"name":"A Life Engineered","_id":"cm5faokht000fgwova0l01iix"},{"name":"npm","_id":"cm5faokhu000igwov8qpm3e53"},{"name":"devops","_id":"cm5faokhu000mgwovhh9i7hpo"},{"name":"docker","_id":"cm5faokhu000ngwov64kc6xag"},{"name":"concurrency","_id":"cm5faoki2000tgwov2ucf8uu5"},{"name":"synchronization","_id":"cm5faoki2000vgwov1g0y4uv8"},{"name":"low-level","_id":"cm5faoki2000wgwov0xlifh36"},{"name":"c","_id":"cm5faoki2000xgwov486g2ze0"},{"name":"c++","_id":"cm5faoki2000ygwov2q70gwb6"},{"name":"posix","_id":"cm5faoki2000zgwov4mlgd9m0"},{"name":"linux","_id":"cm5faoki30010gwovcqw1f0ic"},{"name":"macos","_id":"cm5faoki30011gwov35lngtt3"},{"name":"rejection","_id":"cm5farpra0000hkov4748cgrz"},{"name":"life","_id":"cm5farprd0002hkovhq4g2tgi"}]}}