From 2d9ae59c863436c9e93772ba9add88fe78e8d652 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 26 Feb 2024 04:04:46 +0000 Subject: [PATCH] deploy: 120dd4539635d10f2866e65883b81a07798bc981 --- 404.html | 2 +- ...s => 2022-09-06_hetzner-cloud-B9u-MxgU.js} | 2 +- ...c.js => 2022-12-31_typography-C35AONwX.js} | 2 +- ...8nsUk.js => 2023-01-01_deploy-Bh3tgLQ9.js} | 2 +- ...-CnHF8_tj.js => 2023-01-10_vs-Dpo3fFRu.js} | 2 +- ...j5SqpT.js => 2023-01-11_rider-C1RjBW7K.js} | 2 +- ...jTU3tE.js => 2023-01-21_start-Dvy20kPM.js} | 2 +- ...T.js => 2023-02-01_javascript-DsU9PqrK.js} | 2 +- ...r7.js => 2023-03-30_razor-ssg-h6EyxEND.js} | 2 +- ...3_razor-ssg-new-blog-features-DJ1Rr8VN.js} | 2 +- ...23-11-20_net8-blazor-template-csCQIEk-.js} | 2 +- ...> 2023-11-22_net8-best-blazor-B8AK7TtK.js} | 2 +- ...28_markdown-components-in-vue-OgPNuM_j.js} | 2 +- ... 2024-03-01_vite-press-plugin-DJwsPj6t.js} | 54 +++++++++---------- ...e_type_script_setup_true_lang-DMQXQGLg.js} | 2 +- ...hartJs-I6khMjFE.js => ChartJs-ljXEK9mH.js} | 2 +- ...e_type_script_setup_true_lang-CEPiro_Z.js} | 2 +- ...e_type_script_setup_true_lang-BcGdWgS3.js} | 2 +- ...e_type_script_setup_true_lang-DrkDEcx3.js} | 2 +- ...e_type_script_setup_true_lang-CsTUuBVZ.js} | 2 +- ...e_type_script_setup_true_lang-BiYTyr_j.js} | 2 +- ...e_type_script_setup_true_lang-BUJJyXxz.js} | 2 +- ...e_type_script_setup_true_lang-8Ivl7FzK.js} | 2 +- ...e_type_script_setup_true_lang-Cko02hll.js} | 2 +- ....all_-ByINYo4N.js => _...all_-DOrRbYkV.js} | 2 +- ...{_name_-D0WdA550.js => _name_-D5H8wJy-.js} | 2 +- ...{_slug_-D0R-lY2g.js => _slug_-BaiPQcvV.js} | 2 +- .../{_tag_-A7_HVUVC.js => _tag_-Bl8Dgnay.js} | 2 +- ...{_year_-bjfw_pb5.js => _year_-C2Zxurez.js} | 2 +- .../{about-C5lL5M9L.js => about-CSevwr_F.js} | 2 +- .../{admin-ddEAmk2a.js => admin-DfK6L5xt.js} | 2 +- ...-B8jP3C5m.js => autoquerygrid-CYIg7oz6.js} | 2 +- assets/{blog-DsWHVwkJ.js => blog-NLNSyVmF.js} | 2 +- ...0AHB4nY.js => component-links-B6Jg27wb.js} | 2 +- ...nts-D8n2u9I9.js => components-Q0dmsTg-.js} | 2 +- ...ounter-BqsUn9iq.js => counter-DSxYdCIG.js} | 2 +- ...efault-Bpx-Aajc.js => default-Caiy_OVN.js} | 2 +- .../{empty-BlQdiYK7.js => empty-u1n3FCjQ.js} | 2 +- ...ture1-BJlXHRzt.js => feature1-CYSjmA7I.js} | 2 +- ...ture1-B0cK-EMF.js => feature1-CvHTx5Sl.js} | 2 +- ...ture1-B9tl-y8M.js => feature1-FhqPQYoT.js} | 2 +- ...tures-DgyWH2Q5.js => features-nHCxd1P1.js} | 2 +- .../{index-B-kKBcPB.js => index-CoFPLbfm.js} | 8 +-- .../{index-BG5anPub.js => index-Da1NoZ0N.js} | 2 +- .../{index-DB65REeY.js => index-Db6kjhtf.js} | 2 +- assets/{logo-DspwJfOt.js => logo-BG60RFri.js} | 2 +- ...{modern-CCyvQdVa.js => modern-DHYi0nI9.js} | 2 +- ...rivacy-CgZlqKfp.js => privacy-BP3kbvHT.js} | 2 +- .../{utils-D7bH4Tlo.js => utils-BDrlE94o.js} | 2 +- ...{videos-B48T2Bqr.js => videos-DZLBdRXH.js} | 2 +- ...tsnew-DLwuVrUY.js => whatsnew-CZ_1B3HR.js} | 2 +- index.html | 2 +- 52 files changed, 81 insertions(+), 81 deletions(-) rename assets/{2022-09-06_hetzner-cloud-CMGV4KKw.js => 2022-09-06_hetzner-cloud-B9u-MxgU.js} (99%) rename assets/{2022-12-31_typography-CQ2u4p7c.js => 2022-12-31_typography-C35AONwX.js} (98%) rename assets/{2023-01-01_deploy-DS48nsUk.js => 2023-01-01_deploy-Bh3tgLQ9.js} (98%) rename assets/{2023-01-10_vs-CnHF8_tj.js => 2023-01-10_vs-Dpo3fFRu.js} (98%) rename assets/{2023-01-11_rider-BIj5SqpT.js => 2023-01-11_rider-C1RjBW7K.js} (98%) rename assets/{2023-01-21_start-BLjTU3tE.js => 2023-01-21_start-Dvy20kPM.js} (98%) rename assets/{2023-02-01_javascript-BozINeQT.js => 2023-02-01_javascript-DsU9PqrK.js} (99%) rename assets/{2023-03-30_razor-ssg-Ci0fv4r7.js => 2023-03-30_razor-ssg-h6EyxEND.js} (99%) rename assets/{2023-08-23_razor-ssg-new-blog-features-DA5S93ND.js => 2023-08-23_razor-ssg-new-blog-features-DJ1Rr8VN.js} (99%) rename assets/{2023-11-20_net8-blazor-template-BS9qPuaN.js => 2023-11-20_net8-blazor-template-csCQIEk-.js} (97%) rename assets/{2023-11-22_net8-best-blazor-wjwjFuPp.js => 2023-11-22_net8-best-blazor-B8AK7TtK.js} (99%) rename assets/{2024-02-28_markdown-components-in-vue-BMrj5Q1x.js => 2024-02-28_markdown-components-in-vue-OgPNuM_j.js} (98%) rename assets/{2024-03-01_vite-press-plugin-BV6PDf7d.js => 2024-03-01_vite-press-plugin-DJwsPj6t.js} (63%) rename assets/{BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js => BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js} (95%) rename assets/{ChartJs-I6khMjFE.js => ChartJs-ljXEK9mH.js} (84%) rename assets/{Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js => Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js} (70%) rename assets/{GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js => GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js} (98%) rename assets/{HelloApi.vue_vue_type_script_setup_true_lang-BNRlbX2m.js => HelloApi.vue_vue_type_script_setup_true_lang-DrkDEcx3.js} (95%) rename assets/{MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js => MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js} (88%) rename assets/{MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js => MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js} (78%) rename assets/{SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js => SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js} (93%) rename assets/{Templates.vue_vue_type_script_setup_true_lang-DajVBfQg.js => Templates.vue_vue_type_script_setup_true_lang-8Ivl7FzK.js} (99%) rename assets/{VideoGroup.vue_vue_type_script_setup_true_lang-yt9KRqcL.js => VideoGroup.vue_vue_type_script_setup_true_lang-Cko02hll.js} (94%) rename assets/{_...all_-ByINYo4N.js => _...all_-DOrRbYkV.js} (92%) rename assets/{_name_-D0WdA550.js => _name_-D5H8wJy-.js} (90%) rename assets/{_slug_-D0R-lY2g.js => _slug_-BaiPQcvV.js} (98%) rename assets/{_tag_-A7_HVUVC.js => _tag_-Bl8Dgnay.js} (91%) rename assets/{_year_-bjfw_pb5.js => _year_-C2Zxurez.js} (93%) rename assets/{about-C5lL5M9L.js => about-CSevwr_F.js} (98%) rename assets/{admin-ddEAmk2a.js => admin-DfK6L5xt.js} (91%) rename assets/{autoquerygrid-B8jP3C5m.js => autoquerygrid-CYIg7oz6.js} (92%) rename assets/{blog-DsWHVwkJ.js => blog-NLNSyVmF.js} (98%) rename assets/{component-links-B0AHB4nY.js => component-links-B6Jg27wb.js} (85%) rename assets/{components-D8n2u9I9.js => components-Q0dmsTg-.js} (91%) rename assets/{counter-BqsUn9iq.js => counter-DSxYdCIG.js} (82%) rename assets/{default-Bpx-Aajc.js => default-Caiy_OVN.js} (96%) rename assets/{empty-BlQdiYK7.js => empty-u1n3FCjQ.js} (81%) rename assets/{feature1-BJlXHRzt.js => feature1-CYSjmA7I.js} (94%) rename assets/{feature1-B0cK-EMF.js => feature1-CvHTx5Sl.js} (94%) rename assets/{feature1-B9tl-y8M.js => feature1-FhqPQYoT.js} (93%) rename assets/{features-DgyWH2Q5.js => features-nHCxd1P1.js} (95%) rename assets/{index-B-kKBcPB.js => index-CoFPLbfm.js} (99%) rename assets/{index-BG5anPub.js => index-Da1NoZ0N.js} (90%) rename assets/{index-DB65REeY.js => index-Db6kjhtf.js} (88%) rename assets/{logo-DspwJfOt.js => logo-BG60RFri.js} (85%) rename assets/{modern-CCyvQdVa.js => modern-DHYi0nI9.js} (91%) rename assets/{privacy-CgZlqKfp.js => privacy-BP3kbvHT.js} (97%) rename assets/{utils-D7bH4Tlo.js => utils-BDrlE94o.js} (84%) rename assets/{videos-B48T2Bqr.js => videos-DZLBdRXH.js} (75%) rename assets/{whatsnew-DLwuVrUY.js => whatsnew-CZ_1B3HR.js} (94%) diff --git a/404.html b/404.html index 8be181c..90900ef 100644 --- a/404.html +++ b/404.html @@ -5,7 +5,7 @@ Vite + Vue + TS - + diff --git a/assets/2022-09-06_hetzner-cloud-CMGV4KKw.js b/assets/2022-09-06_hetzner-cloud-B9u-MxgU.js similarity index 99% rename from assets/2022-09-06_hetzner-cloud-CMGV4KKw.js rename to assets/2022-09-06_hetzner-cloud-B9u-MxgU.js index 48e56a2..48db81c 100644 --- a/assets/2022-09-06_hetzner-cloud-CMGV4KKw.js +++ b/assets/2022-09-06_hetzner-cloud-B9u-MxgU.js @@ -1,3 +1,3 @@ -import{_ as n}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o as i,h as l,w as u,a as e,e as t}from"./index-B-kKBcPB.js";const d=e("div",{class:"markdown-body"},[e("p",null,[t("At "),e("a",{href:"./"},"ServiceStack"),t(", we have been using AWS for hosting for over 10 years. It has served us well, but it suffers from complex pricing and possibility of bill shock due to its fractured pay-as-you-go design.")]),e("p",null,[t("Thankfully, more and more companies are providing simpler offerings for hosting needs, and AWS themselves launched "),e("a",{href:"https://aws.amazon.com/lightsail"},"Lightsail"),t(" as their answer to market demands for simple hosting options that package everything you need for basic hosting.")]),e("p",null,"These simpler hosting options tend to bundle several things together as one fixed monthly price. A VM with a specific compute and memory allocation, as well as data transfer, and storage."),e("h2",null,"Looking at different US offerings"),e("p",null,[t("Something we wanted to do was to host our "),e("a",{href:"https://github.com/ServiceStackApps/LiveDemos"},"live demo applications"),t(" on a US based host. We were using "),e("a",{href:"https://www.hetzner.com/dedicated-rootserver"},"Hetzner dedicated servers"),t(" in the past for non-latency sensitive use cases like our build server and "),e("a",{href:"https://gist.cafe"},"Gist.Cafe (our interactive playground for multiple platforms)"),t(" but we also wanted our demo applications to be snappy for US users.")]),e("p",null,[e("a",{href:"https://www.digitalocean.com/pricing"},"DigitalOcean"),t(" provides "),e("a",{href:"https://www.digitalocean.com/pricing/droplets"},"“Droplets”"),t(" with this fixed pricing model with a nice and simple interface. Their pricing was quite good and we realized we could run all 20+ of our demo applications on a single droplet for $40/month.")]),e("p",null,[t("For deployment, "),e("a",{href:"https://docs.servicestack.net/do-github-action-mix-deployment"},"we also like to keep things as simple as we can, whilst keeping portability"),t(". Since all our projects are public and on GitHub, we use "),e("a",{href:"https://docs.servicestack.net/do-github-action-mix-deployment#github-repository-setup"},"GitHub Actions"),t(" heavily along with a pattern that deploys our applications using Docker Compose via SSH. Each application runs in its own container behind an "),e("a",{href:"https://docs.servicestack.net/do-github-action-mix-deployment#get-nginx-reverse-proxy-and-letsencrypt-companion-running"},"NGINX proxy"),t(" with a side car that handles renewing LetsEncrypt certificates. Below is an example of this pattern with Blazor and Litestream.")]),e("iframe",{class:"youtube",src:"https://www.youtube.com/embed/fY50dWszpw4",frameborder:"0",allow:"autoplay; encrypted-media",allowfullscreen:""}),e("p",null,"A nice side effect of this approach is moving servers is relatively painless. We change the DNS entry for the application to point to our new server, update the GitHub Action Secrets if needed and run our Release workflow."),e("p",null,[t("A minute or so later, the application is back running again. Since their were 20+ of these repositories we took advantage of the "),e("a",{href:"https://cli.github.com/manual/gh_secret_set"},"GitHub Organization Secrets"),t(" so we only needed to update values in one place, and "),e("a",{href:"https://cli.github.com/manual/gh_workflow_run"},"running the workflows again"),t(" can also be done programmatically through the GitHub CLI.")]),e("h2",null,"DigitalOcean Price Increase"),e("p",null,[t("In June of 2022, we got a notification that "),e("a",{href:"https://www.digitalocean.com/try/new-pricing"},"prices for droplets would be increasing"),t(", and for our droplet it would be going from "),e("strong",null,"$40 to $48"),t(". While this is a small amount of money, it prompted us to have a wider look into this market.")]),e("p",null,"Something we try to do at ServiceStack is to not only provide a comprehensive .NET Framework for building API first systems, but also seek out great value hosting options we can recommend in this ever change space which we’re happy to share, like this blog post, that might be useful to our users and others."),e("p",null,[t("Not everyone builds massively distributed systems, and as hardware performance increases, and platforms like "),e("a",{href:"https://devblogs.microsoft.com/dotnet/performance-improvements-in-aspnet-core-6"},".NET are becoming even more optimized"),t(", a setup with just a server or two can manage larger loads and use cases.")]),e("p",null,[t("Our research and evaluations ended up right back at "),e("a",{href:"https://www.hetzner.com/cloud"},"Hetzner but this time with their Cloud offering"),t(". For less than "),e("strong",null,"$15 USD"),t(" per month, you can get a "),e("strong",null,"4 vCPU, 8GB RAM, 160GB storage and 20TB"),t(" of data transfer "),e("strong",null,"hosted in the US"),t(".")]),e("p",null,"We found this was by far the cheapest offering for a simple fixed monthly hosting, and looked to compare how well it performed against the more traditional cloud hosting setups."),e("h2",null,"Litestream and SQLite"),e("p",null,[t("Our demo applications use "),e("a",{href:"https://www.sqlite.org"},"SQLite"),t(" as a simple way to host the database storage and application together, taking advantage of SQLite’s embedded nature. We were also testing out "),e("a",{href:"https://litestream.io"},"Litestream"),t(" as a possible solution to the lack of data backups and safety when using SQLite for more production like workloads.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("a",{href:"https://litestream.io"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/litestream.svg",alt:""})]),e("div",{class:"text-gray-500 text-center"},"litestream.io")])]),e("p",null,[t("Litestream runs as a separate process and watches your SQLite file for changes and replicates them to storage options like AWS S3, Azure Blob storage and SFTP. "),e("a",{href:"https://docs.servicestack.net/ormlite/litestream"},"We created several templates to make this easier"),t(" and provide a way to bake in automated disaster recovery using Litestream when used with GitHub Actions and our SSH with Docker Compose deployment.")]),e("p",null,"With some basic load testing, we noticed that SQLite performed pretty well without any effort on our part, and decided we should see how this compares to the commonly suggested hosting patterns provided by the large cloud providers of AWS and Azure."),e("p",null,"We used the recommended “Production” setups provided by AWS RDS and Azure SQL Database wizards along with 2 vCPU application server to provide the basis on our comparison. The reason we chose to use the suggested defaults from these providers was to illustrate the power of defaults when offered by market leaders. When compared to a simple SQLite setup, and providers that offer fixed monthly pricing like Hetzner and DigitalOcean, which is often enough to small companies selling Business to Business (B2B) solutions, AWS and Azure recommended “Production” environments can look extremely over priced."),e("p",null,"One of the main reasons managed database solutions are chosen is the fact that they take care of automated backups and restore if things go wrong. There are other nice features that definitely have a lot of value, but managed disaster recovery is probably the most commonly cited one I’ve come across for why services like RDS are chosen during early development."),e("p",null,"Litestream provides this kind of data safety and disaster recovery functionality by targeting cost effective and robust storage solutions like AWS S3 and other cloud provided object stores, and making the backup process close to real-time, and accessible via their CLI. And the embedded nature of SQLite removes the uncertainty of the process of upgrading your database."),e("h2",null,"The Test"),e("p",null,[t("To get a clearer idea how each of these hosting options perform with a fairly modest workload, we used a "),e("a",{href:"https://gatling.io"},"Gatling"),t(" test to simulate a user logging into our sample Bookings application, browsing around and creating a booking.")]),e("p",null,"These series of steps had 2 write requests and 8 read, separated by 2 seconds per step. We then setup a Gatling simulation that ramped up adding new users to our system from 5 per second to 15 per second, to add a growing number of users over 10 minutes, then sustained over another 10 minutes."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/aws-gatling-result.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"AWS Gatling Result.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/azure-gatling-result.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Azure Gatling Result.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/hetzner-gatling-result.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Hetzner Gatling Result.")]),e("p",null,[t("All 3 setups could handle this rate of requests without issue, and though the “Recommended” AWS and Azure setups would have more headroom, the price difference is far too large to ignore, especially as the difference is paid every month. The requests throughput of that this test illustrated ~100rps can suit many many use cases, and SQLite is "),e("a",{href:"https://www.sqlite.org/whentouse.html#:~:text=An%20SQLite%20database%20is%20limited,to%20something%20less%20than%20this."},"really only limited by its single writer design"),t(". We did previous tests of upto 250rps on the same Hetzner Cloud instance with SQLite, but this was starting to reach the maximum throughput, again purely to do with the single writer limitation.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/litestream-costs.svg",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Previous test result price comparison without AWS using Provisioned IOPS.")]),e("p",null,[t("This level of throughput is enough to service many kinds of businesses with a drastically more simple system to manage, with large cost savings. Also, with the use of an ORM like "),e("a",{href:"https://docs.servicestack.net/ormlite"},"OrmLite"),t(", switching to another database provider can be migrated if and when the traditional offerings like Postgres are needed.")]),e("h2",null,"The Setups"),e("p",null,"The original setup for tests we did in June didn’t default to provisioned IOPs for AWS, but when repeating the tests AWS costs blow out due to this feature being enabled by default."),e("p",null,[t("Without provisioned IOPs, it drops to around "),e("strong",null,"$132/month"),t(" as an estimated cost. The "),e("strong",null,"$300/month"),t(" default feature for a “Production” database is very hard for AWS to justify, and I think more of a sign of their poor performing GP2 storage option. Although this will only impact very “chatty” types of applications that need higher IOPs throughput, the difference in performance from RDS vs providers like DigitalOcean and Hetzner can be quite stark.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/aws-rds-with-provisioned-iops.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"AWS RDS now defaults to provisioned IOPs for a Production setup, drastically increasing costs.")]),e("table",null,[e("thead",null,[e("tr",null,[e("th"),e("th",null,"AWS (DB)"),e("th",null,"AWS (App)"),e("th",null,"Azure (DB)"),e("th",null,"Azure (App)"),e("th",null,"DigitalOcean"),e("th",null,"Hetzner Cloud")])]),e("tbody",null,[e("tr",null,[e("td",null,"vCPU"),e("td",null,"2"),e("td",null,"2"),e("td",null,"4"),e("td",null,"2"),e("td",null,"4"),e("td",null,"4")]),e("tr",null,[e("td",null,"Memory (GB)"),e("td",null,"8"),e("td",null,"4"),e("td",null,"10"),e("td",null,"8"),e("td",null,"8"),e("td",null,"8")]),e("tr",null,[e("td",null,"Storage (GB)"),e("td",null,"100 (provisioned)"),e("td",null,"16"),e("td",null,"32"),e("td",null,"30"),e("td",null,"160"),e("td",null,"160")]),e("tr",null,[e("td",null,"Cost"),e("td",null,"$442"),e("td",null,"$34"),e("td",null,"$373"),e("td",null,"$70"),e("td",null,"$48"),e("td",null,"$15")])])]),e("p",null,"The above specs were provided as “Production” defaults when using a single database instance. Azure SQL Database defaults to costing $373, during the load test, the database CPU hit ~25%."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/azure-db-cpu-during-test.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Azure SQL database without tuning performs poorly for cost, likely due to lack of indexes")]),e("table",null,[e("thead",null,[e("tr",null,[e("th"),e("th",null,"AWS (DB)"),e("th",null,"AWS (App)"),e("th",null,"Azure (DB)"),e("th",null,"Azure (App)"),e("th",null,"Hetzner Cloud")])]),e("tbody",null,[e("tr",null,[e("td",null,"Max CPU %"),e("td",null,"8"),e("td",null,"35"),e("td",null,"25"),e("td",null,"45"),e("td",null,"40")])])]),e("p",null,"This is without any tuning on any of the databases, so while you like more performance out of the recommended setups, it is still clear SQLite performs well by default, and it is well worth considering not only Hetzner Cloud for value for money, but if your use can only needs a single host with SQLite."),e("h2",null,"Hetzner Cloud"),e("p",null,"While we were primarily looking for one of the lowest cost options with simplified pricing, Hetzner Cloud pleasantly surprised us with a few features the larger providers could learn from."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/hetzner-cloud-buy.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Hetzner Cloud Pricing.")]),e("h3",null,"Creating a new instance is fast"),e("p",null,[t("Most of the time if will be ready to remote to before you can open your terminal. Not sure if this is due to some kind of pre-creation process on Hetzner part during the creation screen, but everything is very responsive. In my testing from the time the “Create” button was clicked, my SSH commands would succeed within "),e("strong",null,"20 seconds"),t(".")]),e("h3",null,"Live Graphs"),e("p",null,"Another part of the responsiveness is their “Live” graphs for monitoring. It is surprisingly low latency and an extremely stark difference between AWS charging extra for “Detailed” monitoring on EC2 instances. The graphs update every 3-5 seconds in the browser and look to be over a few seconds behind real-time."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/hetzner-cloud-live-graphs.gif",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Live monitoring updates every 3-5 seconds.")]),e("p",null,"CloudWatch is a major value add for AWS, and Hetzner’s offering is very very basic in comparison, but it is nice to see live updating stats right in your web browser, and something hopefully the other providers can also offer in the future."),e("h3",null,"Price"),e("p",null,[t("This is the biggest draw card by a long way. The AWS and Azure “recommended” setups are extremely expensive for the hardware and performance they offer. Yes they are mature cloud offerings with a large array of features, but their "),e("strong",null,"pricing scales with hardware resources"),t(". Products like "),e("strong",null,"Provisioned IOPs"),t(" are extremely expensive, and when other cloud providers are offering far more performant and competitive storage with their instances, it can feel like AWS is using it’s market share and their defaults to upsell very expensive products.")]),e("h3",null,"Transfer costs"),e("p",null,[t("It’s been long known that one of the ways large cloud providers keep customers in their network is by charging "),e("a",{href:"https://aws.amazon.com/blogs/architecture/overview-of-data-transfer-costs-for-common-architectures"},"excessively large and complex data egress costs"),t(". Something attractive about simplified pricing from Hetzner Cloud (and DigitalOcean to a lesser degree) is the included data transfer of 20TB a month.")]),e("p",null,[t("Not only is AWS data transfer pricing extremely complicated (inter region vs cross region vs CloudFront vs Transit Gateway and so on), but if your application was sending a lot of data to clients, that same "),e("strong",null,"20TB"),t(" you get for free with a "),e("strong",null,"$15 server"),t(", would cost "),e("strong",null,"$1,791 just for data"),t(" when coming from AWS. Azure pricing also confusing, and in some ways more expensive.")]),e("h2",null,"Defaults are powerful"),e("p",null,"Both AWS and Azure “recommended” defaults are there not because the software selected (SQL Server and Postgres) need that amount of resources just to operate, but more as an upsell. Lots of projects and applications absolutely do not need features like “Provisioned IOPs”, despite GP2 storage of AWS being incredibly slow."),e("p",null,[t("Performing disk speed check using the Linux utility "),e("code",null,"fio"),t(" an AWS EC2 instance with 100GB GP2 storage can do ~2250 IOPS and 9MB/s read, and ~750 IOPs at 3MB/s write. In contrast, Digital Ocean $48 instance, this is not even paying the extra $8/month for the faster storage can do 35.2k IOPS at 144MB/s read, and 11.8k IOPS at 48MB/s write.")]),e("p",null,"Hetzner again is the stand out, with the $15 instance tests resulting in 50.8k IOPS at 207MB/s read, and 16.9k IOPS at 69MB/s write."),e("table",null,[e("thead",null,[e("tr",null,[e("th"),e("th",null,"Read IOPS"),e("th",null,"Write IOPs"),e("th",null,"Read MBs"),e("th",null,"Write MBs")])]),e("tbody",null,[e("tr",null,[e("td",null,"AWS"),e("td",null,"2.3k"),e("td",null,"0.8k"),e("td",null,"9.2 MB/s"),e("td",null,"3.1 MB/s")]),e("tr",null,[e("td",null,"Azure"),e("td",null,"3.0k"),e("td",null,"1.0k"),e("td",null,"12.5 MB/s"),e("td",null,"4.2 MB/s")]),e("tr",null,[e("td",null,"DigitalOcean"),e("td",null,"35.2k"),e("td",null,"11.8k"),e("td",null,"144 MB/s"),e("td",null,"48.2 MB/s")]),e("tr",null,[e("td",null,"Hetzner Cloud"),e("td",null,"50.5k"),e("td",null,"16.9k"),e("td",null,"207 MB/s"),e("td",null,"69.2 MB/s")])])]),e("p",null,[t("All tests used the following "),e("code",null,"fio"),t(" command.")]),e("pre",{class:"language-shell"},[e("code",{class:"language-shell"},[t("fio "),e("span",{class:"token parameter variable"},"--randrepeat"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"1"),t(),e("span",{class:"token parameter variable"},"--ioengine"),e("span",{class:"token operator"},"="),t("libaio "),e("span",{class:"token parameter variable"},"--direct"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"1"),t(),e("span",{class:"token parameter variable"},"--gtod_reduce"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"1"),t(),e("span",{class:"token parameter variable"},"--name"),e("span",{class:"token operator"},"="),t("test "),e("span",{class:"token punctuation"},"\\"),t(` +import{_ as n}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o as i,h as l,w as u,a as e,e as t}from"./index-CoFPLbfm.js";const d=e("div",{class:"markdown-body"},[e("p",null,[t("At "),e("a",{href:"./"},"ServiceStack"),t(", we have been using AWS for hosting for over 10 years. It has served us well, but it suffers from complex pricing and possibility of bill shock due to its fractured pay-as-you-go design.")]),e("p",null,[t("Thankfully, more and more companies are providing simpler offerings for hosting needs, and AWS themselves launched "),e("a",{href:"https://aws.amazon.com/lightsail"},"Lightsail"),t(" as their answer to market demands for simple hosting options that package everything you need for basic hosting.")]),e("p",null,"These simpler hosting options tend to bundle several things together as one fixed monthly price. A VM with a specific compute and memory allocation, as well as data transfer, and storage."),e("h2",null,"Looking at different US offerings"),e("p",null,[t("Something we wanted to do was to host our "),e("a",{href:"https://github.com/ServiceStackApps/LiveDemos"},"live demo applications"),t(" on a US based host. We were using "),e("a",{href:"https://www.hetzner.com/dedicated-rootserver"},"Hetzner dedicated servers"),t(" in the past for non-latency sensitive use cases like our build server and "),e("a",{href:"https://gist.cafe"},"Gist.Cafe (our interactive playground for multiple platforms)"),t(" but we also wanted our demo applications to be snappy for US users.")]),e("p",null,[e("a",{href:"https://www.digitalocean.com/pricing"},"DigitalOcean"),t(" provides "),e("a",{href:"https://www.digitalocean.com/pricing/droplets"},"“Droplets”"),t(" with this fixed pricing model with a nice and simple interface. Their pricing was quite good and we realized we could run all 20+ of our demo applications on a single droplet for $40/month.")]),e("p",null,[t("For deployment, "),e("a",{href:"https://docs.servicestack.net/do-github-action-mix-deployment"},"we also like to keep things as simple as we can, whilst keeping portability"),t(". Since all our projects are public and on GitHub, we use "),e("a",{href:"https://docs.servicestack.net/do-github-action-mix-deployment#github-repository-setup"},"GitHub Actions"),t(" heavily along with a pattern that deploys our applications using Docker Compose via SSH. Each application runs in its own container behind an "),e("a",{href:"https://docs.servicestack.net/do-github-action-mix-deployment#get-nginx-reverse-proxy-and-letsencrypt-companion-running"},"NGINX proxy"),t(" with a side car that handles renewing LetsEncrypt certificates. Below is an example of this pattern with Blazor and Litestream.")]),e("iframe",{class:"youtube",src:"https://www.youtube.com/embed/fY50dWszpw4",frameborder:"0",allow:"autoplay; encrypted-media",allowfullscreen:""}),e("p",null,"A nice side effect of this approach is moving servers is relatively painless. We change the DNS entry for the application to point to our new server, update the GitHub Action Secrets if needed and run our Release workflow."),e("p",null,[t("A minute or so later, the application is back running again. Since their were 20+ of these repositories we took advantage of the "),e("a",{href:"https://cli.github.com/manual/gh_secret_set"},"GitHub Organization Secrets"),t(" so we only needed to update values in one place, and "),e("a",{href:"https://cli.github.com/manual/gh_workflow_run"},"running the workflows again"),t(" can also be done programmatically through the GitHub CLI.")]),e("h2",null,"DigitalOcean Price Increase"),e("p",null,[t("In June of 2022, we got a notification that "),e("a",{href:"https://www.digitalocean.com/try/new-pricing"},"prices for droplets would be increasing"),t(", and for our droplet it would be going from "),e("strong",null,"$40 to $48"),t(". While this is a small amount of money, it prompted us to have a wider look into this market.")]),e("p",null,"Something we try to do at ServiceStack is to not only provide a comprehensive .NET Framework for building API first systems, but also seek out great value hosting options we can recommend in this ever change space which we’re happy to share, like this blog post, that might be useful to our users and others."),e("p",null,[t("Not everyone builds massively distributed systems, and as hardware performance increases, and platforms like "),e("a",{href:"https://devblogs.microsoft.com/dotnet/performance-improvements-in-aspnet-core-6"},".NET are becoming even more optimized"),t(", a setup with just a server or two can manage larger loads and use cases.")]),e("p",null,[t("Our research and evaluations ended up right back at "),e("a",{href:"https://www.hetzner.com/cloud"},"Hetzner but this time with their Cloud offering"),t(". For less than "),e("strong",null,"$15 USD"),t(" per month, you can get a "),e("strong",null,"4 vCPU, 8GB RAM, 160GB storage and 20TB"),t(" of data transfer "),e("strong",null,"hosted in the US"),t(".")]),e("p",null,"We found this was by far the cheapest offering for a simple fixed monthly hosting, and looked to compare how well it performed against the more traditional cloud hosting setups."),e("h2",null,"Litestream and SQLite"),e("p",null,[t("Our demo applications use "),e("a",{href:"https://www.sqlite.org"},"SQLite"),t(" as a simple way to host the database storage and application together, taking advantage of SQLite’s embedded nature. We were also testing out "),e("a",{href:"https://litestream.io"},"Litestream"),t(" as a possible solution to the lack of data backups and safety when using SQLite for more production like workloads.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("a",{href:"https://litestream.io"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/litestream.svg",alt:""})]),e("div",{class:"text-gray-500 text-center"},"litestream.io")])]),e("p",null,[t("Litestream runs as a separate process and watches your SQLite file for changes and replicates them to storage options like AWS S3, Azure Blob storage and SFTP. "),e("a",{href:"https://docs.servicestack.net/ormlite/litestream"},"We created several templates to make this easier"),t(" and provide a way to bake in automated disaster recovery using Litestream when used with GitHub Actions and our SSH with Docker Compose deployment.")]),e("p",null,"With some basic load testing, we noticed that SQLite performed pretty well without any effort on our part, and decided we should see how this compares to the commonly suggested hosting patterns provided by the large cloud providers of AWS and Azure."),e("p",null,"We used the recommended “Production” setups provided by AWS RDS and Azure SQL Database wizards along with 2 vCPU application server to provide the basis on our comparison. The reason we chose to use the suggested defaults from these providers was to illustrate the power of defaults when offered by market leaders. When compared to a simple SQLite setup, and providers that offer fixed monthly pricing like Hetzner and DigitalOcean, which is often enough to small companies selling Business to Business (B2B) solutions, AWS and Azure recommended “Production” environments can look extremely over priced."),e("p",null,"One of the main reasons managed database solutions are chosen is the fact that they take care of automated backups and restore if things go wrong. There are other nice features that definitely have a lot of value, but managed disaster recovery is probably the most commonly cited one I’ve come across for why services like RDS are chosen during early development."),e("p",null,"Litestream provides this kind of data safety and disaster recovery functionality by targeting cost effective and robust storage solutions like AWS S3 and other cloud provided object stores, and making the backup process close to real-time, and accessible via their CLI. And the embedded nature of SQLite removes the uncertainty of the process of upgrading your database."),e("h2",null,"The Test"),e("p",null,[t("To get a clearer idea how each of these hosting options perform with a fairly modest workload, we used a "),e("a",{href:"https://gatling.io"},"Gatling"),t(" test to simulate a user logging into our sample Bookings application, browsing around and creating a booking.")]),e("p",null,"These series of steps had 2 write requests and 8 read, separated by 2 seconds per step. We then setup a Gatling simulation that ramped up adding new users to our system from 5 per second to 15 per second, to add a growing number of users over 10 minutes, then sustained over another 10 minutes."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/aws-gatling-result.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"AWS Gatling Result.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/azure-gatling-result.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Azure Gatling Result.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/hetzner-gatling-result.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Hetzner Gatling Result.")]),e("p",null,[t("All 3 setups could handle this rate of requests without issue, and though the “Recommended” AWS and Azure setups would have more headroom, the price difference is far too large to ignore, especially as the difference is paid every month. The requests throughput of that this test illustrated ~100rps can suit many many use cases, and SQLite is "),e("a",{href:"https://www.sqlite.org/whentouse.html#:~:text=An%20SQLite%20database%20is%20limited,to%20something%20less%20than%20this."},"really only limited by its single writer design"),t(". We did previous tests of upto 250rps on the same Hetzner Cloud instance with SQLite, but this was starting to reach the maximum throughput, again purely to do with the single writer limitation.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/litestream-costs.svg",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Previous test result price comparison without AWS using Provisioned IOPS.")]),e("p",null,[t("This level of throughput is enough to service many kinds of businesses with a drastically more simple system to manage, with large cost savings. Also, with the use of an ORM like "),e("a",{href:"https://docs.servicestack.net/ormlite"},"OrmLite"),t(", switching to another database provider can be migrated if and when the traditional offerings like Postgres are needed.")]),e("h2",null,"The Setups"),e("p",null,"The original setup for tests we did in June didn’t default to provisioned IOPs for AWS, but when repeating the tests AWS costs blow out due to this feature being enabled by default."),e("p",null,[t("Without provisioned IOPs, it drops to around "),e("strong",null,"$132/month"),t(" as an estimated cost. The "),e("strong",null,"$300/month"),t(" default feature for a “Production” database is very hard for AWS to justify, and I think more of a sign of their poor performing GP2 storage option. Although this will only impact very “chatty” types of applications that need higher IOPs throughput, the difference in performance from RDS vs providers like DigitalOcean and Hetzner can be quite stark.")]),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/aws-rds-with-provisioned-iops.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"AWS RDS now defaults to provisioned IOPs for a Production setup, drastically increasing costs.")]),e("table",null,[e("thead",null,[e("tr",null,[e("th"),e("th",null,"AWS (DB)"),e("th",null,"AWS (App)"),e("th",null,"Azure (DB)"),e("th",null,"Azure (App)"),e("th",null,"DigitalOcean"),e("th",null,"Hetzner Cloud")])]),e("tbody",null,[e("tr",null,[e("td",null,"vCPU"),e("td",null,"2"),e("td",null,"2"),e("td",null,"4"),e("td",null,"2"),e("td",null,"4"),e("td",null,"4")]),e("tr",null,[e("td",null,"Memory (GB)"),e("td",null,"8"),e("td",null,"4"),e("td",null,"10"),e("td",null,"8"),e("td",null,"8"),e("td",null,"8")]),e("tr",null,[e("td",null,"Storage (GB)"),e("td",null,"100 (provisioned)"),e("td",null,"16"),e("td",null,"32"),e("td",null,"30"),e("td",null,"160"),e("td",null,"160")]),e("tr",null,[e("td",null,"Cost"),e("td",null,"$442"),e("td",null,"$34"),e("td",null,"$373"),e("td",null,"$70"),e("td",null,"$48"),e("td",null,"$15")])])]),e("p",null,"The above specs were provided as “Production” defaults when using a single database instance. Azure SQL Database defaults to costing $373, during the load test, the database CPU hit ~25%."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/azure-db-cpu-during-test.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Azure SQL database without tuning performs poorly for cost, likely due to lack of indexes")]),e("table",null,[e("thead",null,[e("tr",null,[e("th"),e("th",null,"AWS (DB)"),e("th",null,"AWS (App)"),e("th",null,"Azure (DB)"),e("th",null,"Azure (App)"),e("th",null,"Hetzner Cloud")])]),e("tbody",null,[e("tr",null,[e("td",null,"Max CPU %"),e("td",null,"8"),e("td",null,"35"),e("td",null,"25"),e("td",null,"45"),e("td",null,"40")])])]),e("p",null,"This is without any tuning on any of the databases, so while you like more performance out of the recommended setups, it is still clear SQLite performs well by default, and it is well worth considering not only Hetzner Cloud for value for money, but if your use can only needs a single host with SQLite."),e("h2",null,"Hetzner Cloud"),e("p",null,"While we were primarily looking for one of the lowest cost options with simplified pricing, Hetzner Cloud pleasantly surprised us with a few features the larger providers could learn from."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/hetzner-cloud-buy.png",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Hetzner Cloud Pricing.")]),e("h3",null,"Creating a new instance is fast"),e("p",null,[t("Most of the time if will be ready to remote to before you can open your terminal. Not sure if this is due to some kind of pre-creation process on Hetzner part during the creation screen, but everything is very responsive. In my testing from the time the “Create” button was clicked, my SSH commands would succeed within "),e("strong",null,"20 seconds"),t(".")]),e("h3",null,"Live Graphs"),e("p",null,"Another part of the responsiveness is their “Live” graphs for monitoring. It is surprisingly low latency and an extremely stark difference between AWS charging extra for “Detailed” monitoring on EC2 instances. The graphs update every 3-5 seconds in the browser and look to be over a few seconds behind real-time."),e("div",{class:"mx-auto mt-4 mb-4"},[e("div",{class:"inline-flex justify-center w-full"},[e("img",{src:"https://servicestack.net/img/posts/hetzner-cloud/hetzner-cloud-live-graphs.gif",alt:""})]),e("div",{class:"text-gray-500 text-center"},"Live monitoring updates every 3-5 seconds.")]),e("p",null,"CloudWatch is a major value add for AWS, and Hetzner’s offering is very very basic in comparison, but it is nice to see live updating stats right in your web browser, and something hopefully the other providers can also offer in the future."),e("h3",null,"Price"),e("p",null,[t("This is the biggest draw card by a long way. The AWS and Azure “recommended” setups are extremely expensive for the hardware and performance they offer. Yes they are mature cloud offerings with a large array of features, but their "),e("strong",null,"pricing scales with hardware resources"),t(". Products like "),e("strong",null,"Provisioned IOPs"),t(" are extremely expensive, and when other cloud providers are offering far more performant and competitive storage with their instances, it can feel like AWS is using it’s market share and their defaults to upsell very expensive products.")]),e("h3",null,"Transfer costs"),e("p",null,[t("It’s been long known that one of the ways large cloud providers keep customers in their network is by charging "),e("a",{href:"https://aws.amazon.com/blogs/architecture/overview-of-data-transfer-costs-for-common-architectures"},"excessively large and complex data egress costs"),t(". Something attractive about simplified pricing from Hetzner Cloud (and DigitalOcean to a lesser degree) is the included data transfer of 20TB a month.")]),e("p",null,[t("Not only is AWS data transfer pricing extremely complicated (inter region vs cross region vs CloudFront vs Transit Gateway and so on), but if your application was sending a lot of data to clients, that same "),e("strong",null,"20TB"),t(" you get for free with a "),e("strong",null,"$15 server"),t(", would cost "),e("strong",null,"$1,791 just for data"),t(" when coming from AWS. Azure pricing also confusing, and in some ways more expensive.")]),e("h2",null,"Defaults are powerful"),e("p",null,"Both AWS and Azure “recommended” defaults are there not because the software selected (SQL Server and Postgres) need that amount of resources just to operate, but more as an upsell. Lots of projects and applications absolutely do not need features like “Provisioned IOPs”, despite GP2 storage of AWS being incredibly slow."),e("p",null,[t("Performing disk speed check using the Linux utility "),e("code",null,"fio"),t(" an AWS EC2 instance with 100GB GP2 storage can do ~2250 IOPS and 9MB/s read, and ~750 IOPs at 3MB/s write. In contrast, Digital Ocean $48 instance, this is not even paying the extra $8/month for the faster storage can do 35.2k IOPS at 144MB/s read, and 11.8k IOPS at 48MB/s write.")]),e("p",null,"Hetzner again is the stand out, with the $15 instance tests resulting in 50.8k IOPS at 207MB/s read, and 16.9k IOPS at 69MB/s write."),e("table",null,[e("thead",null,[e("tr",null,[e("th"),e("th",null,"Read IOPS"),e("th",null,"Write IOPs"),e("th",null,"Read MBs"),e("th",null,"Write MBs")])]),e("tbody",null,[e("tr",null,[e("td",null,"AWS"),e("td",null,"2.3k"),e("td",null,"0.8k"),e("td",null,"9.2 MB/s"),e("td",null,"3.1 MB/s")]),e("tr",null,[e("td",null,"Azure"),e("td",null,"3.0k"),e("td",null,"1.0k"),e("td",null,"12.5 MB/s"),e("td",null,"4.2 MB/s")]),e("tr",null,[e("td",null,"DigitalOcean"),e("td",null,"35.2k"),e("td",null,"11.8k"),e("td",null,"144 MB/s"),e("td",null,"48.2 MB/s")]),e("tr",null,[e("td",null,"Hetzner Cloud"),e("td",null,"50.5k"),e("td",null,"16.9k"),e("td",null,"207 MB/s"),e("td",null,"69.2 MB/s")])])]),e("p",null,[t("All tests used the following "),e("code",null,"fio"),t(" command.")]),e("pre",{class:"language-shell"},[e("code",{class:"language-shell"},[t("fio "),e("span",{class:"token parameter variable"},"--randrepeat"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"1"),t(),e("span",{class:"token parameter variable"},"--ioengine"),e("span",{class:"token operator"},"="),t("libaio "),e("span",{class:"token parameter variable"},"--direct"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"1"),t(),e("span",{class:"token parameter variable"},"--gtod_reduce"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"1"),t(),e("span",{class:"token parameter variable"},"--name"),e("span",{class:"token operator"},"="),t("test "),e("span",{class:"token punctuation"},"\\"),t(` `),e("span",{class:"token parameter variable"},"--filename"),e("span",{class:"token operator"},"="),t("test "),e("span",{class:"token parameter variable"},"--bs"),e("span",{class:"token operator"},"="),t("4k "),e("span",{class:"token parameter variable"},"--iodepth"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"64"),t(),e("span",{class:"token parameter variable"},"--size"),e("span",{class:"token operator"},"="),t("4G "),e("span",{class:"token parameter variable"},"--readwrite"),e("span",{class:"token operator"},"="),t("randrw "),e("span",{class:"token parameter variable"},"--rwmixread"),e("span",{class:"token operator"},"="),e("span",{class:"token number"},"75"),t(` `)])]),e("h2",null,"SQLite"),e("p",null,"Part of the resurgence in popularity of using SQLite is not only the simplicity of a single server, but also as hardware is getting faster, issues surrounding limitations of a single writer are becoming less of an issue for a wider number of use cases."),e("p",null,"Litestream’s elegant solution for streaming backups to cheap replica storage is definitely adding to that popularity as well since it was a sticking point for a lot of use cases that need that simple data redundancy functionality."),e("p",null,[t("Other solutions for Postgres like "),e("code",null,"pgbackrest"),t(" are similar, but the ease of use is another big part of what makes SQLite and Litestream a great combination. One command to watch and replicate, another to restore, and it runs completely independent of your application using the SQLite file.")]),e("h2",null,"Hetzner Cloud is hard to beat on price"),e("p",null,"We’re going to keep testing Hetzner Cloud with new applications and use cases going into the future. While they are a very new player in the crowded Cloud Provider market, and their offerings are much more limited, the pricing is a breath of fresh air from the large three providers."),e("p",null,"More competition in this space is a great thing, and for those that can use solutions like SQLite for their projects, checking out some of the smaller players like DigitalOcean and Hetzner Cloud is well worth your time. The early signs from Hetzner Cloud is they not only have an amazing value product, but the features they do have improve on the equivalents from likes of AWS and Azure, which is hopefully a sign of things to come from them.")],-1),w="In pursuit of the best value US cloud provider",v="We've been using AWS at ServiceStack for 10+ years, it's served us well but suffers from complex & expensive pricing",y="Brandon Foley",b=["dev","hosting","devops"],k="https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000",S=[{property:"og:title",content:"In pursuit of the best value US cloud provider"},{name:"twitter:title",content:"In pursuit of the best value US cloud provider"},{property:"og:image",content:"https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}],x={__name:"2022-09-06_hetzner-cloud",setup(c,{expose:a}){const s={title:"In pursuit of the best value US cloud provider",summary:"We've been using AWS at ServiceStack for 10+ years, it's served us well but suffers from complex & expensive pricing",author:"Brandon Foley",tags:["dev","hosting","devops"],image:"https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000",meta:[{property:"og:title",content:"In pursuit of the best value US cloud provider"},{name:"twitter:title",content:"In pursuit of the best value US cloud provider"},{property:"og:image",content:"https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]};return a({frontmatter:s}),r({title:"In pursuit of the best value US cloud provider",meta:[{property:"og:title",content:"In pursuit of the best value US cloud provider"},{name:"twitter:title",content:"In pursuit of the best value US cloud provider"},{property:"og:image",content:"https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1451187580459-43490279c0fa?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]}),(h,m)=>{const o=n;return i(),l(o,{frontmatter:s},{default:u(()=>[d]),_:1})}}};export{y as author,x as default,k as image,S as meta,v as summary,b as tags,w as title}; diff --git a/assets/2022-12-31_typography-CQ2u4p7c.js b/assets/2022-12-31_typography-C35AONwX.js similarity index 98% rename from assets/2022-12-31_typography-CQ2u4p7c.js rename to assets/2022-12-31_typography-C35AONwX.js index 19a67c3..9d86f4d 100644 --- a/assets/2022-12-31_typography-CQ2u4p7c.js +++ b/assets/2022-12-31_typography-C35AONwX.js @@ -1,4 +1,4 @@ -import{_ as s}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as l,o as i,h as r,w as p,a as t,e}from"./index-B-kKBcPB.js";const c=t("div",{class:"markdown-body"},[t("p",{class:"lead"}," Until now, trying to style an article, document, or blog post with Tailwind has been a tedious task that required a keen eye for typography and a lot of complex custom CSS. "),t("p",null,[e("By default, Tailwind removes all of the default browser styling from paragraphs, headings, lists and more. This ends up being really useful for building application UIs because you spend less time undoing user-agent styles, but when you "),t("em",null,"really are"),e(" just trying to style some content that came from a rich-text editor in a CMS or a markdown file, it can be surprising and unintuitive.")]),t("p",null,"We get lots of complaints about it actually, with people regularly asking us things like:"),t("blockquote",null,[t("p",null,[e("Why is Tailwind removing the default styles on my "),t("code",null,"h1"),e(" elements? How do I disable this? What do you mean I lose all the other base styles too?")])]),t("p",null,[e("We hear you, but we’re not convinced that simply disabling our base styles is what you really want. You don’t want to have to remove annoying margins every time you use a "),t("code",null,"p"),e(" element in a piece of your dashboard UI. And I doubt you really want your blog posts to use the user-agent styles either — you want them to look "),t("em",null,"awesome"),e(", not awful.")]),t("p",null,[e("The "),t("code",null,"@tailwindcss/typography"),e(" plugin is our attempt to give you what you "),t("em",null,"actually"),e(" want, without any of the downsides of doing something stupid like disabling our base styles.")]),t("p",null,[e("It adds a new "),t("code",null,"prose"),e(" class that you can slap on any block of vanilla HTML content and turn it into a beautiful, well-formatted document:")]),t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),e("article")]),e(),t("span",{class:"token attr-name"},"class"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("prose"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),e(` +import{_ as s}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as l,o as i,h as r,w as p,a as t,e}from"./index-CoFPLbfm.js";const c=t("div",{class:"markdown-body"},[t("p",{class:"lead"}," Until now, trying to style an article, document, or blog post with Tailwind has been a tedious task that required a keen eye for typography and a lot of complex custom CSS. "),t("p",null,[e("By default, Tailwind removes all of the default browser styling from paragraphs, headings, lists and more. This ends up being really useful for building application UIs because you spend less time undoing user-agent styles, but when you "),t("em",null,"really are"),e(" just trying to style some content that came from a rich-text editor in a CMS or a markdown file, it can be surprising and unintuitive.")]),t("p",null,"We get lots of complaints about it actually, with people regularly asking us things like:"),t("blockquote",null,[t("p",null,[e("Why is Tailwind removing the default styles on my "),t("code",null,"h1"),e(" elements? How do I disable this? What do you mean I lose all the other base styles too?")])]),t("p",null,[e("We hear you, but we’re not convinced that simply disabling our base styles is what you really want. You don’t want to have to remove annoying margins every time you use a "),t("code",null,"p"),e(" element in a piece of your dashboard UI. And I doubt you really want your blog posts to use the user-agent styles either — you want them to look "),t("em",null,"awesome"),e(", not awful.")]),t("p",null,[e("The "),t("code",null,"@tailwindcss/typography"),e(" plugin is our attempt to give you what you "),t("em",null,"actually"),e(" want, without any of the downsides of doing something stupid like disabling our base styles.")]),t("p",null,[e("It adds a new "),t("code",null,"prose"),e(" class that you can slap on any block of vanilla HTML content and turn it into a beautiful, well-formatted document:")]),t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),e("article")]),e(),t("span",{class:"token attr-name"},"class"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("prose"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),e(` `),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),e("h1")]),t("span",{class:"token punctuation"},">")]),e("Garlic bread with cheese: What the science tells us"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),e(` `),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),e("p")]),t("span",{class:"token punctuation"},">")]),e(` For years parents have espoused the health benefits of eating garlic bread with cheese to their diff --git a/assets/2023-01-01_deploy-DS48nsUk.js b/assets/2023-01-01_deploy-Bh3tgLQ9.js similarity index 98% rename from assets/2023-01-01_deploy-DS48nsUk.js rename to assets/2023-01-01_deploy-Bh3tgLQ9.js index 0d80776..5799828 100644 --- a/assets/2023-01-01_deploy-DS48nsUk.js +++ b/assets/2023-01-01_deploy-Bh3tgLQ9.js @@ -1,4 +1,4 @@ -import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as l,o as c,h as i,w as r,a as e,e as t}from"./index-B-kKBcPB.js";const p=e("div",{class:"markdown-body"},[e("h1",null,"ServiceStack GitHub Action Deployments"),e("p",null,[t("The "),e("a",{href:"https://github.com/NetCoreTemplates/razor-tailwind/blob/main/.github/workflows/release.yml"},"release.yml"),t(" in this template enables GitHub Actions CI deployment to a dedicated server with SSH access.")]),e("h2",null,"Overview"),e("p",null,[e("code",null,"release.yml"),t(" is designed to work with a ServiceStack app deploying directly to a single server via SSH. A docker image is built and stored on GitHub’s "),e("code",null,"ghcr.io"),t(" docker registry when a GitHub Release is created.")]),e("p",null,[t("GitHub Actions specified in "),e("code",null,"release.yml"),t(" then copy files remotely via scp and use "),e("code",null,"docker-compose"),t(" to run the app remotely via SSH.")]),e("h2",null,[t("What’s the process of "),e("code",null,"release.yml"),t("?")]),e("p",null,[e("img",{src:"https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/mix/release-ghr-vanilla-diagram.png",alt:""})]),e("h2",null,"Deployment server setup"),e("p",null,"To get this working, a server needs to be setup with the following:"),e("ul",null,[e("li",null,"SSH access"),e("li",null,"docker"),e("li",null,"docker-compose"),e("li",null,"ports 443 and 80 for web access of your hosted application")]),e("p",null,[t("This can be your own server or any cloud hosted server like Digital Ocean, AWS, Azure etc. We use "),e("a",{href:"http://cloud.hetzner.com/"},"Hetzner Cloud"),t(" to deploy all ServiceStack’s "),e("a",{href:"https://github.com/NetCoreTemplates/"},"GitHub Project Templates"),t(" as it was the "),e("a",{href:"https://servicestack.net/blog/finding-best-us-value-cloud-provider"},"best value US cloud provider"),t(" we’ve found.")]),e("p",null,[t("When setting up your server, you’ll want to use a dedicated SSH key for access to be used by GitHub Actions. GitHub Actions will need the "),e("em",null,"private"),t(" SSH key within a GitHub Secret to authenticate. This can be done via ssh-keygen and copying the public key to the authorized clients on the server.")]),e("p",null,[t("To let your server handle multiple ServiceStack applications and automate the generation and management of TLS certificates, an additional docker-compose file is provided in this template, "),e("code",null,"nginx-proxy-compose.yml"),t(". This docker-compose file is ready to run and can be copied to the deployment server.")]),e("p",null,[t("For example, once copied to remote "),e("code",null,"~/nginx-proxy-compose.yml"),t(", the following command can be run on the remote server.")]),e("pre",null,[e("code",null,`docker-compose -f ~/nginx-proxy-compose.yml up -d +import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as l,o as c,h as i,w as r,a as e,e as t}from"./index-CoFPLbfm.js";const p=e("div",{class:"markdown-body"},[e("h1",null,"ServiceStack GitHub Action Deployments"),e("p",null,[t("The "),e("a",{href:"https://github.com/NetCoreTemplates/razor-tailwind/blob/main/.github/workflows/release.yml"},"release.yml"),t(" in this template enables GitHub Actions CI deployment to a dedicated server with SSH access.")]),e("h2",null,"Overview"),e("p",null,[e("code",null,"release.yml"),t(" is designed to work with a ServiceStack app deploying directly to a single server via SSH. A docker image is built and stored on GitHub’s "),e("code",null,"ghcr.io"),t(" docker registry when a GitHub Release is created.")]),e("p",null,[t("GitHub Actions specified in "),e("code",null,"release.yml"),t(" then copy files remotely via scp and use "),e("code",null,"docker-compose"),t(" to run the app remotely via SSH.")]),e("h2",null,[t("What’s the process of "),e("code",null,"release.yml"),t("?")]),e("p",null,[e("img",{src:"https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/mix/release-ghr-vanilla-diagram.png",alt:""})]),e("h2",null,"Deployment server setup"),e("p",null,"To get this working, a server needs to be setup with the following:"),e("ul",null,[e("li",null,"SSH access"),e("li",null,"docker"),e("li",null,"docker-compose"),e("li",null,"ports 443 and 80 for web access of your hosted application")]),e("p",null,[t("This can be your own server or any cloud hosted server like Digital Ocean, AWS, Azure etc. We use "),e("a",{href:"http://cloud.hetzner.com/"},"Hetzner Cloud"),t(" to deploy all ServiceStack’s "),e("a",{href:"https://github.com/NetCoreTemplates/"},"GitHub Project Templates"),t(" as it was the "),e("a",{href:"https://servicestack.net/blog/finding-best-us-value-cloud-provider"},"best value US cloud provider"),t(" we’ve found.")]),e("p",null,[t("When setting up your server, you’ll want to use a dedicated SSH key for access to be used by GitHub Actions. GitHub Actions will need the "),e("em",null,"private"),t(" SSH key within a GitHub Secret to authenticate. This can be done via ssh-keygen and copying the public key to the authorized clients on the server.")]),e("p",null,[t("To let your server handle multiple ServiceStack applications and automate the generation and management of TLS certificates, an additional docker-compose file is provided in this template, "),e("code",null,"nginx-proxy-compose.yml"),t(". This docker-compose file is ready to run and can be copied to the deployment server.")]),e("p",null,[t("For example, once copied to remote "),e("code",null,"~/nginx-proxy-compose.yml"),t(", the following command can be run on the remote server.")]),e("pre",null,[e("code",null,`docker-compose -f ~/nginx-proxy-compose.yml up -d `)]),e("p",null,"This will run an nginx reverse proxy along with a companion container that will watch for additional containers in the same docker network and attempt to initialize them with valid TLS certificates."),e("h3",null,"GitHub Actions secrets"),e("p",null,[t("The "),e("code",null,"release.yml"),t(" uses the following secrets.")]),e("table",null,[e("thead",null,[e("tr",null,[e("th",null,"Required Secrets"),e("th",null,"Description")])]),e("tbody",null,[e("tr",null,[e("td",null,[e("code",null,"DEPLOY_HOST")]),e("td",null,"Hostname used to SSH deploy .NET App to, this can either be an IP address or subdomain with A record pointing to the server")]),e("tr",null,[e("td",null,[e("code",null,"DEPLOY_USERNAME")]),e("td",null,[t("Username to log in with via SSH e.g, "),e("strong",null,"ubuntu"),t(", "),e("strong",null,"ec2-user"),t(", "),e("strong",null,"root")])]),e("tr",null,[e("td",null,[e("code",null,"DEPLOY_KEY")]),e("td",null,"SSH private key used to remotely access deploy .NET App")]),e("tr",null,[e("td",null,[e("code",null,"LETSENCRYPT_EMAIL")]),e("td",null,"Email required for Let’s Encrypt automated TLS certificates")])])]),e("p",null,[t("These secrets can use the "),e("a",{href:"https://cli.github.com/manual/gh_secret_set"},"GitHub CLI"),t(" for ease of creation. Eg, using the GitHub CLI the following can be set.")]),e("pre",{class:"language-bash"},[e("code",{class:"language-bash"},[t("gh secret "),e("span",{class:"token builtin class-name"},"set"),t(" DEPLOY_HOST -b"),e("span",{class:"token string"},'""'),t(` gh secret `),e("span",{class:"token builtin class-name"},"set"),t(" DEPLOY_USERNAME -b"),e("span",{class:"token string"},'""'),t(` gh secret `),e("span",{class:"token builtin class-name"},"set"),t(" DEPLOY_KEY "),e("span",{class:"token operator"},"<"),t(" key.pem "),e("span",{class:"token comment"},"# DEPLOY_KEY"),t(` diff --git a/assets/2023-01-10_vs-CnHF8_tj.js b/assets/2023-01-10_vs-Dpo3fFRu.js similarity index 98% rename from assets/2023-01-10_vs-CnHF8_tj.js rename to assets/2023-01-10_vs-Dpo3fFRu.js index 05e618d..dc6f8c6 100644 --- a/assets/2023-01-10_vs-CnHF8_tj.js +++ b/assets/2023-01-10_vs-Dpo3fFRu.js @@ -1,4 +1,4 @@ -import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o,h as c,w as p,a as t,c as a,e}from"./index-B-kKBcPB.js";const u={class:"markdown-body"},d=t("p",null,[e("A popular alternative development environment to our preferred "),t("a",{href:"rider"},"JetBrains Rider"),e(" IDE is to use Visual Studio, the primary issue with this is that VS Code is a better IDE with richer support for JavaScript and npm projects whilst Visual Studio is a better IDE for C# Projects.")],-1),h=t("p",null,"Essentially this is why we recommend Rider where it’s best at both, where both C# and JS/TypeScript projects can be developed from within the same solution.",-1),m=t("h3",null,"Developing with just VS Code",-1),g={href:"https://visualstudio.microsoft.com/",title:"VS Code",class:"sm:float-left mr-8"},_={class:"w-24 h-24",style:{"margin-top":"1rem"},xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 254"},f=t("defs",null,[t("linearGradient",{id:"logosVisualStudioCode0",x1:"50%",x2:"50%",y1:"0%",y2:"100%"},[t("stop",{offset:"0%","stop-color":"#FFF"}),t("stop",{offset:"100%","stop-color":"#FFF","stop-opacity":"0"})]),t("path",{id:"logosVisualStudioCode1",d:"M180.828 252.605a15.872 15.872 0 0 0 12.65-.486l52.501-25.262a15.94 15.94 0 0 0 9.025-14.364V41.197a15.939 15.939 0 0 0-9.025-14.363l-52.5-25.263a15.877 15.877 0 0 0-18.115 3.084L74.857 96.35l-43.78-33.232a10.614 10.614 0 0 0-13.56.603L3.476 76.494c-4.63 4.211-4.635 11.495-.012 15.713l37.967 34.638l-37.967 34.637c-4.623 4.219-4.618 11.502.012 15.714l14.041 12.772a10.614 10.614 0 0 0 13.56.604l43.78-33.233l100.507 91.695a15.853 15.853 0 0 0 5.464 3.571Zm10.464-183.649l-76.262 57.889l76.262 57.888V68.956Z"})],-1),w=t("mask",{id:"logosVisualStudioCode2",fill:"#fff"},[t("use",{href:"#logosVisualStudioCode1"})],-1),v=t("path",{fill:"#0065A9",d:"M246.135 26.873L193.593 1.575a15.885 15.885 0 0 0-18.123 3.08L3.466 161.482c-4.626 4.219-4.62 11.502.012 15.714l14.05 12.772a10.625 10.625 0 0 0 13.569.604L238.229 33.436c6.949-5.271 16.93-.315 16.93 8.407v-.61a15.938 15.938 0 0 0-9.024-14.36Z",mask:"url(#logosVisualStudioCode2)"},null,-1),y=t("path",{fill:"#007ACC",d:"m246.135 226.816l-52.542 25.298a15.887 15.887 0 0 1-18.123-3.08L3.466 92.207c-4.626-4.218-4.62-11.502.012-15.713l14.05-12.773a10.625 10.625 0 0 1 13.569-.603l207.132 157.135c6.949 5.271 16.93.315 16.93-8.408v.611a15.939 15.939 0 0 1-9.024 14.36Z",mask:"url(#logosVisualStudioCode2)"},null,-1),V=t("path",{fill:"#1F9CF0",d:"M193.428 252.134a15.892 15.892 0 0 1-18.125-3.083c5.881 5.88 15.938 1.715 15.938-6.603V11.273c0-8.318-10.057-12.483-15.938-6.602a15.892 15.892 0 0 1 18.125-3.084l52.533 25.263a15.937 15.937 0 0 1 9.03 14.363V212.51c0 6.125-3.51 11.709-9.03 14.363l-52.533 25.262Z",mask:"url(#logosVisualStudioCode2)"},null,-1),S=t("path",{fill:"url(#logosVisualStudioCode0)","fill-opacity":".25",d:"M180.828 252.605a15.874 15.874 0 0 0 12.65-.486l52.5-25.263a15.938 15.938 0 0 0 9.026-14.363V41.197a15.939 15.939 0 0 0-9.025-14.363L193.477 1.57a15.877 15.877 0 0 0-18.114 3.084L74.857 96.35l-43.78-33.232a10.614 10.614 0 0 0-13.56.603L3.476 76.494c-4.63 4.211-4.635 11.495-.012 15.713l37.967 34.638l-37.967 34.637c-4.623 4.219-4.618 11.502.012 15.714l14.041 12.772a10.614 10.614 0 0 0 13.56.604l43.78-33.233l100.506 91.695a15.857 15.857 0 0 0 5.465 3.571Zm10.464-183.65l-76.262 57.89l76.262 57.888V68.956Z",mask:"url(#logosVisualStudioCode2)"},null,-1),k=[f,w,v,y,V,S],C=t("p",null,[e("If you prefer the dev UX of a lightweight text editor or your C# project isn’t large, than VS Code on its own can provide a great development UX which is also what "),t("a",{href:"https://v3.vuejs.org/api/sfc-tooling.html#ide-support"},"Vue recommends themselves"),e(", to be used together with the "),t("a",{href:"https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar"},"Volar extension"),e(".")],-1),b=t("p",null,[e("VSCode’s "),t("a",{href:"https://code.visualstudio.com/docs/editor/integrated-terminal"},"Integrated Terminal"),e(" has great multi-terminal support you can toggle between the editor and terminal with "),t("code",null,"Ctrl+"),e(" or open a new Terminal Window with "),t("code",null,"Ctrl+Shift+`"),e(" to run Tailwind with:")],-1),A=t("pre",{class:"language-bash"},[t("code",{class:"language-bash"},[e("$ "),t("span",{class:"token function"},"npm"),e(` run ui:dev +import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o,h as c,w as p,a as t,c as a,e}from"./index-CoFPLbfm.js";const u={class:"markdown-body"},d=t("p",null,[e("A popular alternative development environment to our preferred "),t("a",{href:"rider"},"JetBrains Rider"),e(" IDE is to use Visual Studio, the primary issue with this is that VS Code is a better IDE with richer support for JavaScript and npm projects whilst Visual Studio is a better IDE for C# Projects.")],-1),h=t("p",null,"Essentially this is why we recommend Rider where it’s best at both, where both C# and JS/TypeScript projects can be developed from within the same solution.",-1),m=t("h3",null,"Developing with just VS Code",-1),g={href:"https://visualstudio.microsoft.com/",title:"VS Code",class:"sm:float-left mr-8"},_={class:"w-24 h-24",style:{"margin-top":"1rem"},xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 254"},f=t("defs",null,[t("linearGradient",{id:"logosVisualStudioCode0",x1:"50%",x2:"50%",y1:"0%",y2:"100%"},[t("stop",{offset:"0%","stop-color":"#FFF"}),t("stop",{offset:"100%","stop-color":"#FFF","stop-opacity":"0"})]),t("path",{id:"logosVisualStudioCode1",d:"M180.828 252.605a15.872 15.872 0 0 0 12.65-.486l52.501-25.262a15.94 15.94 0 0 0 9.025-14.364V41.197a15.939 15.939 0 0 0-9.025-14.363l-52.5-25.263a15.877 15.877 0 0 0-18.115 3.084L74.857 96.35l-43.78-33.232a10.614 10.614 0 0 0-13.56.603L3.476 76.494c-4.63 4.211-4.635 11.495-.012 15.713l37.967 34.638l-37.967 34.637c-4.623 4.219-4.618 11.502.012 15.714l14.041 12.772a10.614 10.614 0 0 0 13.56.604l43.78-33.233l100.507 91.695a15.853 15.853 0 0 0 5.464 3.571Zm10.464-183.649l-76.262 57.889l76.262 57.888V68.956Z"})],-1),w=t("mask",{id:"logosVisualStudioCode2",fill:"#fff"},[t("use",{href:"#logosVisualStudioCode1"})],-1),v=t("path",{fill:"#0065A9",d:"M246.135 26.873L193.593 1.575a15.885 15.885 0 0 0-18.123 3.08L3.466 161.482c-4.626 4.219-4.62 11.502.012 15.714l14.05 12.772a10.625 10.625 0 0 0 13.569.604L238.229 33.436c6.949-5.271 16.93-.315 16.93 8.407v-.61a15.938 15.938 0 0 0-9.024-14.36Z",mask:"url(#logosVisualStudioCode2)"},null,-1),y=t("path",{fill:"#007ACC",d:"m246.135 226.816l-52.542 25.298a15.887 15.887 0 0 1-18.123-3.08L3.466 92.207c-4.626-4.218-4.62-11.502.012-15.713l14.05-12.773a10.625 10.625 0 0 1 13.569-.603l207.132 157.135c6.949 5.271 16.93.315 16.93-8.408v.611a15.939 15.939 0 0 1-9.024 14.36Z",mask:"url(#logosVisualStudioCode2)"},null,-1),V=t("path",{fill:"#1F9CF0",d:"M193.428 252.134a15.892 15.892 0 0 1-18.125-3.083c5.881 5.88 15.938 1.715 15.938-6.603V11.273c0-8.318-10.057-12.483-15.938-6.602a15.892 15.892 0 0 1 18.125-3.084l52.533 25.263a15.937 15.937 0 0 1 9.03 14.363V212.51c0 6.125-3.51 11.709-9.03 14.363l-52.533 25.262Z",mask:"url(#logosVisualStudioCode2)"},null,-1),S=t("path",{fill:"url(#logosVisualStudioCode0)","fill-opacity":".25",d:"M180.828 252.605a15.874 15.874 0 0 0 12.65-.486l52.5-25.263a15.938 15.938 0 0 0 9.026-14.363V41.197a15.939 15.939 0 0 0-9.025-14.363L193.477 1.57a15.877 15.877 0 0 0-18.114 3.084L74.857 96.35l-43.78-33.232a10.614 10.614 0 0 0-13.56.603L3.476 76.494c-4.63 4.211-4.635 11.495-.012 15.713l37.967 34.638l-37.967 34.637c-4.623 4.219-4.618 11.502.012 15.714l14.041 12.772a10.614 10.614 0 0 0 13.56.604l43.78-33.233l100.506 91.695a15.857 15.857 0 0 0 5.465 3.571Zm10.464-183.65l-76.262 57.89l76.262 57.888V68.956Z",mask:"url(#logosVisualStudioCode2)"},null,-1),k=[f,w,v,y,V,S],C=t("p",null,[e("If you prefer the dev UX of a lightweight text editor or your C# project isn’t large, than VS Code on its own can provide a great development UX which is also what "),t("a",{href:"https://v3.vuejs.org/api/sfc-tooling.html#ide-support"},"Vue recommends themselves"),e(", to be used together with the "),t("a",{href:"https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar"},"Volar extension"),e(".")],-1),b=t("p",null,[e("VSCode’s "),t("a",{href:"https://code.visualstudio.com/docs/editor/integrated-terminal"},"Integrated Terminal"),e(" has great multi-terminal support you can toggle between the editor and terminal with "),t("code",null,"Ctrl+"),e(" or open a new Terminal Window with "),t("code",null,"Ctrl+Shift+`"),e(" to run Tailwind with:")],-1),A=t("pre",{class:"language-bash"},[t("code",{class:"language-bash"},[e("$ "),t("span",{class:"token function"},"npm"),e(` run ui:dev `)])],-1),L=t("p",null,"Then in a new Terminal Window, start a new watched .NET App with:",-1),x=t("pre",{class:"language-bash"},[t("code",{class:"language-bash"},[e("$ dotnet "),t("span",{class:"token function"},"watch"),e(` `)])],-1),T=t("p",null,[e("With both projects started you can open a browser tab running at "),t("code",null,"https://localhost:5001"),e(" where it will automatically reload itself at every "),t("code",null,"Ctrl+S"),e(" save point.")],-1),D=t("h4",null,"Useful VS Code extensions",-1),F=t("p",null,"We recommend these extensions below to enhance the development experience of this template:",-1),Z=t("ul",null,[t("li",null,[t("a",{href:"https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss"},"Tailwind CSS IntelliSense"),e(" - Add Intellisense for Tailwind classes")]),t("li",null,[t("a",{href:"https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html"},"es6-string-html"),e(" - Add HTML Syntax Highlighting in string literals")])],-1),E=t("h3",null,"Using Visual Studio",-1),M={href:"https://code.visualstudio.com/",title:"Visual Studio",class:"sm:float-left mr-8"},j={class:"w-24 h-24",style:{"margin-top":"1rem"},xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256"},N=t("defs",null,[t("linearGradient",{id:"logosVisualStudio0",x1:"50%",x2:"50%",y1:".002%",y2:"100%"},[t("stop",{offset:"0%","stop-color":"#FFF"}),t("stop",{offset:"100%","stop-color":"#FFF","stop-opacity":"0"})])],-1),I=t("path",{fill:"#52218A",d:"M36.987 200.406a10.667 10.667 0 0 1-11.04 1.734L6.56 194.006A10.667 10.667 0 0 1 0 184.22V70.46a10.667 10.667 0 0 1 6.56-9.787l19.387-8a10.667 10.667 0 0 1 11.04 1.733l4.346 3.6a5.893 5.893 0 0 0-9.333 4.8v129.067a5.893 5.893 0 0 0 9.333 4.8l-4.346 3.733Z"},null,-1),B=t("path",{fill:"#6C33AF",d:"M6.56 194.006A10.667 10.667 0 0 1 0 184.22v-.88a6.16 6.16 0 0 0 10.667 4.133L176 4.673a16 16 0 0 1 18.187-3.093l52.746 25.386A16 16 0 0 1 256 41.393v.613a10.107 10.107 0 0 0-16.507-7.813l-198.16 162.48l-4.346 3.733a10.667 10.667 0 0 1-11.04 1.734L6.56 194.006Z"},null,-1),G=t("path",{fill:"#854CC7",d:"M6.56 60.673A10.667 10.667 0 0 0 0 70.46v.88a6.16 6.16 0 0 1 10.667-4.134L176 250.006a16 16 0 0 0 18.187 3.094l52.746-25.387A16 16 0 0 0 256 213.286v-.613a10.107 10.107 0 0 1-16.507 7.813L41.333 58.006l-4.346-3.733a10.667 10.667 0 0 0-11.04-1.6l-19.387 8Z"},null,-1),H=t("path",{fill:"#B179F1",d:"M194.187 253.1A16 16 0 0 1 176 250.006a9.387 9.387 0 0 0 16-6.64v-232a9.387 9.387 0 0 0-16-6.693a16 16 0 0 1 18.187-3.093l52.746 25.36A16 16 0 0 1 256 41.366v171.947a16 16 0 0 1-9.067 14.427l-52.746 25.36Z"},null,-1),J=t("path",{fill:"url(#logosVisualStudio0)","fill-opacity":".25",d:"M183.707 254.273a16 16 0 0 0 10.48-1.173l52.746-25.36A16 16 0 0 0 256 213.313V41.366a16 16 0 0 0-9.067-14.426L194.187 1.58A16 16 0 0 0 182.24.806A16 16 0 0 0 176 4.673L90.987 98.7L41.333 58.006l-4.346-3.733a10.667 10.667 0 0 0-9.627-2.213a6.8 6.8 0 0 0-1.413.48L6.56 60.673A10.667 10.667 0 0 0 0 69.66v115.36a10.664 10.664 0 0 0 6.56 8.986l19.387 8a6.8 6.8 0 0 0 1.413.48c3.378.882 6.973.056 9.627-2.213l4.346-3.6l49.654-40.693L176 250.006a16 16 0 0 0 7.707 4.267ZM192 73.153l-66.107 54.187L192 181.526V73.153ZM32 90.726l33.093 36.614L32 163.953V90.726Z"},null,-1),P=[N,I,B,G,H,J],U=t("p",null,"As your C# project grows you’ll want to consider running the back-end C# Solution with Visual Studio .NET with its much improved intelli-sense, navigation, tests runner & debug capabilities.",-1),W=t("p",null,"As we’ve never had a satisfactory experience trying develop npm or JS/TypeScript projects with VS.NET, we’d recommend only using VS.NET for C# and Razor and continuing to use VSCode for everything else.",-1),R=t("p",null,"If you’d prefer to use Visual Studio for front-end development we recommend moving all JS to external files for a better Dev UX, e.g:",-1),X=t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),e("script")]),e(),t("span",{class:"token attr-name"},"type"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("module"),t("span",{class:"token punctuation"},'"')]),e(),t("span",{class:"token attr-name"},"src"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("./pages/SignIn.mjs"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),t("span",{class:"token script"}),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),e(` `)])],-1),$=t("h3",null,"Deploying to Production",-1),q=t("p",null,[e("This template also includes the necessary GitHub Actions to deploy this Apps production static assets to GitHub Pages CDN, for more info, checkout "),t("a",{href:"deploy"},"GitHub Actions Deployments"),e(".")],-1),z=t("h3",null,"Get Started",-1),K=t("p",null,[e("If you’re new to Vue 3 a good place to start is "),t("a",{href:"https://vuejs.org/api/composition-api-setup.html"},"Vue 3 Composition API"),e(".")],-1),st="Develop using Visual Studio",at="Exploring development workflow in VS Code and Visual Studio .NET",nt="Lucy Bates",lt=["c#","dev"],it="https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000",rt=[{property:"og:title",content:"Develop using Visual Studio"},{name:"twitter:title",content:"Develop using Visual Studio"},{property:"og:image",content:"https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}],ct={__name:"2023-01-10_vs",setup(O,{expose:n}){const s={title:"Develop using Visual Studio",summary:"Exploring development workflow in VS Code and Visual Studio .NET",author:"Lucy Bates",tags:["c#","dev"],image:"https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000",meta:[{property:"og:title",content:"Develop using Visual Studio"},{name:"twitter:title",content:"Develop using Visual Studio"},{property:"og:image",content:"https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]};return n({frontmatter:s}),r({title:"Develop using Visual Studio",meta:[{property:"og:title",content:"Develop using Visual Studio"},{name:"twitter:title",content:"Develop using Visual Studio"},{property:"og:image",content:"https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]}),(Y,tt)=>{const l=i;return o(),c(l,{frontmatter:s},{default:p(()=>[t("div",u,[d,h,m,t("a",g,[(o(),a("svg",_,k))]),C,b,A,L,x,T,D,F,Z,E,t("a",M,[(o(),a("svg",j,P))]),U,W,R,X,$,q,z,K])]),_:1})}}};export{nt as author,ct as default,it as image,rt as meta,at as summary,lt as tags,st as title}; diff --git a/assets/2023-01-11_rider-BIj5SqpT.js b/assets/2023-01-11_rider-C1RjBW7K.js similarity index 98% rename from assets/2023-01-11_rider-BIj5SqpT.js rename to assets/2023-01-11_rider-C1RjBW7K.js index ba28889..f0029ae 100644 --- a/assets/2023-01-11_rider-BIj5SqpT.js +++ b/assets/2023-01-11_rider-C1RjBW7K.js @@ -1,4 +1,4 @@ -import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o as n,h as c,w as l,a as e,c as p,e as t}from"./index-B-kKBcPB.js";const d={class:"markdown-body"},u=e("a",{href:"https://www.jetbrains.com/rider/"},[e("img",{src:"https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/svg/rider.svg",class:"sm:float-left mr-8 w-24 h-24",style:{"margin-top":"0"}})],-1),h=e("p",null,[e("a",{href:"https://www.jetbrains.com/rider/"},"JetBrains Rider"),t(" is our recommended IDE for any C# + JavaScript development as it offers a great development UX for both, including excellent support for TypeScript and popular JavaScript Framework SPA assets like "),e("a",{href:"https://v3.vuejs.org/guide/single-file-component.html"},"Vue SFC’s"),t(".")],-1),m=e("h4",null,"Setup Rider IDE",-1),g=e("p",null,[t("As Rider already understands and provides excellent HTML/JS/TypeScript support you’ll be immediately productive out-of-the-box, we can further improve the development experience for Vue.js Apps by adding an empty "),e("strong",null,"vue"),t(" dependency to "),e("strong",null,"package.json"),t(":")],-1),_=e("pre",{class:"language-json"},[e("code",{class:"language-json"},[e("span",{class:"token punctuation"},"{"),t(` +import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o as n,h as c,w as l,a as e,c as p,e as t}from"./index-CoFPLbfm.js";const d={class:"markdown-body"},u=e("a",{href:"https://www.jetbrains.com/rider/"},[e("img",{src:"https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/svg/rider.svg",class:"sm:float-left mr-8 w-24 h-24",style:{"margin-top":"0"}})],-1),h=e("p",null,[e("a",{href:"https://www.jetbrains.com/rider/"},"JetBrains Rider"),t(" is our recommended IDE for any C# + JavaScript development as it offers a great development UX for both, including excellent support for TypeScript and popular JavaScript Framework SPA assets like "),e("a",{href:"https://v3.vuejs.org/guide/single-file-component.html"},"Vue SFC’s"),t(".")],-1),m=e("h4",null,"Setup Rider IDE",-1),g=e("p",null,[t("As Rider already understands and provides excellent HTML/JS/TypeScript support you’ll be immediately productive out-of-the-box, we can further improve the development experience for Vue.js Apps by adding an empty "),e("strong",null,"vue"),t(" dependency to "),e("strong",null,"package.json"),t(":")],-1),_=e("pre",{class:"language-json"},[e("code",{class:"language-json"},[e("span",{class:"token punctuation"},"{"),t(` `),e("span",{class:"token property"},'"devDependencies"'),e("span",{class:"token operator"},":"),t(),e("span",{class:"token punctuation"},"{"),t(` `),e("span",{class:"token property"},'"vue"'),e("span",{class:"token operator"},":"),t(),e("span",{class:"token string"},'""'),t(` `),e("span",{class:"token punctuation"},"}"),t(` diff --git a/assets/2023-01-21_start-BLjTU3tE.js b/assets/2023-01-21_start-Dvy20kPM.js similarity index 98% rename from assets/2023-01-21_start-BLjTU3tE.js rename to assets/2023-01-21_start-Dvy20kPM.js index cb945b8..986a762 100644 --- a/assets/2023-01-21_start-BLjTU3tE.js +++ b/assets/2023-01-21_start-Dvy20kPM.js @@ -1,4 +1,4 @@ -import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as c,o as p,h as l,w as i,a as t,e as n}from"./index-B-kKBcPB.js";const u=t("div",{class:"markdown-body"},[t("h3",null,"Setup"),t("p",null,[n("If project wasn’t created with "),t("a",{href:"https://docs.servicestack.net/dotnet-new"},"x new"),n(", ensure postinstall tasks are run with:")]),t("pre",{class:"language-bash"},[t("code",{class:"language-bash"},[n("$ "),t("span",{class:"token function"},"npm"),n(),t("span",{class:"token function"},"install"),n(` +import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as c,o as p,h as l,w as i,a as t,e as n}from"./index-CoFPLbfm.js";const u=t("div",{class:"markdown-body"},[t("h3",null,"Setup"),t("p",null,[n("If project wasn’t created with "),t("a",{href:"https://docs.servicestack.net/dotnet-new"},"x new"),n(", ensure postinstall tasks are run with:")]),t("pre",{class:"language-bash"},[t("code",{class:"language-bash"},[n("$ "),t("span",{class:"token function"},"npm"),n(),t("span",{class:"token function"},"install"),n(` `)])]),t("h3",null,"Tailwind Configuration"),t("p",null,[n("This template is configured with a stand-alone "),t("a",{href:"https://tailwindcss.com/docs/installation"},"Tailwind CSS CLI"),n(" installation with a modified "),t("strong",null,"tailwind.input.css"),n(" that includes "),t("a",{href:"https://github.com/tailwindlabs/tailwindcss-forms"},"@tailwindcss/forms"),n(" and "),t("a",{href:"https://github.com/tailwindlabs/tailwindcss-aspect-ratio"},"@tailwindcss/aspect-ratio"),n(" plugins so that no "),t("strong",null,"node_modules"),n(" dependencies are needed.")]),t("p",null,[n("The "),t("a",{href:"https://tailwindcss.com/docs/typography-plugin"},"@tailwindcss/typography"),n(" plugin css is contained in "),t("code",null,"css/typography.css"),n(" which applies a beautiful default style to unstyled HTML, ideal for Markdown content like this.")]),t("h3",null,"Running Tailwind during development"),t("p",null,[n("Run tailwind in a new terminal during development to auto update your "),t("strong",null,"app.css"),n(":")]),t("pre",{class:"language-bash"},[t("code",{class:"language-bash"},[n("$ "),t("span",{class:"token function"},"npm"),n(` run ui:dev `)])]),t("p",null,[n("For an optimal development experience run it together with "),t("code",null,"dotnet watch"),n(" to preview changes on each save.")]),t("p",null,[n("Or if using JetBrains Rider, "),t("strong",null,"ui:dev"),n(" can be run directly from Rider in "),t("strong",null,"package.json"),n(":")]),t("p",null,[t("img",{src:"https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/servicestack-reference/scripts-tailwind.png",alt:""})]),t("h3",null,"Using JsonServiceClient in Web Pages"),t("p",null,[n("Easiest way to call APIs is to use "),t("a",{href:"https://docs.servicestack.net/javascript-client"},"@servicestack/client"),n(" with the built-in "),t("a",{href:"https://vue-mjs.web-templates.io/types/mjs"},"/types/mjs"),n(" which returns your APIs annotated typed JS DTOs that can be used immediately (i.e. without any build steps):")]),t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),n("input")]),n(),t("span",{class:"token attr-name"},"type"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("text"),t("span",{class:"token punctuation"},'"')]),n(),t("span",{class:"token attr-name"},"id"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("txtName"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),n(` `),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),n("div")]),n(),t("span",{class:"token attr-name"},"id"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("result"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),n(` diff --git a/assets/2023-02-01_javascript-BozINeQT.js b/assets/2023-02-01_javascript-DsU9PqrK.js similarity index 99% rename from assets/2023-02-01_javascript-BozINeQT.js rename to assets/2023-02-01_javascript-DsU9PqrK.js index 22e6b9d..19edf54 100644 --- a/assets/2023-02-01_javascript-BozINeQT.js +++ b/assets/2023-02-01_javascript-DsU9PqrK.js @@ -1,4 +1,4 @@ -import{_ as v}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{d,r as i,o as r,c as h,a as n,b as t,w as e,e as s,i as f,h as y}from"./index-B-kKBcPB.js";import{_ as w,a as _,b}from"./HelloApi.vue_vue_type_script_setup_true_lang-BNRlbX2m.js";import{_ as S}from"./Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js";const x={class:"not-prose"},A=n("div",{class:"mt-16 mx-auto flex justify-center"},[n("div",{class:"flex items-center"},[n("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",class:"w-32 h-32 sm:w-44 sm:h-44 text-gray-700",viewBox:"0 0 32 32"},[n("path",{fill:"currentColor",d:"M10 6c1.544 1.76 2.276 4.15 2.217 6.61c3.968 1.67 9.924 6.12 11.181 12.39H28C26.051 14.31 14.918 6.77 10 6zm-2 7c4.67 4.913.81 11.582-4 12h18.97C21.5 18.289 11.95 13.533 8 13z"})]),n("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",class:"w-32 h-32 sm:w-44 sm:h-44",viewBox:"0 0 32 32"},[n("path",{fill:"#41b883",d:"M24.4 3.925H30l-14 24.15L2 3.925h10.71l3.29 5.6l3.22-5.6Z"}),n("path",{fill:"#41b883",d:"m2 3.925l14 24.15l14-24.15h-5.6L16 18.415L7.53 3.925Z"}),n("path",{fill:"#35495e",d:"M7.53 3.925L16 18.485l8.4-14.56h-5.18L16 9.525l-3.29-5.6Z"})]),n("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",class:"w-32 h-32 sm:w-44 sm:h-44",viewBox:"0 0 32 32"},[n("path",{fill:"#44a8b3",d:"M9 13.7q1.4-5.6 7-5.6c5.6 0 6.3 4.2 9.1 4.9q2.8.7 4.9-2.1q-1.4 5.6-7 5.6c-5.6 0-6.3-4.2-9.1-4.9q-2.8-.7-4.9 2.1Zm-7 8.4q1.4-5.6 7-5.6c5.6 0 6.3 4.2 9.1 4.9q2.8.7 4.9-2.1q-1.4 5.6-7 5.6c-5.6 0-6.3-4.2-9.1-4.9q-2.8-.7-4.9 2.1Z"})])])],-1),C=n("div",{class:"text-center"},[n("h1",{class:"mt-2 text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100 sm:text-5xl"}," Component Gallery "),n("p",{class:"mt-2 text-lg text-gray-500 dark:text-gray-400"}," Explore Vue Tailwind Component Gallery ")],-1),j={class:"pt-4 pb-16"},M={class:"mx-auto"},T=d({__name:"VueComponentGallery",setup(k){const c=(p,l)=>`${l}`,a={AutoQueryGrid:c("0 0 28 28",""),DataGrid:c("0 0 16 16",""),AutoForms:c("0 0 1024 1024",""),FormInputs:c("0 0 36 36",""),Markdown:c("0 0 15 15",""),Modals:c("0 0 32 32",""),Navigation:c("0 0 12 12",""),Alerts:c("0 0 16 16",""),Formats:c("0 0 1024 1024",""),Code:c("0 0 24 24","")};return(p,l)=>{const o=i("NavListItem"),u=i("NavList");return r(),h("div",x,[A,C,n("div",j,[n("div",M,[t(u,{title:""},{default:e(()=>[t(o,{title:"AutoQueryGrid",href:"https://docs.servicestack.net/vue/autoquerygrid",iconSvg:a.AutoQueryGrid},{default:e(()=>[s(" Instant customizable UIs for calling AutoQuery CRUD APIs ")]),_:1},8,["iconSvg"]),t(o,{title:"DataGrid",href:"https://docs.servicestack.net/vue/datagrid",iconSvg:a.DataGrid},{default:e(()=>[s(" DataGrid Component Examples for rendering tabular data ")]),_:1},8,["iconSvg"]),t(o,{title:"Auto Forms",href:"https://docs.servicestack.net/vue/autoform",iconSvg:a.AutoForms},{default:e(()=>[s(" Render Auto Form UIs from a Request DTO class ")]),_:1},8,["iconSvg"]),t(o,{title:"Form Inputs",href:"https://docs.servicestack.net/vue/form-inputs",iconSvg:a.FormInputs},{default:e(()=>[s(" Tailwind UI Input Components ")]),_:1},8,["iconSvg"]),t(o,{title:"Markdown Editor",href:"https://docs.servicestack.net/vue/markdown",iconSvg:a.Markdown},{default:e(()=>[s(" Rich Markdown Editing Input Control ")]),_:1},8,["iconSvg"]),t(o,{title:"Modals",href:"https://docs.servicestack.net/vue/modals",iconSvg:a.Modals},{default:e(()=>[s(" Modal Dialogs and Slide Overs ")]),_:1},8,["iconSvg"]),t(o,{title:"Navigation",href:"https://docs.servicestack.net/vue/navigation",iconSvg:a.Navigation},{default:e(()=>[s(" Breadcrumbs and Link navigation components ")]),_:1},8,["iconSvg"]),t(o,{title:"Alerts",href:"https://docs.servicestack.net/vue/alerts",iconSvg:a.Alerts},{default:e(()=>[s(" Tailwind Alert and Notification components ")]),_:1},8,["iconSvg"]),t(o,{title:"Formats",href:"https://docs.servicestack.net/vue/formats",iconSvg:a.Formats},{default:e(()=>[s(" HTML Value Formatters ")]),_:1},8,["iconSvg"])]),_:1})])])])}}}),I={class:"not-prose"},V=n("div",{class:"text-center"},[n("h1",{class:"mt-2 text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100 sm:text-5xl"}," Vue Library ")],-1),H={class:"pt-4 pb-16"},L={class:"mx-auto"},P=d({__name:"VueComponentLibrary",setup(k){const a={Code:((p,l)=>`${l}`)("0 0 24 24","")};return(p,l)=>{const o=i("NavListItem"),u=i("NavList");return r(),h("div",I,[V,n("div",H,[n("div",L,[t(u,{class:"mt-8",title:""},{default:e(()=>[t(o,{title:"useMetadata",href:"https://docs.servicestack.net/vue/use-metadata",iconSvg:a.Code},{default:e(()=>[s(" Reflective utils for inspecting API AppMetadata ")]),_:1},8,["iconSvg"]),t(o,{title:"useClient",href:"https://docs.servicestack.net/vue/use-client",iconSvg:a.Code},{default:e(()=>[s(" Utilize JSON Api Client features in Components ")]),_:1},8,["iconSvg"]),t(o,{title:"useAuth",href:"https://docs.servicestack.net/vue/use-auth",iconSvg:a.Code},{default:e(()=>[s(" Inspect Authenticated Users Info, Roles & Permissions ")]),_:1},8,["iconSvg"]),t(o,{title:"useFormatters",href:"https://docs.servicestack.net/vue/use-formatters",iconSvg:a.Code},{default:e(()=>[s(" Built-in Formats and formatting functions ")]),_:1},8,["iconSvg"]),t(o,{title:"useFiles",href:"https://docs.servicestack.net/vue/use-files",iconSvg:a.Code},{default:e(()=>[s(" File utils for resolving SVG icons, extensions and MIME types ")]),_:1},8,["iconSvg"]),t(o,{title:"useConfig",href:"https://docs.servicestack.net/vue/use-config",iconSvg:a.Code},{default:e(()=>[s(" Manage global configuration & defaults ")]),_:1},8,["iconSvg"]),t(o,{title:"useUtils",href:"https://docs.servicestack.net/vue/use-utils",iconSvg:a.Code},{default:e(()=>[s(" General functionality and utils ")]),_:1},8,["iconSvg"])]),_:1})])])])}}}),q={class:"markdown-body"},J=n("p",null,"JavaScript has progressed significantly in recent times where many of the tooling & language enhancements that we used to rely on external tools for is now available in modern browsers alleviating the need for complex tooling and npm dependencies that have historically plagued modern web development.",-1),z=n("p",null,[s("The good news is that the complex npm tooling that was previously considered mandatory in modern JavaScript App development can be considered optional as we can now utilize modern browser features like "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"},"async/await"),s(", "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"},"JavaScript Modules"),s(", "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},"dynamic imports"),s(", "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap"},"import maps"),s(" and "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide"},"modern language features"),s(" for a sophisticated development workflow without the need for any npm build tools.")],-1),Z=n("h3",null,"Bringing Simplicity Back",-1),D=n("p",null,[s("The "),n("a",{href:"https://github.com/NetCoreTemplates/razor"},"razor"),s(" template focuses on simplicity and eschews many aspects that has complicated modern JavaScript development, specifically:")],-1),N=n("ul",null,[n("li",null,"No npm node_modules or build tools"),n("li",null,"No client side routing"),n("li",null,"No heavy client state")],-1),R=n("p",null,[s("Effectively abandoning the traditional SPA approach in lieu of a simpler "),n("a",{href:"https://docs.astro.build/en/concepts/mpa-vs-spa/"},"MPA"),s(" development model using Razor Pages for Server Rendered content with any interactive UIs progressively enhanced with JavaScript.")],-1),U=n("h4",null,"Freedom to use any JS library",-1),E=n("p",null,[s("Avoiding the SPA route ends up affording more flexibility on which JS libraries each page can use as without heavy bundled JS blobs of all JS used in the entire App, it’s free to only load the required JS each page needs to best implement its required functionality, which can be any JS library, preferably utilizing ESM builds that can be referenced from a "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"},"JavaScript Module"),s(", taking advantage of the module system native to modern browsers able to efficiently download the declarative matrix of dependencies each script needs.")],-1),F=n("h3",null,"Best libraries for progressive Multi Page Apps",-1),B=n("p",null,"It includes a collection of libraries we believe offers the best modern development experience in Progressive MPA Web Apps, specifically:",-1),O=n("h4",null,[n("a",{href:"https://tailwindcss.com/docs/installation"},"Tailwind CLI")],-1),W=n("p",null,"Tailwind enables a responsive, utility-first CSS framework for creating maintainable CSS at scale without the need for any CSS preprocessors like Sass, which is configured to run from an npx script to avoid needing any node_module dependencies.",-1),$=n("h4",null,[n("a",{href:"https://vuejs.org/guide/introduction.html"},"Vue 3")],-1),G=n("p",null,[s("Vue is a popular Progressive JavaScript Framework that makes it easy to create interactive Reactive Components whose "),n("a",{href:"https://vuejs.org/api/composition-api-setup.html"},"Composition API"),s(" offers a nice development model without requiring any pre-processors like JSX.")],-1),Q=n("p",null,"Where creating a component is as simple as:",-1),Y=n("pre",{class:"language-js"},[n("code",{class:"language-js"},[n("span",{class:"token keyword"},"const"),s(" Hello "),n("span",{class:"token operator"},"="),s(),n("span",{class:"token punctuation"},"{"),s(` +import{_ as v}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{d,r as i,o as r,c as h,a as n,b as t,w as e,e as s,i as f,h as y}from"./index-CoFPLbfm.js";import{_ as w,a as _,b}from"./HelloApi.vue_vue_type_script_setup_true_lang-DrkDEcx3.js";import{_ as S}from"./Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js";const x={class:"not-prose"},A=n("div",{class:"mt-16 mx-auto flex justify-center"},[n("div",{class:"flex items-center"},[n("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",class:"w-32 h-32 sm:w-44 sm:h-44 text-gray-700",viewBox:"0 0 32 32"},[n("path",{fill:"currentColor",d:"M10 6c1.544 1.76 2.276 4.15 2.217 6.61c3.968 1.67 9.924 6.12 11.181 12.39H28C26.051 14.31 14.918 6.77 10 6zm-2 7c4.67 4.913.81 11.582-4 12h18.97C21.5 18.289 11.95 13.533 8 13z"})]),n("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",class:"w-32 h-32 sm:w-44 sm:h-44",viewBox:"0 0 32 32"},[n("path",{fill:"#41b883",d:"M24.4 3.925H30l-14 24.15L2 3.925h10.71l3.29 5.6l3.22-5.6Z"}),n("path",{fill:"#41b883",d:"m2 3.925l14 24.15l14-24.15h-5.6L16 18.415L7.53 3.925Z"}),n("path",{fill:"#35495e",d:"M7.53 3.925L16 18.485l8.4-14.56h-5.18L16 9.525l-3.29-5.6Z"})]),n("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",class:"w-32 h-32 sm:w-44 sm:h-44",viewBox:"0 0 32 32"},[n("path",{fill:"#44a8b3",d:"M9 13.7q1.4-5.6 7-5.6c5.6 0 6.3 4.2 9.1 4.9q2.8.7 4.9-2.1q-1.4 5.6-7 5.6c-5.6 0-6.3-4.2-9.1-4.9q-2.8-.7-4.9 2.1Zm-7 8.4q1.4-5.6 7-5.6c5.6 0 6.3 4.2 9.1 4.9q2.8.7 4.9-2.1q-1.4 5.6-7 5.6c-5.6 0-6.3-4.2-9.1-4.9q-2.8-.7-4.9 2.1Z"})])])],-1),C=n("div",{class:"text-center"},[n("h1",{class:"mt-2 text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100 sm:text-5xl"}," Component Gallery "),n("p",{class:"mt-2 text-lg text-gray-500 dark:text-gray-400"}," Explore Vue Tailwind Component Gallery ")],-1),j={class:"pt-4 pb-16"},M={class:"mx-auto"},T=d({__name:"VueComponentGallery",setup(k){const c=(p,l)=>`${l}`,a={AutoQueryGrid:c("0 0 28 28",""),DataGrid:c("0 0 16 16",""),AutoForms:c("0 0 1024 1024",""),FormInputs:c("0 0 36 36",""),Markdown:c("0 0 15 15",""),Modals:c("0 0 32 32",""),Navigation:c("0 0 12 12",""),Alerts:c("0 0 16 16",""),Formats:c("0 0 1024 1024",""),Code:c("0 0 24 24","")};return(p,l)=>{const o=i("NavListItem"),u=i("NavList");return r(),h("div",x,[A,C,n("div",j,[n("div",M,[t(u,{title:""},{default:e(()=>[t(o,{title:"AutoQueryGrid",href:"https://docs.servicestack.net/vue/autoquerygrid",iconSvg:a.AutoQueryGrid},{default:e(()=>[s(" Instant customizable UIs for calling AutoQuery CRUD APIs ")]),_:1},8,["iconSvg"]),t(o,{title:"DataGrid",href:"https://docs.servicestack.net/vue/datagrid",iconSvg:a.DataGrid},{default:e(()=>[s(" DataGrid Component Examples for rendering tabular data ")]),_:1},8,["iconSvg"]),t(o,{title:"Auto Forms",href:"https://docs.servicestack.net/vue/autoform",iconSvg:a.AutoForms},{default:e(()=>[s(" Render Auto Form UIs from a Request DTO class ")]),_:1},8,["iconSvg"]),t(o,{title:"Form Inputs",href:"https://docs.servicestack.net/vue/form-inputs",iconSvg:a.FormInputs},{default:e(()=>[s(" Tailwind UI Input Components ")]),_:1},8,["iconSvg"]),t(o,{title:"Markdown Editor",href:"https://docs.servicestack.net/vue/markdown",iconSvg:a.Markdown},{default:e(()=>[s(" Rich Markdown Editing Input Control ")]),_:1},8,["iconSvg"]),t(o,{title:"Modals",href:"https://docs.servicestack.net/vue/modals",iconSvg:a.Modals},{default:e(()=>[s(" Modal Dialogs and Slide Overs ")]),_:1},8,["iconSvg"]),t(o,{title:"Navigation",href:"https://docs.servicestack.net/vue/navigation",iconSvg:a.Navigation},{default:e(()=>[s(" Breadcrumbs and Link navigation components ")]),_:1},8,["iconSvg"]),t(o,{title:"Alerts",href:"https://docs.servicestack.net/vue/alerts",iconSvg:a.Alerts},{default:e(()=>[s(" Tailwind Alert and Notification components ")]),_:1},8,["iconSvg"]),t(o,{title:"Formats",href:"https://docs.servicestack.net/vue/formats",iconSvg:a.Formats},{default:e(()=>[s(" HTML Value Formatters ")]),_:1},8,["iconSvg"])]),_:1})])])])}}}),I={class:"not-prose"},V=n("div",{class:"text-center"},[n("h1",{class:"mt-2 text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100 sm:text-5xl"}," Vue Library ")],-1),H={class:"pt-4 pb-16"},L={class:"mx-auto"},P=d({__name:"VueComponentLibrary",setup(k){const a={Code:((p,l)=>`${l}`)("0 0 24 24","")};return(p,l)=>{const o=i("NavListItem"),u=i("NavList");return r(),h("div",I,[V,n("div",H,[n("div",L,[t(u,{class:"mt-8",title:""},{default:e(()=>[t(o,{title:"useMetadata",href:"https://docs.servicestack.net/vue/use-metadata",iconSvg:a.Code},{default:e(()=>[s(" Reflective utils for inspecting API AppMetadata ")]),_:1},8,["iconSvg"]),t(o,{title:"useClient",href:"https://docs.servicestack.net/vue/use-client",iconSvg:a.Code},{default:e(()=>[s(" Utilize JSON Api Client features in Components ")]),_:1},8,["iconSvg"]),t(o,{title:"useAuth",href:"https://docs.servicestack.net/vue/use-auth",iconSvg:a.Code},{default:e(()=>[s(" Inspect Authenticated Users Info, Roles & Permissions ")]),_:1},8,["iconSvg"]),t(o,{title:"useFormatters",href:"https://docs.servicestack.net/vue/use-formatters",iconSvg:a.Code},{default:e(()=>[s(" Built-in Formats and formatting functions ")]),_:1},8,["iconSvg"]),t(o,{title:"useFiles",href:"https://docs.servicestack.net/vue/use-files",iconSvg:a.Code},{default:e(()=>[s(" File utils for resolving SVG icons, extensions and MIME types ")]),_:1},8,["iconSvg"]),t(o,{title:"useConfig",href:"https://docs.servicestack.net/vue/use-config",iconSvg:a.Code},{default:e(()=>[s(" Manage global configuration & defaults ")]),_:1},8,["iconSvg"]),t(o,{title:"useUtils",href:"https://docs.servicestack.net/vue/use-utils",iconSvg:a.Code},{default:e(()=>[s(" General functionality and utils ")]),_:1},8,["iconSvg"])]),_:1})])])])}}}),q={class:"markdown-body"},J=n("p",null,"JavaScript has progressed significantly in recent times where many of the tooling & language enhancements that we used to rely on external tools for is now available in modern browsers alleviating the need for complex tooling and npm dependencies that have historically plagued modern web development.",-1),z=n("p",null,[s("The good news is that the complex npm tooling that was previously considered mandatory in modern JavaScript App development can be considered optional as we can now utilize modern browser features like "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"},"async/await"),s(", "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"},"JavaScript Modules"),s(", "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},"dynamic imports"),s(", "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap"},"import maps"),s(" and "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide"},"modern language features"),s(" for a sophisticated development workflow without the need for any npm build tools.")],-1),Z=n("h3",null,"Bringing Simplicity Back",-1),D=n("p",null,[s("The "),n("a",{href:"https://github.com/NetCoreTemplates/razor"},"razor"),s(" template focuses on simplicity and eschews many aspects that has complicated modern JavaScript development, specifically:")],-1),N=n("ul",null,[n("li",null,"No npm node_modules or build tools"),n("li",null,"No client side routing"),n("li",null,"No heavy client state")],-1),R=n("p",null,[s("Effectively abandoning the traditional SPA approach in lieu of a simpler "),n("a",{href:"https://docs.astro.build/en/concepts/mpa-vs-spa/"},"MPA"),s(" development model using Razor Pages for Server Rendered content with any interactive UIs progressively enhanced with JavaScript.")],-1),U=n("h4",null,"Freedom to use any JS library",-1),E=n("p",null,[s("Avoiding the SPA route ends up affording more flexibility on which JS libraries each page can use as without heavy bundled JS blobs of all JS used in the entire App, it’s free to only load the required JS each page needs to best implement its required functionality, which can be any JS library, preferably utilizing ESM builds that can be referenced from a "),n("a",{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"},"JavaScript Module"),s(", taking advantage of the module system native to modern browsers able to efficiently download the declarative matrix of dependencies each script needs.")],-1),F=n("h3",null,"Best libraries for progressive Multi Page Apps",-1),B=n("p",null,"It includes a collection of libraries we believe offers the best modern development experience in Progressive MPA Web Apps, specifically:",-1),O=n("h4",null,[n("a",{href:"https://tailwindcss.com/docs/installation"},"Tailwind CLI")],-1),W=n("p",null,"Tailwind enables a responsive, utility-first CSS framework for creating maintainable CSS at scale without the need for any CSS preprocessors like Sass, which is configured to run from an npx script to avoid needing any node_module dependencies.",-1),$=n("h4",null,[n("a",{href:"https://vuejs.org/guide/introduction.html"},"Vue 3")],-1),G=n("p",null,[s("Vue is a popular Progressive JavaScript Framework that makes it easy to create interactive Reactive Components whose "),n("a",{href:"https://vuejs.org/api/composition-api-setup.html"},"Composition API"),s(" offers a nice development model without requiring any pre-processors like JSX.")],-1),Q=n("p",null,"Where creating a component is as simple as:",-1),Y=n("pre",{class:"language-js"},[n("code",{class:"language-js"},[n("span",{class:"token keyword"},"const"),s(" Hello "),n("span",{class:"token operator"},"="),s(),n("span",{class:"token punctuation"},"{"),s(` `),n("span",{class:"token literal-property property"},"template"),n("span",{class:"token operator"},":"),s(),n("span",{class:"token template-string"},[n("span",{class:"token template-punctuation string"},"`"),n("span",{class:"token string"},"Hello, {{name}}!"),n("span",{class:"token template-punctuation string"},"`")]),n("span",{class:"token punctuation"},","),s(` `),n("span",{class:"token literal-property property"},"props"),n("span",{class:"token operator"},":"),s(),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token literal-property property"},"name"),n("span",{class:"token operator"},":"),s("String "),n("span",{class:"token punctuation"},"}"),s(` `),n("span",{class:"token punctuation"},"}"),s(` diff --git a/assets/2023-03-30_razor-ssg-Ci0fv4r7.js b/assets/2023-03-30_razor-ssg-h6EyxEND.js similarity index 99% rename from assets/2023-03-30_razor-ssg-Ci0fv4r7.js rename to assets/2023-03-30_razor-ssg-h6EyxEND.js index 16f29ef..d8b2fb9 100644 --- a/assets/2023-03-30_razor-ssg-Ci0fv4r7.js +++ b/assets/2023-03-30_razor-ssg-h6EyxEND.js @@ -1,4 +1,4 @@ -import{_ as l}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{_ as c}from"./GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js";import{i as p,o as i,h as u,w as r,a as n,b as k,e as s}from"./index-B-kKBcPB.js";const d={class:"markdown-body"},h=n("p",null,[s("Razor SSG is a Razor Pages powered Markdown alternative to "),n("a",{href:"https://jekyllrb.com/"},"Ruby’s Jekyll"),s(" & "),n("a",{href:"https://nextjs.org"},"Next.js"),s(" that’s ideal for generating static websites & blogs using C#, Razor Pages & Markdown.")],-1),g=n("h3",null,"GitHub Codespaces Friendly",-1),m=n("p",null,"In addition to having a pure Razor + .NET solution to create fast, CDN-hostable static websites, it also aims to provide a great experience from GitHub Codespaces, where you can create, modify, preview & check-in changes before the included GitHub Actions auto deploy changes to its GitHub Pages CDN - all from your iPad!",-1),w=n("p",null,[n("a",{href:"https://github.com/features/codespaces"},[n("img",{src:"https://servicestack.net/img/posts/razor-ssg/codespaces.png",alt:""})])],-1),f=n("p",null,[s("To see this in action, we walk through the entire workflow of creating, updating and adding features to a custom Razor SSG website from just a browser using Codespaces, that auto publishes changes to your GitHub Repo’s "),n("strong",null,"gh-pages"),s(" branch where it’s hosted for free on GitHub Pages CDN:")],-1),y=n("iframe",{class:"youtube",src:"https://www.youtube.com/embed/MRQMBrXi5Sc",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:""},null,-1),b=n("h3",null,"Enhance with simple, modern JavaScript",-1),_=n("p",null,[s("For enhanced interactivity, static markdown content can be "),n("a",{href:"https://servicestack.net/posts/javascript"},"progressively enhanced"),s(" with Vue 3 components, as done in this example that embed’s the "),n("a",{href:"https://github.com/NetCoreTemplates/razor-ssg/blob/main/MyApp/wwwroot/mjs/components/GettingStarted.mjs"},"GettingStarted.mjs"),s(" Vue Component to create new Razor SSG App’s below with:")],-1),v=n("pre",{class:"language-html"},[n("code",{class:"language-html"},[n("span",{class:"token tag"},[n("span",{class:"token tag"},[n("span",{class:"token punctuation"},"<"),s("getting-started")]),s(),n("span",{class:"token attr-name"},"template"),n("span",{class:"token attr-value"},[n("span",{class:"token punctuation attr-equals"},"="),n("span",{class:"token punctuation"},'"'),s("razor-ssg"),n("span",{class:"token punctuation"},'"')]),n("span",{class:"token punctuation"},">")]),n("span",{class:"token tag"},[n("span",{class:"token tag"},[n("span",{class:"token punctuation"},"")]),s(` +import{_ as l}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{_ as c}from"./GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js";import{i as p,o as i,h as u,w as r,a as n,b as k,e as s}from"./index-CoFPLbfm.js";const d={class:"markdown-body"},h=n("p",null,[s("Razor SSG is a Razor Pages powered Markdown alternative to "),n("a",{href:"https://jekyllrb.com/"},"Ruby’s Jekyll"),s(" & "),n("a",{href:"https://nextjs.org"},"Next.js"),s(" that’s ideal for generating static websites & blogs using C#, Razor Pages & Markdown.")],-1),g=n("h3",null,"GitHub Codespaces Friendly",-1),m=n("p",null,"In addition to having a pure Razor + .NET solution to create fast, CDN-hostable static websites, it also aims to provide a great experience from GitHub Codespaces, where you can create, modify, preview & check-in changes before the included GitHub Actions auto deploy changes to its GitHub Pages CDN - all from your iPad!",-1),w=n("p",null,[n("a",{href:"https://github.com/features/codespaces"},[n("img",{src:"https://servicestack.net/img/posts/razor-ssg/codespaces.png",alt:""})])],-1),f=n("p",null,[s("To see this in action, we walk through the entire workflow of creating, updating and adding features to a custom Razor SSG website from just a browser using Codespaces, that auto publishes changes to your GitHub Repo’s "),n("strong",null,"gh-pages"),s(" branch where it’s hosted for free on GitHub Pages CDN:")],-1),y=n("iframe",{class:"youtube",src:"https://www.youtube.com/embed/MRQMBrXi5Sc",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:""},null,-1),b=n("h3",null,"Enhance with simple, modern JavaScript",-1),_=n("p",null,[s("For enhanced interactivity, static markdown content can be "),n("a",{href:"https://servicestack.net/posts/javascript"},"progressively enhanced"),s(" with Vue 3 components, as done in this example that embed’s the "),n("a",{href:"https://github.com/NetCoreTemplates/razor-ssg/blob/main/MyApp/wwwroot/mjs/components/GettingStarted.mjs"},"GettingStarted.mjs"),s(" Vue Component to create new Razor SSG App’s below with:")],-1),v=n("pre",{class:"language-html"},[n("code",{class:"language-html"},[n("span",{class:"token tag"},[n("span",{class:"token tag"},[n("span",{class:"token punctuation"},"<"),s("getting-started")]),s(),n("span",{class:"token attr-name"},"template"),n("span",{class:"token attr-value"},[n("span",{class:"token punctuation attr-equals"},"="),n("span",{class:"token punctuation"},'"'),s("razor-ssg"),n("span",{class:"token punctuation"},'"')]),n("span",{class:"token punctuation"},">")]),n("span",{class:"token tag"},[n("span",{class:"token tag"},[n("span",{class:"token punctuation"},"")]),s(` `)])],-1),M={class:"py-8 not-prose text-base flex justify-center"},P=n("p",null,[s("Although with full control over the websites "),n("code",null,"_Layout.cshtml"),s(", you’re free to use any preferred JS Module or Web Component you prefer.")],-1),x=n("h2",null,"Razor Pages",-1),S=n("p",null,[s("Your website can be built using either Markdown "),n("code",null,".md"),s(" or Razor "),n("code",null,".cshtml"),s(" pages, although it’s generally recommended to use Markdown to capture the static content for your website for improved productivity and ease of maintenance.")],-1),z=n("h3",null,"Content in Markdown, Functionality in Razor Pages",-1),A=n("p",null,"The basic premise behind most built-in features is to capture static content in markdown using a combination of folder structure & file name conventions in addition to each markdown page’s frontmatter & content. This information is then used to power each feature using Razor pages for precise layout and functionality.",-1),C=n("p",null,"The template includes the source code for each website feature, enabling full customization that also serves as good examples for how to implement your own custom markdown-powered website features.",-1),T=n("h3",null,"Markdown Feature Structure",-1),R=n("p",null,[s("All markdown features are effectively implemented in the same way, starting with a "),n("strong",null,"_folder"),s(" for maintaining its static markdown content, a "),n("strong",null,".cs"),s(" class to load the markdown and a "),n("strong",null,".cshtml"),s(" Razor Page to render it:")],-1),N=n("table",null,[n("thead",null,[n("tr",null,[n("th",null,"Location"),n("th",null,"Description")])]),n("tbody",null,[n("tr",null,[n("td",null,[n("code",null,"/_{Feature}")]),n("td",null,"Maintains the static markdown for the feature")]),n("tr",null,[n("td",null,[n("code",null,"Markdown.{Feature}.cs")]),n("td",null,"Functionality to read the feature’s markdown into logical collections")]),n("tr",null,[n("td",null,[n("code",null,"{Feature}.cshtml")]),n("td",null,"Functionality to Render the feature")]),n("tr",null,[n("td",null,[n("a",{href:"https://github.com/NetCoreTemplates/razor-ssg/blob/main/MyApp/Configure.Ssg.cs"},"Configure.Ssg.cs")]),n("td",null,"Initializes and registers the feature with ASP .NET’s IOC")])])],-1),L=n("p",null,"Lets see what this looks like in practice by walking through the “Pages” feature:",-1),F=n("h2",null,"Pages Feature",-1),G=n("p",null,[s("The pages feature simply makes all pages in the "),n("strong",null,"_pages"),s(" folder, available from "),n("code",null,"/{filename}"),s(".")],-1),I=n("p",null,"Where the included pages:",-1),B=n("h3",null,[n("a",{href:"https://github.com/NetCoreTemplates/razor-ssg/tree/main/MyApp/_pages"},"/_pages")],-1),V=n("ul",null,[n("li",null,"privacy.md"),n("li",null,"speaking.md"),n("li",null,"uses.md")],-1),D=n("p",null,"Are made available from:",-1),H=n("ul",null,[n("li",null,[n("a",{href:"https://razor-ssg.web-templates.io/privacy"},"/privacy")]),n("li",null,[n("a",{href:"https://razor-ssg.web-templates.io/speaking"},"/speaking")]),n("li",null,[n("a",{href:"https://razor-ssg.web-templates.io/uses"},"/uses")])],-1),j=n("h3",null,"Loading Pages Markdown",-1),W=n("p",null,[s("The code that loads the Pages feature markdown content is in "),n("a",{href:"https://github.com/NetCoreTemplates/razor-ssg/blob/main/MyApp/Markdown.Pages.cs"},"Markdown.Pages.cs"),s(":")],-1),E=n("pre",{class:"language-csharp"},[n("code",{class:"language-csharp"},[n("span",{class:"token keyword"},"public"),s(),n("span",{class:"token keyword"},"class"),s(),n("span",{class:"token class-name"},"MarkdownPages"),s(),n("span",{class:"token punctuation"},":"),s(),n("span",{class:"token type-list"},[n("span",{class:"token class-name"},[s("MarkdownPagesBase"),n("span",{class:"token punctuation"},"<"),s("MarkdownFileInfo"),n("span",{class:"token punctuation"},">")])]),s(` `),n("span",{class:"token punctuation"},"{"),s(` `),n("span",{class:"token keyword"},"public"),s(),n("span",{class:"token function"},"MarkdownPages"),n("span",{class:"token punctuation"},"("),n("span",{class:"token class-name"},[s("ILogger"),n("span",{class:"token punctuation"},"<"),s("MarkdownPages"),n("span",{class:"token punctuation"},">")]),s(" log"),n("span",{class:"token punctuation"},","),s(),n("span",{class:"token class-name"},"IWebHostEnvironment"),s(" env"),n("span",{class:"token punctuation"},")"),s(` diff --git a/assets/2023-08-23_razor-ssg-new-blog-features-DA5S93ND.js b/assets/2023-08-23_razor-ssg-new-blog-features-DJ1Rr8VN.js similarity index 99% rename from assets/2023-08-23_razor-ssg-new-blog-features-DA5S93ND.js rename to assets/2023-08-23_razor-ssg-new-blog-features-DJ1Rr8VN.js index 04ca2f3..3eaff99 100644 --- a/assets/2023-08-23_razor-ssg-new-blog-features-DA5S93ND.js +++ b/assets/2023-08-23_razor-ssg-new-blog-features-DJ1Rr8VN.js @@ -1,4 +1,4 @@ -import{_}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{_ as f}from"./GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js";import{d as k,r as b,o as n,c as e,F as i,g as p,a as t,t as g,h as u,i as y,w as v,b as c,u as S,e as s}from"./index-B-kKBcPB.js";import{C as x}from"./ChartJs-I6khMjFE.js";const C={key:0},z={class:"ml-6 flex items-center text-base leading-8"},M={class:"mr-1 text-slate-600","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},j=t("path",{d:"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"},null,-1),B=[j],R={key:1},P={class:"ml-6"},T={class:"flex items-center text-base leading-8"},G={class:"mr-1 text-slate-600","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 12 12",width:"12",height:"12",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},N=t("path",{d:"M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1l-3.2 3.2c-.2.2-.4.3-.6.3Z"},null,-1),A=[N],F={class:"mr-1 text-sky-500","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},L=t("path",{d:"M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.55 0 1.07.26 1.4.7l.9 1.2a.25.25 0 0 0 .2.1H13a1 1 0 0 1 1 1v.5H2.75a.75.75 0 0 0 0 1.5h11.978a1 1 0 0 1 .994 1.117L15 13.25A1.75 1.75 0 0 1 13.25 15H1.75A1.75 1.75 0 0 1 0 13.25V2.75c0-.464.184-.91.513-1.237Z"},null,-1),$=[L],V=k({__name:"File",props:{label:{},contents:{},depth:{}},setup(d){return(a,r)=>{const l=b("File",!0);return n(),e("div",null,[a.label=="_"?(n(),e("div",C,[(n(!0),e(i,null,p(a.contents,o=>(n(),e("div",z,[(n(),e("svg",M,B)),t("span",null,g(o),1)]))),256))])):(n(),e("div",R,[t("div",P,[t("div",T,[(n(),e("svg",G,A)),(n(),e("svg",F,$)),t("span",null,g(a.label),1)]),(n(!0),e(i,null,p(a.contents,(o,h)=>(n(),u(l,{label:h,contents:o},null,8,["label","contents"]))),256))])]))])}}}),I=k({__name:"FileLayout",props:{files:{}},setup(d){return(a,r)=>(n(),e("div",null,[(n(!0),e(i,null,p(a.files,(l,o)=>(n(),u(V,{label:o,contents:l},null,8,["label","contents"]))),256))]))}}),W={class:"markdown-body"},E=t("h2",null,"New Blogging features in Razor SSG",-1),H=t("p",null,[t("a",{href:"https://razor-ssg.web-templates.io"},"Razor SSG"),s(" is our Free Project Template for creating fast, statically generated Websites and Blogs with Markdown & C# Razor Pages. A benefit of using Razor SSG to maintain this "),t("a",{href:"https://github.com/ServiceStack/servicestack.net"},"servicestack.net(github)"),s(" website is that any improvements added to our website end up being rolled into the Razor SSG Project Template for everyone else to enjoy.")],-1),J=t("p",null,[s("This latest release brings a number of features and enhancements to improve Razor SSG usage as a Blogging Platform - a primary use-case we’re focused on as we pen our "),t("a",{href:"https://servicestack.net/posts/year/2023"},"22nd Blog Post for the year"),s(" with improvements in both discoverability and capability of blog posts:")],-1),q=t("h3",null,"RSS Feed",-1),D=t("p",null,"Razor SSG websites now generates a valid RSS Feed for its blog to support their readers who’d prefer to read blog posts and notify them as they’re published with their favorite RSS reader:",-1),U=t("div",{class:"not-prose my-8"},[t("a",{href:"https://razor-ssg.web-templates.io/feed.xml"},[t("div",{class:"block flex justify-center shadow hover:shadow-lg rounded overflow-hidden"},[t("img",{class:"max-w-3xl py-8",src:"https://servicestack.net/img/posts/razor-ssg/valid-rss.png"})])]),t("div",{class:"mt-4 flex justify-center"},[t("a",{class:"text-indigo-600 hover:text-indigo-800",href:"https://razor-ssg.web-templates.io/feed.xml"},"https://razor-ssg.web-templates.io/feed.xml"),t("a",{class:"ml-4 text-indigo-600 hover:text-indigo-800",href:"https://servicestack.net/feed.xml"},"https://servicestack.net/feed.xml")])],-1),Q=t("h3",null,"Meta Headers support for Twitter cards and SEO",-1),Z=t("p",null,[s("Blog Posts and Pages now include additional "),t("code",null,""),s(" HTML Headers to enable support for "),t("a",{href:"https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards"},"Twitter Cards"),s(" in both Twitter and Meta’s new "),t("a",{href:"https://threads.net"},"threads.net"),s(", e.g:")],-1),O=t("div",{class:"not-prose my-8 flex justify-center"},[t("a",{class:"block max-w-2xl",href:"https://www.threads.net/@servicestack/post/CvIFobPBs5h"},[t("div",{class:"block flex justify-center shadow hover:shadow-lg rounded overflow-hidden"},[t("img",{class:"py-8",src:"https://servicestack.net/img/posts/razor-ssg/twitter-cards.png"})])])],-1),Y=t("h3",null,"Improved Discoverability",-1),K=t("p",null,"To improve discoverability and increase site engagement, bottom of blog posts now include links to other posts by the same Blog Author, including links to connect to their preferred social networks and contact preferences:",-1),X=t("p",null,[t("img",{src:"https://servicestack.net/img/posts/razor-ssg/other-author-posts.png",alt:""})],-1),tt=t("h3",null,"Posts can include Vue Components",-1),st=t("p",null,"Blog Posts can now embed any global Vue Components directly in its Markdown, e.g:",-1),nt=t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),s("getting-started")]),s(),t("span",{class:"token attr-name"},"template"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),s("razor-ssg"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),s(` +import{_}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{_ as f}from"./GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js";import{d as k,r as b,o as n,c as e,F as i,g as p,a as t,t as g,h as u,i as y,w as v,b as c,u as S,e as s}from"./index-CoFPLbfm.js";import{C as x}from"./ChartJs-ljXEK9mH.js";const C={key:0},z={class:"ml-6 flex items-center text-base leading-8"},M={class:"mr-1 text-slate-600","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},j=t("path",{d:"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"},null,-1),B=[j],R={key:1},P={class:"ml-6"},T={class:"flex items-center text-base leading-8"},G={class:"mr-1 text-slate-600","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 12 12",width:"12",height:"12",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},N=t("path",{d:"M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1l-3.2 3.2c-.2.2-.4.3-.6.3Z"},null,-1),A=[N],F={class:"mr-1 text-sky-500","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},L=t("path",{d:"M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.55 0 1.07.26 1.4.7l.9 1.2a.25.25 0 0 0 .2.1H13a1 1 0 0 1 1 1v.5H2.75a.75.75 0 0 0 0 1.5h11.978a1 1 0 0 1 .994 1.117L15 13.25A1.75 1.75 0 0 1 13.25 15H1.75A1.75 1.75 0 0 1 0 13.25V2.75c0-.464.184-.91.513-1.237Z"},null,-1),$=[L],V=k({__name:"File",props:{label:{},contents:{},depth:{}},setup(d){return(a,r)=>{const l=b("File",!0);return n(),e("div",null,[a.label=="_"?(n(),e("div",C,[(n(!0),e(i,null,p(a.contents,o=>(n(),e("div",z,[(n(),e("svg",M,B)),t("span",null,g(o),1)]))),256))])):(n(),e("div",R,[t("div",P,[t("div",T,[(n(),e("svg",G,A)),(n(),e("svg",F,$)),t("span",null,g(a.label),1)]),(n(!0),e(i,null,p(a.contents,(o,h)=>(n(),u(l,{label:h,contents:o},null,8,["label","contents"]))),256))])]))])}}}),I=k({__name:"FileLayout",props:{files:{}},setup(d){return(a,r)=>(n(),e("div",null,[(n(!0),e(i,null,p(a.files,(l,o)=>(n(),u(V,{label:o,contents:l},null,8,["label","contents"]))),256))]))}}),W={class:"markdown-body"},E=t("h2",null,"New Blogging features in Razor SSG",-1),H=t("p",null,[t("a",{href:"https://razor-ssg.web-templates.io"},"Razor SSG"),s(" is our Free Project Template for creating fast, statically generated Websites and Blogs with Markdown & C# Razor Pages. A benefit of using Razor SSG to maintain this "),t("a",{href:"https://github.com/ServiceStack/servicestack.net"},"servicestack.net(github)"),s(" website is that any improvements added to our website end up being rolled into the Razor SSG Project Template for everyone else to enjoy.")],-1),J=t("p",null,[s("This latest release brings a number of features and enhancements to improve Razor SSG usage as a Blogging Platform - a primary use-case we’re focused on as we pen our "),t("a",{href:"https://servicestack.net/posts/year/2023"},"22nd Blog Post for the year"),s(" with improvements in both discoverability and capability of blog posts:")],-1),q=t("h3",null,"RSS Feed",-1),D=t("p",null,"Razor SSG websites now generates a valid RSS Feed for its blog to support their readers who’d prefer to read blog posts and notify them as they’re published with their favorite RSS reader:",-1),U=t("div",{class:"not-prose my-8"},[t("a",{href:"https://razor-ssg.web-templates.io/feed.xml"},[t("div",{class:"block flex justify-center shadow hover:shadow-lg rounded overflow-hidden"},[t("img",{class:"max-w-3xl py-8",src:"https://servicestack.net/img/posts/razor-ssg/valid-rss.png"})])]),t("div",{class:"mt-4 flex justify-center"},[t("a",{class:"text-indigo-600 hover:text-indigo-800",href:"https://razor-ssg.web-templates.io/feed.xml"},"https://razor-ssg.web-templates.io/feed.xml"),t("a",{class:"ml-4 text-indigo-600 hover:text-indigo-800",href:"https://servicestack.net/feed.xml"},"https://servicestack.net/feed.xml")])],-1),Q=t("h3",null,"Meta Headers support for Twitter cards and SEO",-1),Z=t("p",null,[s("Blog Posts and Pages now include additional "),t("code",null,""),s(" HTML Headers to enable support for "),t("a",{href:"https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards"},"Twitter Cards"),s(" in both Twitter and Meta’s new "),t("a",{href:"https://threads.net"},"threads.net"),s(", e.g:")],-1),O=t("div",{class:"not-prose my-8 flex justify-center"},[t("a",{class:"block max-w-2xl",href:"https://www.threads.net/@servicestack/post/CvIFobPBs5h"},[t("div",{class:"block flex justify-center shadow hover:shadow-lg rounded overflow-hidden"},[t("img",{class:"py-8",src:"https://servicestack.net/img/posts/razor-ssg/twitter-cards.png"})])])],-1),Y=t("h3",null,"Improved Discoverability",-1),K=t("p",null,"To improve discoverability and increase site engagement, bottom of blog posts now include links to other posts by the same Blog Author, including links to connect to their preferred social networks and contact preferences:",-1),X=t("p",null,[t("img",{src:"https://servicestack.net/img/posts/razor-ssg/other-author-posts.png",alt:""})],-1),tt=t("h3",null,"Posts can include Vue Components",-1),st=t("p",null,"Blog Posts can now embed any global Vue Components directly in its Markdown, e.g:",-1),nt=t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),s("getting-started")]),s(),t("span",{class:"token attr-name"},"template"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),s("razor-ssg"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),s(` `)])],-1),et=t("h4",null,[t("a",{href:"https://github.com/NetCoreTemplates/razor-ssg/blob/main/MyApp/wwwroot/mjs/components/GettingStarted.mjs"},"/mjs/components/GettingStarted.mjs")],-1),at={class:"not-prose my-20 flex justify-center"},ot=t("h4",null,"Individual Blog Post dependencies",-1),rt=t("p",null,[s("Just like Pages and Docs they can also include specific JavaScript "),t("strong",null,".mjs"),s(" or "),t("strong",null,".css"),s(" in the "),t("code",null,"/wwwroot/posts"),s(" folder which will only be loaded for that post:")],-1),lt=t("p",null,[s("Now posts that need it can dynamically load large libraries like "),t("a",{href:"https://www.chartjs.org"},"Chart.js"),s(" and use it inside a custom Vue component by creating a custom "),t("code",null,"/posts/.mjs"),s(" that exports what components and features your blog post needs, e.g:")],-1),ct=t("h4",null,[t("a",{href:"https://github.com/NetCoreTemplates/razor-ssg/blob/main/MyApp/wwwroot/posts/new-blog-features.mjs"},"/posts/new-blog-features.mjs")],-1),it=t("pre",{class:"language-js"},[t("code",{class:"language-js"},[t("span",{class:"token keyword"},"import"),s(" ChartJs "),t("span",{class:"token keyword"},"from"),s(),t("span",{class:"token string"},"'./components/ChartJs.mjs'"),s(` `),t("span",{class:"token keyword"},"export"),s(),t("span",{class:"token keyword"},"default"),s(),t("span",{class:"token punctuation"},"{"),s(` diff --git a/assets/2023-11-20_net8-blazor-template-BS9qPuaN.js b/assets/2023-11-20_net8-blazor-template-csCQIEk-.js similarity index 97% rename from assets/2023-11-20_net8-blazor-template-BS9qPuaN.js rename to assets/2023-11-20_net8-blazor-template-csCQIEk-.js index 0681a38..576fa08 100644 --- a/assets/2023-11-20_net8-blazor-template-BS9qPuaN.js +++ b/assets/2023-11-20_net8-blazor-template-csCQIEk-.js @@ -1 +1 @@ -import{_ as p}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{d,o as n,h as s,u as h,i as u,r as m,w as f,a as t,b as i,e}from"./index-B-kKBcPB.js";import{_ as w,I as g}from"./Templates.vue_vue_type_script_setup_true_lang-DajVBfQg.js";const y=d({__name:"BlazorTemplate",setup(r){return(o,a)=>(n(),s(w,{templates:[h(g).blazor]},null,8,["templates"]))}}),b={class:"markdown-body"},v=t("p",null,[e("With the release of "),t("strong",null,".NET 8"),e(", we’re happy to announce ServiceStack’s new "),t("a",{href:"https://blazor.web-templates.io/"},"Blazor"),e(" Tailwind project template that takes advantage of .NET 8 Blazor’s new features that redefines modern Web Development in C#.")],-1),_=t("p",null,[e("In this video overview we’ll explore how the template, adopts Blazor’s familiar "),t("strong",null,"ASP.NET Core Identity"),e(" for its authentication, utilizes the modern "),t("a",{href:"https://tailwindcss.com"},"Tailwind CSS"),e(" framework for beautiful responsive design and adopts .NET’s best-practice "),t("a",{href:"https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container"},"Docker Containerization"),e(" support for its built-in "),t("a",{href:"https://blazor.web-templates.io/deploy"},"GitHub Action Deployments"),e(" which enables a simple ready-made CI solution for deployment to any Linux Host via SSH and Docker compose.")],-1),T=t("p",null,[e("We’ll also discuss the project’s structure, usage of "),t("strong",null,"ASP.NET Core Identity"),e(" for Authorization and utilizing "),t("strong",null,"ServiceStack Blazor Components"),e(" for data handling, all integrated to maximize developer efficiency in building Web Applications.")],-1),x=t("div",{class:"not-prose mt-16 flex flex-col items-center"},[t("div",{class:"flex"},[t("svg",{class:"w-28 h-28 text-purple-500",xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"currentColor",d:"M23.834 8.101a13.912 13.912 0 0 1-13.643 11.72a10.105 10.105 0 0 1-1.994-.12a6.111 6.111 0 0 1-5.082-5.761a5.934 5.934 0 0 1 11.867-.084c.025.983-.401 1.846-1.277 1.871c-.936 0-1.374-.668-1.374-1.567v-2.5a1.531 1.531 0 0 0-1.52-1.533H8.715a3.648 3.648 0 1 0 2.695 6.08l.073-.11l.074.121a2.58 2.58 0 0 0 2.2 1.048a2.909 2.909 0 0 0 2.695-3.04a7.912 7.912 0 0 0-.217-1.933a7.404 7.404 0 0 0-14.64 1.603a7.497 7.497 0 0 0 7.308 7.405s.549.05 1.167.035a15.803 15.803 0 0 0 8.475-2.528c.036-.025.072.025.048.061a12.44 12.44 0 0 1-9.69 3.963a8.744 8.744 0 0 1-8.9-8.972a9.049 9.049 0 0 1 3.635-7.247a8.863 8.863 0 0 1 5.229-1.726h2.813a7.915 7.915 0 0 0 5.839-2.578a.11.11 0 0 1 .059-.034a.112.112 0 0 1 .12.053a.113.113 0 0 1 .015.067a7.934 7.934 0 0 1-1.227 3.549a.107.107 0 0 0-.014.06a.11.11 0 0 0 .073.095a.109.109 0 0 0 .062.004a8.505 8.505 0 0 0 5.913-4.876a.155.155 0 0 1 .055-.053a.15.15 0 0 1 .147 0a.153.153 0 0 1 .054.053A10.779 10.779 0 0 1 23.834 8.1zM8.895 11.628a2.188 2.188 0 1 0 2.188 2.188v-2.042a.158.158 0 0 0-.15-.15Z"})])])],-1),z={class:"not-prose mt-4 px-4 sm:px-6"},k=t("div",{class:"text-center"},[t("h3",{id:"blazor-template",class:"text-4xl sm:text-5xl md:text-6xl tracking-tight font-extrabold text-gray-900"}," Blazor Tailwind Template ")],-1),S={class:"py-8 max-w-7xl mx-auto px-4 sm:px-6"},A={class:"not-prose relative bg-white dark:bg-black py-4"},B=t("div",{class:"mx-auto max-w-md px-4 text-center sm:max-w-3xl sm:px-6 lg:max-w-7xl lg:px-8"},[t("p",{class:"mt-2 text-3xl font-extrabold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},"Create a new Blazor Tailwind App"),t("p",{class:"mx-auto mt-5 max-w-prose text-xl text-gray-500"}," Create a new Blazor Tailwind project with your preferred project name: ")],-1),I=t("h2",null,"ASP.NET Core Identity Integration",-1),N=t("p",null,"In terms of security, the template integrates ASP.NET Core Identity, offering a structured approach to authentication, including support for email confirmation, two-factor authentication and GDPR compliance features.",-1),C=t("p",null,[e("Integrating ASP.NET Core Identity doesn’t complicate securing ServiceStack services which can still be secured with "),t("a",{href:"https://docs.servicestack.net/auth/authentication-and-authorization#declarative-validation-attributes"},"Declarative Validation Attributes"),e(" for role-based access control, e.g. using "),t("code",null,'[ValidateHasRole("Employee")]'),e(" directly on Request DTOs, bringing any existing knowledge and experience with ServiceStack Authentication to securing UIs and APIs with Identity Auth.")],-1),E=t("p",null,[e("The template includes a pre-baked solution for sending general and Identity Auth Emails with your configured SMTP Server in managed background workers with "),t("a",{href:"https://docs.servicestack.net/background-mq"},"Background MQ"),e(" and an enhanced version of the default ASP.NET Core Blazor Identity UI, with all pages upgraded to use a beautiful Tailwind CSS theme as well as integration with "),t("a",{href:"https://davidshimjs.github.io/qrcodejs/"},"qrcode.js"),e(" for providing a visual QR Code barcode which mobile phone users can easily scan to setup 2FA Authentication:")],-1),D=t("p",null,[t("img",{src:"https://servicestack.net/img/posts/net8-best-blazor/blazor-identityauth-qrcode.png",alt:""})],-1),U=t("h2",null,"Responsive and Interactive UIs with Tailwind CSS",-1),P=t("p",null,[e("With responsive UI out-of-the-box, thanks to Tailwind CSS, Developers can style their Blazor Apps with the modern popular utility-first CSS framework for creating beautiful, maintainable "),t("strong",null,"Responsive UIs"),e(" with "),t("strong",null,"DarkMode"),e(" support")],-1),j=t("p",null,"It also takes full advantage of Blazor’s static rendering for its Website layout for optimal performance and SEO, so only Pages and Components that require interactivity need to opt-in for Blazor Server Interactive rendering modes.",-1),R=t("h2",null,"ServiceStack.Blazor Tailwind Components",-1),H=t("p",null,[e("The "),t("a",{href:"https://blazor-gallery.jamstacks.net"},"ServiceStack.Blazor Components"),e(", updated for .NET 8 enables you to rapidly develop beautiful Blazor Apps integrated with Rich high-productivity UI Tailwind Components like "),t("a",{href:"https://blazor-gallery.servicestack.net/gallery/autoquerygrid"},"AutoQueryGrid"),e(" and "),t("a",{href:"https://blazor-gallery.servicestack.net/gallery/autoform"},"AutoForms"),e(" which interface with "),t("a",{href:"https://docs.servicestack.net/autoquery/"},"AutoQuery services"),e(" to provide a full CRUD data management UI with minimal effort.")],-1),L=t("h2",null,"Enhanced Containerization",-1),M=t("p",null,[e(".NET 8 simplifies Docker integration. Using "),t("code",null,"dotnet publish"),e(", developers can now automate the creation of Docker images that adhere to best security practices, such as running as a non-root user in containers that can utilize the built-in GitHub Actions to effortlessly deploy their containerized Blazor Apps with Docker and GitHub Registry via SSH to any Linux Server.")],-1),q=t("h2",null,"Other Template Features",-1),O=t("p",null,"Other features that enhances the default ASP.NET Blazor App templates with several modern, high-productivity features, include:",-1),Q=t("ul",null,[t("li",null,[t("a",{href:"https://learn.microsoft.com/ef/"},"Entity Framework"),e(" & "),t("a",{href:"https://docs.servicestack.net/ormlite/"},"OrmLite"),e(" - Choose the best ORM for each App feature, with a unified solution that sees "),t("a",{href:"https://docs.servicestack.net/ormlite/db-migrations"},"OrmLite’s DB Migrations"),e(" run both EF and OrmLite migrations, inc. Seed Data with a single command at Development or Deployment")]),t("li",null,[t("a",{href:"https://www.sqlite.org"},"SQLite Database"),e(" - Set up as the default database, it allows developers to start immediately without configuring a separate database server")]),t("li",null,[t("a",{href:"https://docs.servicestack.net/autoquery/"},"AutoQuery"),e(" - Rapidly developing data-driven APIs, UIs and CRUD Apps")]),t("li",null,[t("a",{href:"https://www.youtube.com/watch?v=tt0ytzVVjEY"},"Auto Admin Pages"),e(" - Quickly develop your back-office CRUD Admin UIs to manage your App’s Database tables at "),t("a",{href:"https://blazor.web-templates.io/admin"},"/admin")]),t("li",null,[t("a",{href:"https://docs.servicestack.net/razor-press/syntax"},"Markdown"),e(" - Maintain SEO-friendly documentation and content-rich pages like this one with just Markdown, beautifully styled with "),t("a",{href:"https://tailwindcss.com/docs/typography-plugin"},"@tailwindcss/typography")]),t("li",null,[t("a",{href:"https://servicestack.net/auto-ui"},"Built-in UIs"),e(" - Use ServiceStack’s Auto UIs to "),t("a",{href:"https://docs.servicestack.net/api-explorer"},"Explore your APIs"),e(" at "),t("a",{href:"https://blazor.web-templates.io/ui/"},"/ui"),e(" or Query your "),t("a",{href:"https://docs.servicestack.net/admin-ui-database"},"App’s Database Tables"),e(" at "),t("a",{href:"https://blazor.web-templates.io/admin-ui/database"},"/admin-ui/database")]),t("li",null,[t("a",{href:"https://youtu.be/66DgLHExC9E"},"Universal API Components"),e(" - Effortlessly create reusable, maximally performant universal Blazor API Components that works in Blazor Server and Web Assembly Interactivity modes")]),t("li",null,[t("a",{href:"https://docs.servicestack.net/physical-project-structure"},"Organized Project Structure"),e(" - Divided into AppHost, Service Interface, Service Model, and Tests projects to promote separation of concerns and maintainability.")])],-1),Z="New .NET 8 Blazor Tailwind Template",J="The new Blazor for .NET 8 template streamlines web UI development in C#.",K=["dotnet","blazor","templates"],X="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000",tt="Lucy Bates",et=[{property:"og:title",content:"New .NET 8 Blazor Tailwind Template"},{name:"twitter:title",content:"New .NET 8 Blazor Tailwind Template"},{property:"og:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}],at={__name:"2023-11-20_net8-blazor-template",setup(r,{expose:o}){const a={title:"New .NET 8 Blazor Tailwind Template",summary:"The new Blazor for .NET 8 template streamlines web UI development in C#.",tags:["dotnet","blazor","templates"],image:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000",author:"Lucy Bates",meta:[{property:"og:title",content:"New .NET 8 Blazor Tailwind Template"},{name:"twitter:title",content:"New .NET 8 Blazor Tailwind Template"},{property:"og:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]};return o({frontmatter:a}),u({title:"New .NET 8 Blazor Tailwind Template",meta:[{property:"og:title",content:"New .NET 8 Blazor Tailwind Template"},{name:"twitter:title",content:"New .NET 8 Blazor Tailwind Template"},{property:"og:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]}),(W,F)=>{const l=m("LiteYouTube"),c=p;return n(),s(c,{frontmatter:a},{default:f(()=>[t("div",b,[v,_,T,x,t("div",z,[k,t("div",S,[i(l,{id:"hqyozHSL0Nk",title:".NET 8 Blazor Tailwind Template"})])]),t("div",A,[B,i(y)]),I,N,C,E,D,U,P,j,R,H,L,M,q,O,Q])]),_:1})}}};export{tt as author,at as default,X as image,et as meta,J as summary,K as tags,Z as title}; +import{_ as p}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{d,o as n,h as s,u as h,i as u,r as m,w as f,a as t,b as i,e}from"./index-CoFPLbfm.js";import{_ as w,I as g}from"./Templates.vue_vue_type_script_setup_true_lang-8Ivl7FzK.js";const y=d({__name:"BlazorTemplate",setup(r){return(o,a)=>(n(),s(w,{templates:[h(g).blazor]},null,8,["templates"]))}}),b={class:"markdown-body"},v=t("p",null,[e("With the release of "),t("strong",null,".NET 8"),e(", we’re happy to announce ServiceStack’s new "),t("a",{href:"https://blazor.web-templates.io/"},"Blazor"),e(" Tailwind project template that takes advantage of .NET 8 Blazor’s new features that redefines modern Web Development in C#.")],-1),_=t("p",null,[e("In this video overview we’ll explore how the template, adopts Blazor’s familiar "),t("strong",null,"ASP.NET Core Identity"),e(" for its authentication, utilizes the modern "),t("a",{href:"https://tailwindcss.com"},"Tailwind CSS"),e(" framework for beautiful responsive design and adopts .NET’s best-practice "),t("a",{href:"https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container"},"Docker Containerization"),e(" support for its built-in "),t("a",{href:"https://blazor.web-templates.io/deploy"},"GitHub Action Deployments"),e(" which enables a simple ready-made CI solution for deployment to any Linux Host via SSH and Docker compose.")],-1),T=t("p",null,[e("We’ll also discuss the project’s structure, usage of "),t("strong",null,"ASP.NET Core Identity"),e(" for Authorization and utilizing "),t("strong",null,"ServiceStack Blazor Components"),e(" for data handling, all integrated to maximize developer efficiency in building Web Applications.")],-1),x=t("div",{class:"not-prose mt-16 flex flex-col items-center"},[t("div",{class:"flex"},[t("svg",{class:"w-28 h-28 text-purple-500",xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"currentColor",d:"M23.834 8.101a13.912 13.912 0 0 1-13.643 11.72a10.105 10.105 0 0 1-1.994-.12a6.111 6.111 0 0 1-5.082-5.761a5.934 5.934 0 0 1 11.867-.084c.025.983-.401 1.846-1.277 1.871c-.936 0-1.374-.668-1.374-1.567v-2.5a1.531 1.531 0 0 0-1.52-1.533H8.715a3.648 3.648 0 1 0 2.695 6.08l.073-.11l.074.121a2.58 2.58 0 0 0 2.2 1.048a2.909 2.909 0 0 0 2.695-3.04a7.912 7.912 0 0 0-.217-1.933a7.404 7.404 0 0 0-14.64 1.603a7.497 7.497 0 0 0 7.308 7.405s.549.05 1.167.035a15.803 15.803 0 0 0 8.475-2.528c.036-.025.072.025.048.061a12.44 12.44 0 0 1-9.69 3.963a8.744 8.744 0 0 1-8.9-8.972a9.049 9.049 0 0 1 3.635-7.247a8.863 8.863 0 0 1 5.229-1.726h2.813a7.915 7.915 0 0 0 5.839-2.578a.11.11 0 0 1 .059-.034a.112.112 0 0 1 .12.053a.113.113 0 0 1 .015.067a7.934 7.934 0 0 1-1.227 3.549a.107.107 0 0 0-.014.06a.11.11 0 0 0 .073.095a.109.109 0 0 0 .062.004a8.505 8.505 0 0 0 5.913-4.876a.155.155 0 0 1 .055-.053a.15.15 0 0 1 .147 0a.153.153 0 0 1 .054.053A10.779 10.779 0 0 1 23.834 8.1zM8.895 11.628a2.188 2.188 0 1 0 2.188 2.188v-2.042a.158.158 0 0 0-.15-.15Z"})])])],-1),z={class:"not-prose mt-4 px-4 sm:px-6"},k=t("div",{class:"text-center"},[t("h3",{id:"blazor-template",class:"text-4xl sm:text-5xl md:text-6xl tracking-tight font-extrabold text-gray-900"}," Blazor Tailwind Template ")],-1),S={class:"py-8 max-w-7xl mx-auto px-4 sm:px-6"},A={class:"not-prose relative bg-white dark:bg-black py-4"},B=t("div",{class:"mx-auto max-w-md px-4 text-center sm:max-w-3xl sm:px-6 lg:max-w-7xl lg:px-8"},[t("p",{class:"mt-2 text-3xl font-extrabold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},"Create a new Blazor Tailwind App"),t("p",{class:"mx-auto mt-5 max-w-prose text-xl text-gray-500"}," Create a new Blazor Tailwind project with your preferred project name: ")],-1),I=t("h2",null,"ASP.NET Core Identity Integration",-1),N=t("p",null,"In terms of security, the template integrates ASP.NET Core Identity, offering a structured approach to authentication, including support for email confirmation, two-factor authentication and GDPR compliance features.",-1),C=t("p",null,[e("Integrating ASP.NET Core Identity doesn’t complicate securing ServiceStack services which can still be secured with "),t("a",{href:"https://docs.servicestack.net/auth/authentication-and-authorization#declarative-validation-attributes"},"Declarative Validation Attributes"),e(" for role-based access control, e.g. using "),t("code",null,'[ValidateHasRole("Employee")]'),e(" directly on Request DTOs, bringing any existing knowledge and experience with ServiceStack Authentication to securing UIs and APIs with Identity Auth.")],-1),E=t("p",null,[e("The template includes a pre-baked solution for sending general and Identity Auth Emails with your configured SMTP Server in managed background workers with "),t("a",{href:"https://docs.servicestack.net/background-mq"},"Background MQ"),e(" and an enhanced version of the default ASP.NET Core Blazor Identity UI, with all pages upgraded to use a beautiful Tailwind CSS theme as well as integration with "),t("a",{href:"https://davidshimjs.github.io/qrcodejs/"},"qrcode.js"),e(" for providing a visual QR Code barcode which mobile phone users can easily scan to setup 2FA Authentication:")],-1),D=t("p",null,[t("img",{src:"https://servicestack.net/img/posts/net8-best-blazor/blazor-identityauth-qrcode.png",alt:""})],-1),U=t("h2",null,"Responsive and Interactive UIs with Tailwind CSS",-1),P=t("p",null,[e("With responsive UI out-of-the-box, thanks to Tailwind CSS, Developers can style their Blazor Apps with the modern popular utility-first CSS framework for creating beautiful, maintainable "),t("strong",null,"Responsive UIs"),e(" with "),t("strong",null,"DarkMode"),e(" support")],-1),j=t("p",null,"It also takes full advantage of Blazor’s static rendering for its Website layout for optimal performance and SEO, so only Pages and Components that require interactivity need to opt-in for Blazor Server Interactive rendering modes.",-1),R=t("h2",null,"ServiceStack.Blazor Tailwind Components",-1),H=t("p",null,[e("The "),t("a",{href:"https://blazor-gallery.jamstacks.net"},"ServiceStack.Blazor Components"),e(", updated for .NET 8 enables you to rapidly develop beautiful Blazor Apps integrated with Rich high-productivity UI Tailwind Components like "),t("a",{href:"https://blazor-gallery.servicestack.net/gallery/autoquerygrid"},"AutoQueryGrid"),e(" and "),t("a",{href:"https://blazor-gallery.servicestack.net/gallery/autoform"},"AutoForms"),e(" which interface with "),t("a",{href:"https://docs.servicestack.net/autoquery/"},"AutoQuery services"),e(" to provide a full CRUD data management UI with minimal effort.")],-1),L=t("h2",null,"Enhanced Containerization",-1),M=t("p",null,[e(".NET 8 simplifies Docker integration. Using "),t("code",null,"dotnet publish"),e(", developers can now automate the creation of Docker images that adhere to best security practices, such as running as a non-root user in containers that can utilize the built-in GitHub Actions to effortlessly deploy their containerized Blazor Apps with Docker and GitHub Registry via SSH to any Linux Server.")],-1),q=t("h2",null,"Other Template Features",-1),O=t("p",null,"Other features that enhances the default ASP.NET Blazor App templates with several modern, high-productivity features, include:",-1),Q=t("ul",null,[t("li",null,[t("a",{href:"https://learn.microsoft.com/ef/"},"Entity Framework"),e(" & "),t("a",{href:"https://docs.servicestack.net/ormlite/"},"OrmLite"),e(" - Choose the best ORM for each App feature, with a unified solution that sees "),t("a",{href:"https://docs.servicestack.net/ormlite/db-migrations"},"OrmLite’s DB Migrations"),e(" run both EF and OrmLite migrations, inc. Seed Data with a single command at Development or Deployment")]),t("li",null,[t("a",{href:"https://www.sqlite.org"},"SQLite Database"),e(" - Set up as the default database, it allows developers to start immediately without configuring a separate database server")]),t("li",null,[t("a",{href:"https://docs.servicestack.net/autoquery/"},"AutoQuery"),e(" - Rapidly developing data-driven APIs, UIs and CRUD Apps")]),t("li",null,[t("a",{href:"https://www.youtube.com/watch?v=tt0ytzVVjEY"},"Auto Admin Pages"),e(" - Quickly develop your back-office CRUD Admin UIs to manage your App’s Database tables at "),t("a",{href:"https://blazor.web-templates.io/admin"},"/admin")]),t("li",null,[t("a",{href:"https://docs.servicestack.net/razor-press/syntax"},"Markdown"),e(" - Maintain SEO-friendly documentation and content-rich pages like this one with just Markdown, beautifully styled with "),t("a",{href:"https://tailwindcss.com/docs/typography-plugin"},"@tailwindcss/typography")]),t("li",null,[t("a",{href:"https://servicestack.net/auto-ui"},"Built-in UIs"),e(" - Use ServiceStack’s Auto UIs to "),t("a",{href:"https://docs.servicestack.net/api-explorer"},"Explore your APIs"),e(" at "),t("a",{href:"https://blazor.web-templates.io/ui/"},"/ui"),e(" or Query your "),t("a",{href:"https://docs.servicestack.net/admin-ui-database"},"App’s Database Tables"),e(" at "),t("a",{href:"https://blazor.web-templates.io/admin-ui/database"},"/admin-ui/database")]),t("li",null,[t("a",{href:"https://youtu.be/66DgLHExC9E"},"Universal API Components"),e(" - Effortlessly create reusable, maximally performant universal Blazor API Components that works in Blazor Server and Web Assembly Interactivity modes")]),t("li",null,[t("a",{href:"https://docs.servicestack.net/physical-project-structure"},"Organized Project Structure"),e(" - Divided into AppHost, Service Interface, Service Model, and Tests projects to promote separation of concerns and maintainability.")])],-1),Z="New .NET 8 Blazor Tailwind Template",J="The new Blazor for .NET 8 template streamlines web UI development in C#.",K=["dotnet","blazor","templates"],X="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000",tt="Lucy Bates",et=[{property:"og:title",content:"New .NET 8 Blazor Tailwind Template"},{name:"twitter:title",content:"New .NET 8 Blazor Tailwind Template"},{property:"og:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}],at={__name:"2023-11-20_net8-blazor-template",setup(r,{expose:o}){const a={title:"New .NET 8 Blazor Tailwind Template",summary:"The new Blazor for .NET 8 template streamlines web UI development in C#.",tags:["dotnet","blazor","templates"],image:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000",author:"Lucy Bates",meta:[{property:"og:title",content:"New .NET 8 Blazor Tailwind Template"},{name:"twitter:title",content:"New .NET 8 Blazor Tailwind Template"},{property:"og:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]};return o({frontmatter:a}),u({title:"New .NET 8 Blazor Tailwind Template",meta:[{property:"og:title",content:"New .NET 8 Blazor Tailwind Template"},{name:"twitter:title",content:"New .NET 8 Blazor Tailwind Template"},{property:"og:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]}),(W,F)=>{const l=m("LiteYouTube"),c=p;return n(),s(c,{frontmatter:a},{default:f(()=>[t("div",b,[v,_,T,x,t("div",z,[k,t("div",S,[i(l,{id:"hqyozHSL0Nk",title:".NET 8 Blazor Tailwind Template"})])]),t("div",A,[B,i(y)]),I,N,C,E,D,U,P,j,R,H,L,M,q,O,Q])]),_:1})}}};export{tt as author,at as default,X as image,et as meta,J as summary,K as tags,Z as title}; diff --git a/assets/2023-11-22_net8-best-blazor-wjwjFuPp.js b/assets/2023-11-22_net8-best-blazor-B8AK7TtK.js similarity index 99% rename from assets/2023-11-22_net8-best-blazor-wjwjFuPp.js rename to assets/2023-11-22_net8-best-blazor-B8AK7TtK.js index 5aeb672..d7d95e8 100644 --- a/assets/2023-11-22_net8-best-blazor-wjwjFuPp.js +++ b/assets/2023-11-22_net8-best-blazor-B8AK7TtK.js @@ -1,4 +1,4 @@ -import{_ as u}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{d as r,o as c,h as l,u as k,i as d,r as h,w as m,a as t,b as a,e as n}from"./index-B-kKBcPB.js";import{_ as g}from"./Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js";import{_ as f,I as w}from"./Templates.vue_vue_type_script_setup_true_lang-DajVBfQg.js";const b=r({__name:"BlazorVueTemplate",setup(p){return(e,s)=>(c(),l(f,{templates:[k(w)["blazor-vue"]]},null,8,["templates"]))}}),v={class:"markdown-body"},y=t("p",null,[n("The best way to find out what’s new in .NET 8 Blazor is to watch the excellent "),t("a",{href:"https://www.youtube.com/watch?v=QD2-DwuOfKM"},"Full stack web UI with Blazor in .NET 8"),n(" presentation by Daniel Roth and Steve Sanderson, which covers how Blazor has become a Full Stack UI Web Technology for developing any kind of .NET Web App.")],-1),_=t("h2",null,"Your first .NET 8 Blazor App",-1),z=t("p",null,"You don’t get to appreciate what this means until you create your first .NET 8 Blazor App where you’ll be pleasantly surprised that Blazor Apps render fast, clean HTML without needing to load large Web Assembly assets needed for Blazor WebAssembly Apps or starting a stateful Web Socket connection required for Blazor Server Interactive Apps.",-1),B=t("p",null,[n("This is because the "),t("strong",null,"default rendering mode"),n(" for Blazor uses neither of these technologies, instead it returns to traditional Web App development where Blazor Pages now return clean, glorious HTML - courtesy of Blazor’s "),t("a",{href:"https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes"},"Static render mode"),n(".")],-1),x=t("p",null,[t("a",{href:"https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes"},[t("img",{src:"https://servicestack.net/img/posts/net8-best-blazor/blazor-ssr.png",alt:""})])],-1),C=t("h2",null,"Choose your compromise",-1),A=t("p",null,"Previously we were forced to choose upfront whether we wanted to build a Blazor Web Assembly App or a Blazor Server App and the compromises that came with them, which for public Internet Web Apps wasn’t even a choice as Blazor Server Apps perform poorly over high latency Internet connections.",-1),S=t("p",null,[n("This meant choosing Blazor Web Assembly Apps which required downloading a large Web Assembly runtime with users experiencing a long delay before the App was functional. To minimize this impact our Blazor WebAssembly Tailwind template included "),t("a",{href:"https://blazor-tailwind.jamstacks.net/docs/prerender"},"built-in prerendering"),n(" where as part of deployment would generate "),t("strong",null,"static .html pages"),n(" that were deployed with the Blazor Web Assembly front-end UI that can be hosted on CDN edge networks to further improve load times.")],-1),T=t("p",null,"Whilst this meant the App’s UI would be rendered immediately, it still wouldn’t be functional until the Web Assembly runtime was downloaded and initialized, which would flicker as the static UI was replaced with Blazor’s WASM rendered UI, then later Authenticated users would experience further delay and UI jank whilst the App signs in the Authenticated User. Whilst prerendering is an improvement over Blazor WASM’s default blank loading screen, it’s still not ideal for public facing Web Apps.",-1),q=t("h2",null,".NET 8 Blazor is a Game Changer",-1),I=t("p",null,[n("The situation has greatly improved in .NET 8 where your entire App no longer needs to be bound to a single Interactivity mode. Even better, Blazor’s default "),t("strong",null,"static rendering"),n(" mode results in the best UX where the Website Layout and important landing pages can be rendered instantly.")],-1),E=t("h3",null,"Interactive only when you need it",-1),W=t("p",null,[n("Only pages that need Blazor’s interactivity features can opt-in to whichever Blazor interactive rendering mode makes the most sense, either on a page-by-page or component basis, or by choosing "),t("code",null,"RenderMode.InteractiveAuto"),n(" which uses "),t("strong",null,"InteractiveWebAssembly"),n(" if the WASM runtime is loaded or "),t("strong",null,"InteractiveServer"),n(" if it isn’t.")],-1),j=t("h3",null,"Enhanced Navigation FTW",-1),M=t("p",null,[n("Ultimately I expect Blazor’s new "),t("strong",null,"Enhanced Navigation"),n(" is likely the feature that will deliver the biggest UX improvement users will experience given it’s enabled by default and gives traditional statically rendered Web Apps instant SPA-like navigation responsiveness where new pages are swapped in without needing to perform expensive full page reloads.")],-1),N=t("p",null,"It’s beauty lies in being able to do this as a mostly transparent detail without the traditional SPA complexity of needing to manage complex state or client-side routing. It’s a smart implementation that’s able to perform fine-grained DOM updates to only parts of pages that have changed, providing the ultimate UX of preserving page state, like populated form fields and scroll position, to deliver a fast and responsive UX that previously wasn’t attainable from the simplicity of a Server Rendered App.",-1),D=t("p",null,"Its implementation does pose some challenges in implementing certain features, but we’ll cover some approaches below we’ve used to overcome them below.",-1),L=t("h3",null,"Full Stack Web UI",-1),V=t("p",null,"Blazor’s static rendering with enhanced navigation and its opt-in flexibility makes .NET 8 Blazor a game changer, expanding it from a very niche set of use-cases that weren’t too adversely affected by its Interactivity mode downsides, to becoming a viable solution for developing any kind of .NET Web App, especially as it can also be utilized within existing ASP.NET MVC and Razor Pages Apps.",-1),P=t("h3",null,"Benefits over MVC and Razor Pages",-1),U=t("p",null,[n("In addition, Blazor’s superior component model allows building better encapsulated, more reusable and easier-to-use UI components which has enabled Blazor’s rich 3rd Party library ecosystem to flourish, that we ourselves utilize to develop the high productivity Tailwind Components in the "),t("a",{href:"https://blazor-gallery.servicestack.net"},"ServiceStack.Blazor"),n(" component library.")],-1),J=t("p",null,"So far there’s only upsides for .NET Web App development, the compromises only kick in when you need Blazor’s interactivity features, luckily these can now be scoped to just the Pages and Components that need them. But how often do we need them?",-1),O=t("h3",null,"When do you need Blazor’s Interactivity features?",-1),R=t("p",null,"It ultimately depends on what App your building, but a lot of Websites can happily display dynamic content, navigate quickly with enhanced navigation, fill out and submit forms - all in Blazor’s default static rendering mode.",-1),F=t("p",null,[n("Not even advanced features like "),t("strong",null,"Streaming Rendering"),n(" used in Blazor Template’s "),t("a",{href:"https://github.com/dotnet/aspnetcore/blob/v8.0.0-rc.2.23480.2/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Pages/Weather.razor"},"Weather.razor"),n(" page require interactivity, as its progressive rendered UI updates are achieved in a single request without interactivity.")],-1),H=t("p",null,[n("In fact the only time "),t("code",null,"@rendermode InteractiveServer"),n(" is needed in the default Blazor template is in the "),t("a",{href:"https://github.com/dotnet/aspnetcore/blob/v8.0.0-rc.2.23480.2/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Pages/Counter.razor#L3"},"Counter.razor"),n(" page whose C# Event Handling require it.")],-1),G=t("p",null,"Ultimately some form of Interactivity is going to be required in order to add behavior or client-side functionality that runs after pages have been rendered, but you still have some options left before being forced to opt into an Interactive Blazor solution.",-1),Y=t("h3",null,"Interactive Feature Options",-1),$=t("p",null,[n("We can see some of these options utilized in the Blazor Template "),t("a",{href:"https://github.com/dotnet/aspnetcore/blob/v8.0.0-rc.2.23480.2/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout/NavMenu.razor"},"NavMenu.razor"),n(" component which uses JavaScript "),t("code",null,"onclick"),n(" event handlers to add client-side behavior to simulate mouse clicks to toggle UI elements:")],-1),Q=t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),n("div")]),n(),t("span",{class:"token attr-name"},"class"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("nav-scrollable"),t("span",{class:"token punctuation"},'"')]),n(),t("span",{class:"token special-attr"},[t("span",{class:"token attr-name"},"onclick"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),t("span",{class:"token value javascript language-javascript"},[n("document"),t("span",{class:"token punctuation"},"."),t("span",{class:"token function"},"querySelector"),t("span",{class:"token punctuation"},"("),t("span",{class:"token string"},"'.navbar-toggler'"),t("span",{class:"token punctuation"},")"),t("span",{class:"token punctuation"},"."),t("span",{class:"token function"},"click"),t("span",{class:"token punctuation"},"("),t("span",{class:"token punctuation"},")")]),t("span",{class:"token punctuation"},'"')])]),t("span",{class:"token punctuation"},">")]),n(` +import{_ as u}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{d as r,o as c,h as l,u as k,i as d,r as h,w as m,a as t,b as a,e as n}from"./index-CoFPLbfm.js";import{_ as g}from"./Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js";import{_ as f,I as w}from"./Templates.vue_vue_type_script_setup_true_lang-8Ivl7FzK.js";const b=r({__name:"BlazorVueTemplate",setup(p){return(e,s)=>(c(),l(f,{templates:[k(w)["blazor-vue"]]},null,8,["templates"]))}}),v={class:"markdown-body"},y=t("p",null,[n("The best way to find out what’s new in .NET 8 Blazor is to watch the excellent "),t("a",{href:"https://www.youtube.com/watch?v=QD2-DwuOfKM"},"Full stack web UI with Blazor in .NET 8"),n(" presentation by Daniel Roth and Steve Sanderson, which covers how Blazor has become a Full Stack UI Web Technology for developing any kind of .NET Web App.")],-1),_=t("h2",null,"Your first .NET 8 Blazor App",-1),z=t("p",null,"You don’t get to appreciate what this means until you create your first .NET 8 Blazor App where you’ll be pleasantly surprised that Blazor Apps render fast, clean HTML without needing to load large Web Assembly assets needed for Blazor WebAssembly Apps or starting a stateful Web Socket connection required for Blazor Server Interactive Apps.",-1),B=t("p",null,[n("This is because the "),t("strong",null,"default rendering mode"),n(" for Blazor uses neither of these technologies, instead it returns to traditional Web App development where Blazor Pages now return clean, glorious HTML - courtesy of Blazor’s "),t("a",{href:"https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes"},"Static render mode"),n(".")],-1),x=t("p",null,[t("a",{href:"https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes"},[t("img",{src:"https://servicestack.net/img/posts/net8-best-blazor/blazor-ssr.png",alt:""})])],-1),C=t("h2",null,"Choose your compromise",-1),A=t("p",null,"Previously we were forced to choose upfront whether we wanted to build a Blazor Web Assembly App or a Blazor Server App and the compromises that came with them, which for public Internet Web Apps wasn’t even a choice as Blazor Server Apps perform poorly over high latency Internet connections.",-1),S=t("p",null,[n("This meant choosing Blazor Web Assembly Apps which required downloading a large Web Assembly runtime with users experiencing a long delay before the App was functional. To minimize this impact our Blazor WebAssembly Tailwind template included "),t("a",{href:"https://blazor-tailwind.jamstacks.net/docs/prerender"},"built-in prerendering"),n(" where as part of deployment would generate "),t("strong",null,"static .html pages"),n(" that were deployed with the Blazor Web Assembly front-end UI that can be hosted on CDN edge networks to further improve load times.")],-1),T=t("p",null,"Whilst this meant the App’s UI would be rendered immediately, it still wouldn’t be functional until the Web Assembly runtime was downloaded and initialized, which would flicker as the static UI was replaced with Blazor’s WASM rendered UI, then later Authenticated users would experience further delay and UI jank whilst the App signs in the Authenticated User. Whilst prerendering is an improvement over Blazor WASM’s default blank loading screen, it’s still not ideal for public facing Web Apps.",-1),q=t("h2",null,".NET 8 Blazor is a Game Changer",-1),I=t("p",null,[n("The situation has greatly improved in .NET 8 where your entire App no longer needs to be bound to a single Interactivity mode. Even better, Blazor’s default "),t("strong",null,"static rendering"),n(" mode results in the best UX where the Website Layout and important landing pages can be rendered instantly.")],-1),E=t("h3",null,"Interactive only when you need it",-1),W=t("p",null,[n("Only pages that need Blazor’s interactivity features can opt-in to whichever Blazor interactive rendering mode makes the most sense, either on a page-by-page or component basis, or by choosing "),t("code",null,"RenderMode.InteractiveAuto"),n(" which uses "),t("strong",null,"InteractiveWebAssembly"),n(" if the WASM runtime is loaded or "),t("strong",null,"InteractiveServer"),n(" if it isn’t.")],-1),j=t("h3",null,"Enhanced Navigation FTW",-1),M=t("p",null,[n("Ultimately I expect Blazor’s new "),t("strong",null,"Enhanced Navigation"),n(" is likely the feature that will deliver the biggest UX improvement users will experience given it’s enabled by default and gives traditional statically rendered Web Apps instant SPA-like navigation responsiveness where new pages are swapped in without needing to perform expensive full page reloads.")],-1),N=t("p",null,"It’s beauty lies in being able to do this as a mostly transparent detail without the traditional SPA complexity of needing to manage complex state or client-side routing. It’s a smart implementation that’s able to perform fine-grained DOM updates to only parts of pages that have changed, providing the ultimate UX of preserving page state, like populated form fields and scroll position, to deliver a fast and responsive UX that previously wasn’t attainable from the simplicity of a Server Rendered App.",-1),D=t("p",null,"Its implementation does pose some challenges in implementing certain features, but we’ll cover some approaches below we’ve used to overcome them below.",-1),L=t("h3",null,"Full Stack Web UI",-1),V=t("p",null,"Blazor’s static rendering with enhanced navigation and its opt-in flexibility makes .NET 8 Blazor a game changer, expanding it from a very niche set of use-cases that weren’t too adversely affected by its Interactivity mode downsides, to becoming a viable solution for developing any kind of .NET Web App, especially as it can also be utilized within existing ASP.NET MVC and Razor Pages Apps.",-1),P=t("h3",null,"Benefits over MVC and Razor Pages",-1),U=t("p",null,[n("In addition, Blazor’s superior component model allows building better encapsulated, more reusable and easier-to-use UI components which has enabled Blazor’s rich 3rd Party library ecosystem to flourish, that we ourselves utilize to develop the high productivity Tailwind Components in the "),t("a",{href:"https://blazor-gallery.servicestack.net"},"ServiceStack.Blazor"),n(" component library.")],-1),J=t("p",null,"So far there’s only upsides for .NET Web App development, the compromises only kick in when you need Blazor’s interactivity features, luckily these can now be scoped to just the Pages and Components that need them. But how often do we need them?",-1),O=t("h3",null,"When do you need Blazor’s Interactivity features?",-1),R=t("p",null,"It ultimately depends on what App your building, but a lot of Websites can happily display dynamic content, navigate quickly with enhanced navigation, fill out and submit forms - all in Blazor’s default static rendering mode.",-1),F=t("p",null,[n("Not even advanced features like "),t("strong",null,"Streaming Rendering"),n(" used in Blazor Template’s "),t("a",{href:"https://github.com/dotnet/aspnetcore/blob/v8.0.0-rc.2.23480.2/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Pages/Weather.razor"},"Weather.razor"),n(" page require interactivity, as its progressive rendered UI updates are achieved in a single request without interactivity.")],-1),H=t("p",null,[n("In fact the only time "),t("code",null,"@rendermode InteractiveServer"),n(" is needed in the default Blazor template is in the "),t("a",{href:"https://github.com/dotnet/aspnetcore/blob/v8.0.0-rc.2.23480.2/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Pages/Counter.razor#L3"},"Counter.razor"),n(" page whose C# Event Handling require it.")],-1),G=t("p",null,"Ultimately some form of Interactivity is going to be required in order to add behavior or client-side functionality that runs after pages have been rendered, but you still have some options left before being forced to opt into an Interactive Blazor solution.",-1),Y=t("h3",null,"Interactive Feature Options",-1),$=t("p",null,[n("We can see some of these options utilized in the Blazor Template "),t("a",{href:"https://github.com/dotnet/aspnetcore/blob/v8.0.0-rc.2.23480.2/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout/NavMenu.razor"},"NavMenu.razor"),n(" component which uses JavaScript "),t("code",null,"onclick"),n(" event handlers to add client-side behavior to simulate mouse clicks to toggle UI elements:")],-1),Q=t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),n("div")]),n(),t("span",{class:"token attr-name"},"class"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("nav-scrollable"),t("span",{class:"token punctuation"},'"')]),n(),t("span",{class:"token special-attr"},[t("span",{class:"token attr-name"},"onclick"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),t("span",{class:"token value javascript language-javascript"},[n("document"),t("span",{class:"token punctuation"},"."),t("span",{class:"token function"},"querySelector"),t("span",{class:"token punctuation"},"("),t("span",{class:"token string"},"'.navbar-toggler'"),t("span",{class:"token punctuation"},")"),t("span",{class:"token punctuation"},"."),t("span",{class:"token function"},"click"),t("span",{class:"token punctuation"},"("),t("span",{class:"token punctuation"},")")]),t("span",{class:"token punctuation"},'"')])]),t("span",{class:"token punctuation"},">")]),n(` `)])],-1),X=t("p",null,"and submitting forms to Logout users:",-1),Z=t("pre",{class:"language-html"},[t("code",{class:"language-html"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),n("LogoutForm")]),n(),t("span",{class:"token attr-name"},"id"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("logout-form"),t("span",{class:"token punctuation"},'"')]),n(),t("span",{class:"token punctuation"},"/>")]),n(` `),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),n("NavLink")]),n(),t("span",{class:"token attr-name"},"class"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("nav-link"),t("span",{class:"token punctuation"},'"')]),n(),t("span",{class:"token special-attr"},[t("span",{class:"token attr-name"},"onclick"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),t("span",{class:"token value javascript language-javascript"},[n("document"),t("span",{class:"token punctuation"},"."),t("span",{class:"token function"},"getElementById"),t("span",{class:"token punctuation"},"("),t("span",{class:"token string"},"'logout-form'"),t("span",{class:"token punctuation"},")"),t("span",{class:"token punctuation"},"."),t("span",{class:"token function"},"submit"),t("span",{class:"token punctuation"},"("),t("span",{class:"token punctuation"},")"),t("span",{class:"token punctuation"},";"),n(),t("span",{class:"token keyword"},"return"),n(),t("span",{class:"token boolean"},"false"),t("span",{class:"token punctuation"},";")]),t("span",{class:"token punctuation"},'"')])]),t("span",{class:"token punctuation"},">")]),n(` `),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),n("span")]),n(),t("span",{class:"token attr-name"},"class"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("bi bi-arrow-bar-left"),t("span",{class:"token punctuation"},'"')]),n(),t("span",{class:"token attr-name"},"aria-hidden"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),n("true"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),n(` Logout diff --git a/assets/2024-02-28_markdown-components-in-vue-BMrj5Q1x.js b/assets/2024-02-28_markdown-components-in-vue-OgPNuM_j.js similarity index 98% rename from assets/2024-02-28_markdown-components-in-vue-BMrj5Q1x.js rename to assets/2024-02-28_markdown-components-in-vue-OgPNuM_j.js index 433cc9e..debc51b 100644 --- a/assets/2024-02-28_markdown-components-in-vue-BMrj5Q1x.js +++ b/assets/2024-02-28_markdown-components-in-vue-OgPNuM_j.js @@ -1,4 +1,4 @@ -import{_ as l}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{_ as u}from"./GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js";import{i,r as k,o as r,h as g,w as m,a as n,b as a,u as d,e as s}from"./index-B-kKBcPB.js";import{_ as h,a as f,b as y}from"./HelloApi.vue_vue_type_script_setup_true_lang-BNRlbX2m.js";import{_ as v}from"./Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js";import{C as w}from"./ChartJs-I6khMjFE.js";const _={class:"markdown-body"},b=n("h2",null,"Vue Components in Markdown Pages",-1),x=n("p",null,[s("Thanks to the "),n("a",{href:"https://github.com/unplugin/unplugin-auto-import"},"unplugin-auto-import"),s(" plugin, App Components in "),n("a",{href:"https://github.com/ServiceStack/press-vue/tree/main/src/components"},"/src/components"),s(" are automatically imported and can immediately referenced in "),n("code",null,"*.md"),s(" Markdown pages using normal Vue SFC syntax, e.g:")],-1),C=n("pre",{class:"language-tsx"},[n("code",{class:"language-tsx"},[n("span",{class:"token tag"},[n("span",{class:"token tag"},[n("span",{class:"token punctuation"},"<"),n("span",{class:"token class-name"},"GettingStarted")]),s(),n("span",{class:"token attr-name"},"template"),n("span",{class:"token attr-value"},[n("span",{class:"token punctuation attr-equals"},"="),n("span",{class:"token punctuation"},'"'),s("press-vue"),n("span",{class:"token punctuation"},'"')]),s(),n("span",{class:"token punctuation"},"/>")]),s(` +import{_ as l}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{_ as u}from"./GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js";import{i,r as k,o as r,h as g,w as m,a as n,b as a,u as d,e as s}from"./index-CoFPLbfm.js";import{_ as h,a as f,b as y}from"./HelloApi.vue_vue_type_script_setup_true_lang-DrkDEcx3.js";import{_ as v}from"./Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js";import{C as w}from"./ChartJs-ljXEK9mH.js";const _={class:"markdown-body"},b=n("h2",null,"Vue Components in Markdown Pages",-1),x=n("p",null,[s("Thanks to the "),n("a",{href:"https://github.com/unplugin/unplugin-auto-import"},"unplugin-auto-import"),s(" plugin, App Components in "),n("a",{href:"https://github.com/ServiceStack/press-vue/tree/main/src/components"},"/src/components"),s(" are automatically imported and can immediately referenced in "),n("code",null,"*.md"),s(" Markdown pages using normal Vue SFC syntax, e.g:")],-1),C=n("pre",{class:"language-tsx"},[n("code",{class:"language-tsx"},[n("span",{class:"token tag"},[n("span",{class:"token tag"},[n("span",{class:"token punctuation"},"<"),n("span",{class:"token class-name"},"GettingStarted")]),s(),n("span",{class:"token attr-name"},"template"),n("span",{class:"token attr-value"},[n("span",{class:"token punctuation attr-equals"},"="),n("span",{class:"token punctuation"},'"'),s("press-vue"),n("span",{class:"token punctuation"},'"')]),s(),n("span",{class:"token punctuation"},"/>")]),s(` `)])],-1),S={class:"py-20 not-prose flex justify-center"},V=n("p",null,[s("Additional Global Components can be registered in "),n("a",{href:"https://github.com/ServiceStack/press-vue/blob/main/src/main.ts"},"main.ts"),s(" when creating the Vue App where you can register entire Component libraries, Aliases and TypeScript Vue components, e.g")],-1),M=n("pre",{class:"language-ts"},[n("code",{class:"language-ts"},[n("span",{class:"token keyword"},"import"),s(" ServiceStackVue "),n("span",{class:"token keyword"},"from"),s(),n("span",{class:"token string"},'"@servicestack/vue"'),s(` `),n("span",{class:"token keyword"},"import"),s(),n("span",{class:"token punctuation"},"{"),s(" Icon "),n("span",{class:"token punctuation"},"}"),s(),n("span",{class:"token keyword"},"from"),s(),n("span",{class:"token string"},"'@iconify/vue'"),s(` `),n("span",{class:"token keyword"},"import"),s(" LiteYouTube "),n("span",{class:"token keyword"},"from"),s(),n("span",{class:"token string"},'"@/components/LiteYouTube"'),s(` diff --git a/assets/2024-03-01_vite-press-plugin-BV6PDf7d.js b/assets/2024-03-01_vite-press-plugin-DJwsPj6t.js similarity index 63% rename from assets/2024-03-01_vite-press-plugin-BV6PDf7d.js rename to assets/2024-03-01_vite-press-plugin-DJwsPj6t.js index 5e8c519..1d9d54b 100644 --- a/assets/2024-03-01_vite-press-plugin-BV6PDf7d.js +++ b/assets/2024-03-01_vite-press-plugin-DJwsPj6t.js @@ -1,12 +1,12 @@ -import{_ as P}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{d as V,r as T,o as s,c as o,F as b,g as _,h as g,a as t,t as x,n as C,u as A,i as j,w as B,b as i,e,_ as N}from"./index-B-kKBcPB.js";const S={key:0},I={key:1},R={key:0},z={class:"mr-1 text-slate-600","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},D=t("path",{d:"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"},null,-1),L=[D],F={key:1},U={class:"ml-6"},$={class:"flex items-center text-base leading-8"},W=t("path",{d:"M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1l-3.2 3.2c-.2.2-.4.3-.6.3Z"},null,-1),E=[W],O={class:"mr-1 text-sky-500","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},q=t("path",{d:"M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.55 0 1.07.26 1.4.7l.9 1.2a.25.25 0 0 0 .2.1H13a1 1 0 0 1 1 1v.5H2.75a.75.75 0 0 0 0 1.5h11.978a1 1 0 0 1 .994 1.117L15 13.25A1.75 1.75 0 0 1 13.25 15H1.75A1.75 1.75 0 0 1 0 13.25V2.75c0-.464.184-.91.513-1.237Z"},null,-1),Y=[q],G=V({__name:"FileLayout",props:{files:{},label:{},contents:{}},setup(m){return(n,c)=>{const p=T("FileLayout",!0);return n.files?(s(),o("div",S,[(s(!0),o(b,null,_(n.files,(l,r)=>(s(),g(p,{key:r,label:r,contents:l},null,8,["label","contents"]))),128))])):(s(),o("div",I,[n.label=="_"?(s(),o("div",R,[(s(!0),o(b,null,_(n.contents,l=>(s(),o("div",{key:l,class:"ml-6 flex items-center text-base leading-8"},[(s(),o("svg",z,L)),t("span",null,x(l),1)]))),128))])):(s(),o("div",F,[t("div",U,[t("div",$,[(s(),o("svg",{class:C(["mr-1 text-slate-600",Object.keys(n.contents).length==0?"-rotate-90":""]),"aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 12 12",width:"12",height:"12",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},E,2)),(s(),o("svg",O,Y)),t("span",null,x(n.label),1)]),(s(!0),o(b,null,_(n.contents,(l,r)=>(s(),g(p,{key:r,label:r,contents:l},null,8,["label","contents"]))),128))])]))]))}}}),H=V({__name:"Files",props:{body:{}},setup(m){var r;const n=m;function c(a){const d=a.split(` -`),h={_:[]},u=[h];for(const f of d){const w=f.search(/\S/)/2,k=f.trim(),y=u[w];if(k.includes("."))y._.push(k);else{const v={_:[]},M=k.substring(1);y[M]=v,u.length=w+1,u.push(v)}}return h}const p=((r=n.body)==null?void 0:r.trim())||"",l=c(p);return(a,d)=>(s(),g(G,{files:A(l)},null,8,["files"]))}}),Z={class:"markdown-body"},X=t("p",null,[e("The Vite Press Plugin is an alternative to "),t("a",{href:"https://vitepress.dev"},"VitePress"),e(" for adding Markdown features to existing Vite Vue or React projects. It’s a non-intrusive plugin for Vue and React Vite apps that want to add markdown powered content features without needing to adopt an opinionated framework for their entire App.")],-1),K=t("h2",null,"Universal Markdown Features",-1),J=t("p",null,[e("A goal for "),t("strong",null,"vite-press-plugin"),e(" is to implement a suite of universal markdown-powered features that can be reused across all our Vue, React and .NET Razor and Blazor project templates, allowing you to freely copy and incorporate same set of markdown feature folders to power markdown content features across a range of websites built with different technologies.")],-1),Q=t("h3",null,"Vite Apps with vite-press-plugin",-1),tt=t("p",null,[e("The "),t("strong",null,"vite-press-plugin"),e(" currently powers the markdown features in the following Vite Vue and React templates:")],-1),et=t("h4",null,"Vite Templates with vite-press-plugin",-1),st=t("ul",null,[t("li",null,[t("a",{href:"https://press-vue.web-templates.io"},"press-vue"),e(" - Vite Vue App")]),t("li",null,[t("a",{href:"https://press-react.web-templates.io"},"press-react"),e(" - Vite React App")])],-1),nt=t("div",{class:"not-prose mt-8 grid grid-cols-2 gap-4"},[t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://press-vue.servicestack.net"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/press-vue.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"press-vue.servicestack.net")]),t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://press-react.servicestack.net"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/press-react.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"press-react.servicestack.net")])],-1),ot=t("h4",null,".NET 8 API backend with Vite Vue & React SPA frontend",-1),at=t("ul",null,[t("li",null,[t("a",{href:"https://vue-spa.web-templates.io"},"vue-spa"),e(" - .NET 8 API with Vite Vue SPA frontend")]),t("li",null,[t("a",{href:"https://react-spa.web-templates.io"},"react-spa"),e(" - .NET 8 API with Vite React SPA frontend")])],-1),lt=t("div",{class:"not-prose mt-8 grid grid-cols-2 gap-4"},[t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://vue-spa.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/vue-spa.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"vue-spa.web-templates.io")]),t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://react-spa.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/react-spa.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"react-spa.web-templates.io")])],-1),rt=t("p",null,[e("The "),t("strong",null,"vite-press-plugin"),e(" makes the Markdown features available to the Vite App, whilst the markdown rendering itself is optimally implemented in:")],-1),it=t("ul",null,[t("li",null,[e("Vue Templates - with "),t("a",{href:"https://github.com/markdown-it/markdown-it"},"markdown-it"),e(" in "),t("a",{href:"https://vuejs.org/guide/scaling-up/sfc.html"},"Vue SFC"),e(" Components")]),t("li",null,[e("React Templates - with "),t("a",{href:"https://github.com/remarkjs/remark"},"remark"),e(" and "),t("a",{href:"https://mdxjs.com"},"MDX"),e(" in "),t("a",{href:"https://react.dev"},"React"),e(" Components")])],-1),ct=t("h3",null,".NET Templates with C# and Markdig",-1),pt=t("p",null,[e("Whilst the same Markdown feature folders are "),t("a",{href:"https://razor-ssg.web-templates.io/posts/razor-ssg"},"implemented in C#"),e(" and rendered with "),t("a",{href:"https://github.com/xoofx/markdig"},"Markdig"),e(" and either Razor Pages or Blazor Components:")],-1),ut=t("h4",null,".NET 8 Razor SSG and Blazor SSR Templates",-1),dt=t("ul",null,[t("li",null,[t("a",{href:"https://razor-ssg.web-templates.io"},"razor-ssg"),e(" - .NET Razor SSG Blog and Marketing Website with "),t("strong",null,"Markdig")]),t("li",null,[t("a",{href:"https://blazor-vue.web-templates.io"},"blazor-vue"),e(" - .NET 8 Blazor Server Rendered Website with "),t("strong",null,"Markdig")]),t("li",null,[t("a",{href:"https://razor-press.web-templates.io"},"razor-press"),e(" - .NET Razor SSG Documentation Website with "),t("strong",null,"Markdig")])],-1),ht=t("div",{class:"not-prose mt-8 grid grid-cols-2 gap-4"},[t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://razor-ssg.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/razor-ssg.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"razor-ssg.web-templates.io")]),t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://blazor-vue.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/blazor-vue.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"blazor-vue.web-templates.io")])],-1),gt=t("h3",null,"Markdown Feature Folders",-1),mt=t("p",null,[e("The content for each Markdown feature is maintained within its own feature folder with a "),t("code",null,"_"),e(" prefix:")],-1),kt=t("h4",null,"Markdown Document Structure",-1),bt=t("p",null,"Additional metadata for each markdown page is maintained in the frontmatter of each markdown page, e.g. the front matter for this blog post contains:",-1),_t=t("pre",{class:"language-md"},[t("code",{class:"language-md"},[t("span",{class:"token front-matter-block"},[t("span",{class:"token punctuation"},"---"),e(` +import{_ as C}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{d as T,r as M,o as s,c as o,F as _,g as f,h,a as t,t as V,n as A,u as j,i as B,w as N,b as i,e,_ as S}from"./index-CoFPLbfm.js";const I={key:0},R={key:1},z={key:0},D={class:"mr-1 text-slate-600","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},L=t("path",{d:"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"},null,-1),F=[L],U={key:1},$={class:"ml-6"},W={class:"flex items-center text-base leading-8"},E=t("path",{d:"M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1l-3.2 3.2c-.2.2-.4.3-.6.3Z"},null,-1),O=[E],q={class:"mr-1 text-sky-500","aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 16 16",width:"16",height:"16",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},Y=t("path",{d:"M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.55 0 1.07.26 1.4.7l.9 1.2a.25.25 0 0 0 .2.1H13a1 1 0 0 1 1 1v.5H2.75a.75.75 0 0 0 0 1.5h11.978a1 1 0 0 1 .994 1.117L15 13.25A1.75 1.75 0 0 1 13.25 15H1.75A1.75 1.75 0 0 1 0 13.25V2.75c0-.464.184-.91.513-1.237Z"},null,-1),G=[Y],H=T({__name:"FileLayout",props:{files:{},label:{},contents:{}},setup(g){return(n,c)=>{const p=M("FileLayout",!0);return n.files?(s(),o("div",I,[(s(!0),o(_,null,f(n.files,(l,r)=>(s(),h(p,{key:r,label:r,contents:l},null,8,["label","contents"]))),128))])):(s(),o("div",R,[n.label=="_"?(s(),o("div",z,[(s(!0),o(_,null,f(n.contents,l=>(s(),o("div",{key:l,class:"ml-6 flex items-center text-base leading-8"},[(s(),o("svg",D,F)),t("span",null,V(l),1)]))),128))])):(s(),o("div",U,[t("div",$,[t("div",W,[(s(),o("svg",{class:A(["mr-1 text-slate-600",Object.keys(n.contents).length==0?"-rotate-90":""]),"aria-hidden":"true",focusable:"false",role:"img",viewBox:"0 0 12 12",width:"12",height:"12",fill:"currentColor",style:{display:"inline-block","user-select":"none","vertical-align":"text-bottom",overflow:"visible"}},O,2)),(s(),o("svg",q,G)),t("span",null,V(n.label),1)]),(s(!0),o(_,null,f(n.contents,(l,r)=>(s(),h(p,{key:r,label:r,contents:l},null,8,["label","contents"]))),128))])]))]))}}}),Z=T({__name:"Files",props:{body:{}},setup(g){var r;const n=g;function c(a,u=2){const m=a.split(` +`),d={_:[]},k=[d];for(const w of m){const y=w.search(/\S/)/u,b=w.trim(),v=k[y];if(b.includes("."))v._.push(b);else{const x={_:[]},P=b.substring(1);v[P]=x,k.length=y+1,k.push(x)}}return d}const p=((r=n.body)==null?void 0:r.trim())||"",l=c(p);return(a,u)=>(s(),h(H,{files:j(l)},null,8,["files"]))}}),X={class:"markdown-body"},K=t("p",null,[e("The Vite Press Plugin is an alternative to "),t("a",{href:"https://vitepress.dev"},"VitePress"),e(" for adding Markdown features to existing Vite Vue or React projects. It’s a non-intrusive plugin for Vue and React Vite apps that want to add markdown powered content features without needing to adopt an opinionated framework for their entire App.")],-1),J=t("h2",null,"Universal Markdown Features",-1),Q=t("p",null,[e("A goal for "),t("strong",null,"vite-press-plugin"),e(" is to implement a suite of universal markdown-powered features that can be reused across all our Vue, React and .NET Razor and Blazor project templates, allowing you to freely copy and incorporate same set of markdown feature folders to power markdown content features across a range of websites built with different technologies.")],-1),tt=t("h3",null,"Vite Apps with vite-press-plugin",-1),et=t("p",null,[e("The "),t("strong",null,"vite-press-plugin"),e(" currently powers the markdown features in the following Vite Vue and React templates:")],-1),st=t("h4",null,"Vite Templates with vite-press-plugin",-1),nt=t("ul",null,[t("li",null,[t("a",{href:"https://press-vue.web-templates.io"},"press-vue"),e(" - Vite Vue App")]),t("li",null,[t("a",{href:"https://press-react.web-templates.io"},"press-react"),e(" - Vite React App")])],-1),ot=t("div",{class:"not-prose mt-8 grid grid-cols-2 gap-4"},[t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://press-vue.servicestack.net"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/press-vue.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"press-vue.servicestack.net")]),t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://press-react.servicestack.net"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/press-react.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"press-react.servicestack.net")])],-1),at=t("h4",null,".NET 8 API backend with Vite Vue & React SPA frontend",-1),lt=t("ul",null,[t("li",null,[t("a",{href:"https://vue-spa.web-templates.io"},"vue-spa"),e(" - .NET 8 API with Vite Vue SPA frontend")]),t("li",null,[t("a",{href:"https://react-spa.web-templates.io"},"react-spa"),e(" - .NET 8 API with Vite React SPA frontend")])],-1),rt=t("div",{class:"not-prose mt-8 grid grid-cols-2 gap-4"},[t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://vue-spa.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/vue-spa.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"vue-spa.web-templates.io")]),t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://react-spa.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/react-spa.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"react-spa.web-templates.io")])],-1),it=t("p",null,[e("The "),t("strong",null,"vite-press-plugin"),e(" makes the Markdown features available to the Vite App, whilst the markdown rendering itself is optimally implemented in:")],-1),ct=t("ul",null,[t("li",null,[e("Vue Templates - with "),t("a",{href:"https://github.com/markdown-it/markdown-it"},"markdown-it"),e(" in "),t("a",{href:"https://vuejs.org/guide/scaling-up/sfc.html"},"Vue SFC"),e(" Components")]),t("li",null,[e("React Templates - with "),t("a",{href:"https://github.com/remarkjs/remark"},"remark"),e(" and "),t("a",{href:"https://mdxjs.com"},"MDX"),e(" in "),t("a",{href:"https://react.dev"},"React"),e(" Components")])],-1),pt=t("h3",null,".NET Templates with C# and Markdig",-1),ut=t("p",null,[e("Whilst the same Markdown feature folders are "),t("a",{href:"https://razor-ssg.web-templates.io/posts/razor-ssg"},"implemented in C#"),e(" and rendered with "),t("a",{href:"https://github.com/xoofx/markdig"},"Markdig"),e(" and either Razor Pages or Blazor Components:")],-1),dt=t("h4",null,".NET 8 Razor SSG and Blazor SSR Templates",-1),ht=t("ul",null,[t("li",null,[t("a",{href:"https://razor-ssg.web-templates.io"},"razor-ssg"),e(" - .NET Razor SSG Blog and Marketing Website with "),t("strong",null,"Markdig")]),t("li",null,[t("a",{href:"https://blazor-vue.web-templates.io"},"blazor-vue"),e(" - .NET 8 Blazor Server Rendered Website with "),t("strong",null,"Markdig")]),t("li",null,[t("a",{href:"https://razor-press.web-templates.io"},"razor-press"),e(" - .NET Razor SSG Documentation Website with "),t("strong",null,"Markdig")])],-1),gt=t("div",{class:"not-prose mt-8 grid grid-cols-2 gap-4"},[t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://razor-ssg.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/razor-ssg.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"razor-ssg.web-templates.io")]),t("a",{class:"block group border dark:border-gray-800 hover:border-indigo-700 dark:hover:border-indigo-700 flex flex-col justify-between",href:"https://blazor-vue.web-templates.io"},[t("img",{class:"p-2",src:"https://raw.githubusercontent.com/ServiceStack/Assets/master/csharp-templates/blazor-vue.png"}),t("div",{class:"bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 font-semibold group-hover:bg-indigo-700 group-hover:text-white text-center py-2"},"blazor-vue.web-templates.io")])],-1),mt=t("h3",null,"Markdown Feature Folders",-1),kt=t("p",null,[e("The content for each Markdown feature is maintained within its own feature folder with a "),t("code",null,"_"),e(" prefix:")],-1),bt=t("h4",null,"Markdown Document Structure",-1),_t=t("p",null,"Additional metadata for each markdown page is maintained in the frontmatter of each markdown page, e.g. the front matter for this blog post contains:",-1),ft=t("pre",{class:"language-md"},[t("code",{class:"language-md"},[t("span",{class:"token front-matter-block"},[t("span",{class:"token punctuation"},"---"),e(` `),t("span",{class:"token front-matter yaml language-yaml"},`title: Vite Press Plugin summary: Introducing the Vite Press Plugin author: Lucy Bates tags: [docs,markdown] image: https://source.unsplash.com/random/2000x1000/?stationary`),e(` `),t("span",{class:"token punctuation"},"---")]),e(` -`)])],-1),ft=t("p",null,"The frontmatter is used in combination with file attributes to populate the document metadata. The schema used to support the current markdown features include:",-1),wt=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"type"),e(),t("span",{class:"token class-name"},"Doc"),e(),t("span",{class:"token operator"},"="),e(),t("span",{class:"token punctuation"},"{"),e(` +`)])],-1),wt=t("p",null,"The frontmatter is used in combination with file attributes to populate the document metadata. The schema used to support the current markdown features include:",-1),yt=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"type"),e(),t("span",{class:"token class-name"},"Doc"),e(),t("span",{class:"token operator"},"="),e(),t("span",{class:"token punctuation"},"{"),e(` title`),t("span",{class:"token operator"},":"),e(),t("span",{class:"token builtin"},"string"),e(" "),t("span",{class:"token comment"},"// title of Markdown page (frontmatter)"),e(` slug`),t("span",{class:"token operator"},":"),e(),t("span",{class:"token builtin"},"string"),e(" "),t("span",{class:"token comment"},"// slug to page (populated)"),e(` path`),t("span",{class:"token operator"},":"),e(),t("span",{class:"token builtin"},"string"),e(" "),t("span",{class:"token comment"},"// path to page (populated)"),e(` @@ -36,17 +36,17 @@ image: https://source.unsplash.com/random/2000x1000/?stationary`),e(` url`),t("span",{class:"token operator"},":"),e(),t("span",{class:"token builtin"},"string"),e(" "),t("span",{class:"token comment"},"// URL of YouTube Video"),e(` image`),t("span",{class:"token operator"},":"),e(),t("span",{class:"token builtin"},"string"),e(" "),t("span",{class:"token comment"},"// Image to display for feature"),e(` `),t("span",{class:"token punctuation"},"}"),e(` -`)])],-1),yt=t("p",null,"Markdown files can contain additional frontmatter which is also merged with the document metadata.",-1),vt=t("h3",null,"Accessing Markdown Metadata",-1),xt=t("p",null,[e("In Vue App’s the Metadata is available as an injected dependency that’s navigable with the typed "),t("code",null,"VirtualPress"),e(" schema, e.g:")],-1),Vt=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"import"),e(),t("span",{class:"token keyword"},"type"),e(),t("span",{class:"token punctuation"},"{"),e(" VirtualPress "),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"from"),e(),t("span",{class:"token string"},'"vite-plugin-press"'),e(` +`)])],-1),vt=t("p",null,"Markdown files can contain additional frontmatter which is also merged with the document metadata.",-1),xt=t("h3",null,"Accessing Markdown Metadata",-1),Vt=t("p",null,[e("In Vue App’s the Metadata is available as an injected dependency that’s navigable with the typed "),t("code",null,"VirtualPress"),e(" schema, e.g:")],-1),Tt=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"import"),e(),t("span",{class:"token keyword"},"type"),e(),t("span",{class:"token punctuation"},"{"),e(" VirtualPress "),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"from"),e(),t("span",{class:"token string"},'"vite-plugin-press"'),e(` `),t("span",{class:"token keyword"},"const"),e(" press"),t("span",{class:"token operator"},":"),e("VirtualPress "),t("span",{class:"token operator"},"="),e(),t("span",{class:"token function"},"inject"),t("span",{class:"token punctuation"},"("),t("span",{class:"token string"},"'press'"),t("span",{class:"token punctuation"},")"),t("span",{class:"token operator"},"!"),e(` -`)])],-1),Tt=t("p",null,"In React App’s it’s available via an injected context:",-1),Mt=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"import"),e(),t("span",{class:"token punctuation"},"{"),e(" PressContext "),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"from"),e(),t("span",{class:"token string"},'"@/contexts"'),e(` +`)])],-1),Mt=t("p",null,"In React App’s it’s available via an injected context:",-1),Pt=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"import"),e(),t("span",{class:"token punctuation"},"{"),e(" PressContext "),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"from"),e(),t("span",{class:"token string"},'"@/contexts"'),e(` `),t("span",{class:"token keyword"},"const"),e(" press "),t("span",{class:"token operator"},"="),e(),t("span",{class:"token function"},"useContext"),t("span",{class:"token punctuation"},"("),e("PressContext"),t("span",{class:"token punctuation"},")"),e(` -`)])],-1),Pt=t("p",null,"Which is defined as:",-1),Ct=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"import"),e(),t("span",{class:"token punctuation"},"{"),e(" createContext "),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"from"),e(),t("span",{class:"token string"},"'react'"),e(` +`)])],-1),Ct=t("p",null,"Which is defined as:",-1),At=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"import"),e(),t("span",{class:"token punctuation"},"{"),e(" createContext "),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"from"),e(),t("span",{class:"token string"},"'react'"),e(` `),t("span",{class:"token keyword"},"import"),e(),t("span",{class:"token keyword"},"type"),e(),t("span",{class:"token punctuation"},"{"),e(" VirtualPress "),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"from"),e(),t("span",{class:"token string"},"'vite-plugin-press'"),e(` `),t("span",{class:"token keyword"},"export"),e(),t("span",{class:"token keyword"},"const"),e(" PressContext "),t("span",{class:"token operator"},"="),e(),t("span",{class:"token generic-function"},[t("span",{class:"token function"},"createContext"),t("span",{class:"token generic class-name"},[t("span",{class:"token operator"},"<"),e("VirtualPress"),t("span",{class:"token operator"},">")])]),t("span",{class:"token punctuation"},"("),t("span",{class:"token punctuation"},"{"),t("span",{class:"token punctuation"},"}"),e(),t("span",{class:"token keyword"},"as"),e(" VirtualPress"),t("span",{class:"token punctuation"},")"),e(` -`)])],-1),At=t("p",null,[e("This "),t("code",null,"VirtualPress"),e(" metadata is used to power all markdown features.")],-1),jt=t("h3",null,"Blog",-1),Bt=t("p",null,[e("The blog maintains its markdown posts in a flat "),t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/tree/main/MyApp.Client/src/_posts"},"/_posts"),e(" folder which each Markdown post containing its publish date and URL slug it should be published under, e.g:")],-1),Nt=t("p",null,"Supporting all Blog features requires several different pages to render each of its view:",-1),St=t("table",null,[t("thead",null,[t("tr",null,[t("th",null,"Description"),t("th",null,"Example"),t("th",null,"Vue"),t("th",null,"React")])]),t("tbody",null,[t("tr",null,[t("td",null,"Main Blog layout"),t("td",null,[t("a",{href:"/blog"},"/blog")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/blog.vue"},"blog.vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/blog.tsx"},"blog.tsx")])]),t("tr",null,[t("td",null,"Navigable Archive of Posts"),t("td",null,[t("a",{href:"/posts"},"/posts")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/index.vue"},"index.vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/index.tsx"},"index.tsx")])]),t("tr",null,[t("td",null,"Individual Blog Post (like this!)"),t("td",null,[t("a",{href:"/posts/vite-press-plugin"},"/posts/vite-press-plugin")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/%5Bslug%5D.vue"},"[slug].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/%5Bslug%5D.tsx"},"[slug].tsx")])]),t("tr",null,[t("td",null,"Display Posts by Author"),t("td",null,[t("a",{href:"/posts/author/lucy-bates"},"/posts/author/lucy-bates")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/author/%5Bname%5D.vue"},"[name].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/author/%5Bname%5D.tsx"},"[name].tsx")])]),t("tr",null,[t("td",null,"Display Posts by Tag"),t("td",null,[t("a",{href:"/posts/tagged/markdown"},"/posts/tagged/markdown")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/tagged/%5Btag%5D.vue"},"[tag].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/tagged/%5Btag%5D.tsx"},"[tag].tsx")])]),t("tr",null,[t("td",null,"Display Posts by Year"),t("td",null,[t("a",{href:"/posts/year/2024"},"/posts/year/2024")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/year/%5Byear%5D.vue"},"[year].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/year/%5Byear%5D.tsx"},"[year].tsx")])])])],-1),It=t("h4",null,"Configuration",-1),Rt=t("p",null,[e("Additional information about the Website Blog is maintained in "),t("code",null,"_posts/config.json")],-1),zt=t("pre",{class:"language-json"},[t("code",{class:"language-json"},[t("span",{class:"token punctuation"},"{"),e(` +`)])],-1),jt=t("p",null,[e("This "),t("code",null,"VirtualPress"),e(" metadata is used to power all markdown features.")],-1),Bt=t("h3",null,"Blog",-1),Nt=t("p",null,[e("The blog maintains its markdown posts in a flat "),t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/tree/main/MyApp.Client/src/_posts"},"/_posts"),e(" folder which each Markdown post containing its publish date and URL slug it should be published under, e.g:")],-1),St=t("p",null,"Supporting all Blog features requires several different pages to render each of its view:",-1),It=t("table",null,[t("thead",null,[t("tr",null,[t("th",null,"Description"),t("th",null,"Example"),t("th",null,"Vue"),t("th",null,"React")])]),t("tbody",null,[t("tr",null,[t("td",null,"Main Blog layout"),t("td",null,[t("a",{href:"/blog"},"/blog")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/blog.vue"},"blog.vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/blog.tsx"},"blog.tsx")])]),t("tr",null,[t("td",null,"Navigable Archive of Posts"),t("td",null,[t("a",{href:"/posts"},"/posts")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/index.vue"},"index.vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/index.tsx"},"index.tsx")])]),t("tr",null,[t("td",null,"Individual Blog Post (like this!)"),t("td",null,[t("a",{href:"/posts/vite-press-plugin"},"/posts/vite-press-plugin")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/%5Bslug%5D.vue"},"[slug].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/%5Bslug%5D.tsx"},"[slug].tsx")])]),t("tr",null,[t("td",null,"Display Posts by Author"),t("td",null,[t("a",{href:"/posts/author/lucy-bates"},"/posts/author/lucy-bates")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/author/%5Bname%5D.vue"},"[name].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/author/%5Bname%5D.tsx"},"[name].tsx")])]),t("tr",null,[t("td",null,"Display Posts by Tag"),t("td",null,[t("a",{href:"/posts/tagged/markdown"},"/posts/tagged/markdown")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/tagged/%5Btag%5D.vue"},"[tag].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/tagged/%5Btag%5D.tsx"},"[tag].tsx")])]),t("tr",null,[t("td",null,"Display Posts by Year"),t("td",null,[t("a",{href:"/posts/year/2024"},"/posts/year/2024")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/posts/year/%5Byear%5D.vue"},"[year].vue")]),t("td",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/posts/year/%5Byear%5D.tsx"},"[year].tsx")])])])],-1),Rt=t("h4",null,"Configuration",-1),zt=t("p",null,[e("Additional information about the Website Blog is maintained in "),t("code",null,"_posts/config.json")],-1),Dt=t("pre",{class:"language-json"},[t("code",{class:"language-json"},[t("span",{class:"token punctuation"},"{"),e(` `),t("span",{class:"token property"},'"localBaseUrl"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"http://localhost:5173"'),t("span",{class:"token punctuation"},","),e(` `),t("span",{class:"token property"},'"publicBaseUrl"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"https://press-vue.web-templates.io"'),t("span",{class:"token punctuation"},","),e(` `),t("span",{class:"token property"},'"siteTwitter"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"@Vue"'),t("span",{class:"token punctuation"},","),e(` @@ -55,7 +55,7 @@ image: https://source.unsplash.com/random/2000x1000/?stationary`),e(` `),t("span",{class:"token property"},'"blogEmail"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"email@example.org (Vue)"'),t("span",{class:"token punctuation"},","),e(` `),t("span",{class:"token property"},'"blogImageUrl"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"https://servicestack.net/img/logo.png"'),e(` `),t("span",{class:"token punctuation"},"}"),e(` -`)])],-1),Dt=t("h4",null,"Authors",-1),Lt=t("p",null,[e("Whilst information about Post Authors are maintained in "),t("code",null,"_posts/authors.json")],-1),Ft=t("pre",{class:"language-json"},[t("code",{class:"language-json"},[t("span",{class:"token punctuation"},"["),e(` +`)])],-1),Lt=t("h4",null,"Authors",-1),Ft=t("p",null,[e("Whilst information about Post Authors are maintained in "),t("code",null,"_posts/authors.json")],-1),Ut=t("pre",{class:"language-json"},[t("code",{class:"language-json"},[t("span",{class:"token punctuation"},"["),e(` `),t("span",{class:"token punctuation"},"{"),e(` `),t("span",{class:"token property"},'"name"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"Lucy Bates"'),t("span",{class:"token punctuation"},","),e(` `),t("span",{class:"token property"},'"email"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"lucy@email.org"'),t("span",{class:"token punctuation"},","),e(` @@ -66,25 +66,25 @@ image: https://source.unsplash.com/random/2000x1000/?stationary`),e(` `),t("span",{class:"token property"},'"gitHubUrl"'),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},'"https://github.com/lucy"'),e(` `),t("span",{class:"token punctuation"},"}"),t("span",{class:"token punctuation"},","),e(` `),t("span",{class:"token punctuation"},"]"),e(` -`)])],-1),Ut=t("p",null,[e("To associate an Author the "),t("strong",null,"name"),e(" property is used to match a posts frontmatter "),t("strong",null,"author"),e(".")],-1),$t=t("h3",null,"General Features",-1),Wt=t("p",null,"Most unique markdown features are captured in their Markdown’s frontmatter metadata, but in general these features are broadly available for all features:",-1),Et=t("ul",null,[t("li",null,[t("strong",null,"Live Reload"),e(" - Latest Markdown content is displayed during "),t("strong",null,"Development")]),t("li",null,[t("strong",null,"Drafts"),e(" - Prevent posts being worked on from being published with "),t("code",null,"draft: true")]),t("li",null,[t("strong",null,"Future Dates"),e(" - Posts with a future date wont be published until that date")])],-1),Ot=t("h3",null,"What’s New Feature",-1),qt=t("p",null,[e("The "),t("a",{href:"/whatsnew"},"/whatsnew"),e(" page is an example of creating a custom Markdown feature to implement a portfolio or a product releases page where a new folder is created per release, containing both release date and release or project name, with all features in that release maintained markdown content sorted in alphabetical order:")],-1),Yt=t("p",null,"What’s New follows the same structure as Pages feature which is rendered in:",-1),Gt=t("ul",null,[t("li",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/whatsnew.vue"},"whatsnew.vue")]),t("li",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/whatsnew.tsx"},"whatsnew.tsx")])],-1),Ht=t("h3",null,"Videos Feature",-1),Zt=t("p",null,[e("The videos feature maintained in the "),t("code",null,"_videos"),e(" folder allows grouping of related videos into different folder groups, e.g:")],-1),Xt=t("p",null,[e("These can then be rendered as UI fragments using the "),t("code",null,""),e(" component, e.g:")],-1),Kt=t("pre",{class:"language-tsx"},[t("code",{class:"language-tsx"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),t("span",{class:"token class-name"},"VideoGroup")]),e(` +`)])],-1),$t=t("p",null,[e("To associate an Author the "),t("strong",null,"name"),e(" property is used to match a posts frontmatter "),t("strong",null,"author"),e(".")],-1),Wt=t("h3",null,"General Features",-1),Et=t("p",null,"Most unique markdown features are captured in their Markdown’s frontmatter metadata, but in general these features are broadly available for all features:",-1),Ot=t("ul",null,[t("li",null,[t("strong",null,"Live Reload"),e(" - Latest Markdown content is displayed during "),t("strong",null,"Development")]),t("li",null,[t("strong",null,"Drafts"),e(" - Prevent posts being worked on from being published with "),t("code",null,"draft: true")]),t("li",null,[t("strong",null,"Future Dates"),e(" - Posts with a future date wont be published until that date")])],-1),qt=t("h3",null,"What’s New Feature",-1),Yt=t("p",null,[e("The "),t("a",{href:"/whatsnew"},"/whatsnew"),e(" page is an example of creating a custom Markdown feature to implement a portfolio or a product releases page where a new folder is created per release, containing both release date and release or project name, with all features in that release maintained markdown content sorted in alphabetical order:")],-1),Gt=t("p",null,"What’s New follows the same structure as Pages feature which is rendered in:",-1),Ht=t("ul",null,[t("li",null,[t("a",{href:"https://github.com/NetCoreTemplates/vue-spa/blob/main/MyApp.Client/src/pages/whatsnew.vue"},"whatsnew.vue")]),t("li",null,[t("a",{href:"https://github.com/NetCoreTemplates/react-spa/blob/main/MyApp.Client/src/pages/whatsnew.tsx"},"whatsnew.tsx")])],-1),Zt=t("h3",null,"Videos Feature",-1),Xt=t("p",null,[e("The videos feature maintained in the "),t("code",null,"_videos"),e(" folder allows grouping of related videos into different folder groups, e.g:")],-1),Kt=t("p",null,[e("These can then be rendered as UI fragments using the "),t("code",null,""),e(" component, e.g:")],-1),Jt=t("pre",{class:"language-tsx"},[t("code",{class:"language-tsx"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),t("span",{class:"token class-name"},"VideoGroup")]),e(` `),t("span",{class:"token attr-name"},"title"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("Vue Components"),t("span",{class:"token punctuation"},'"')]),e(` `),t("span",{class:"token attr-name"},"summary"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("Learn about productive features in Vue Component Library"),t("span",{class:"token punctuation"},'"')]),e(` `),t("span",{class:"token attr-name"},"group"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("vue"),t("span",{class:"token punctuation"},'"')]),e(` `),t("span",{class:"token attr-name"},"learnMore"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("https://docs.servicestack.net/vue/"),t("span",{class:"token punctuation"},'"')]),e(),t("span",{class:"token punctuation"},"/>")]),e(` -`)])],-1),Jt=t("h3",null,"Includes Feature",-1),Qt=t("p",null,[e("The includes feature allows maintaining reusable markdown fragments in the "),t("code",null,"_includes"),e(" folder, e.g:")],-1),te=t("p",null,"Which can be included in other Markdown files with:",-1),ee=t("pre",{class:"language-md"},[t("code",{class:"language-md"},`:::include privacy.md::: +`)])],-1),Qt=t("h3",null,"Includes Feature",-1),te=t("p",null,[e("The includes feature allows maintaining reusable markdown fragments in the "),t("code",null,"_includes"),e(" folder, e.g:")],-1),ee=t("p",null,"Which can be included in other Markdown files with:",-1),se=t("pre",{class:"language-md"},[t("code",{class:"language-md"},`:::include privacy.md::: :::include features/include.md::: -`)],-1),se=t("p",null,[e("Alternatively they can be included in other Vue, React or Markdown pages with the "),t("code",null,""),e(" component, e.g:")],-1),ne=t("pre",{class:"language-tsx"},[t("code",{class:"language-tsx"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),t("span",{class:"token class-name"},"Include")]),e(),t("span",{class:"token attr-name"},"src"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("privacy.md"),t("span",{class:"token punctuation"},'"')]),e(),t("span",{class:"token punctuation"},"/>")]),e(` +`)],-1),ne=t("p",null,[e("Alternatively they can be included in other Vue, React or Markdown pages with the "),t("code",null,""),e(" component, e.g:")],-1),oe=t("pre",{class:"language-tsx"},[t("code",{class:"language-tsx"},[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),t("span",{class:"token class-name"},"Include")]),e(),t("span",{class:"token attr-name"},"src"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("privacy.md"),t("span",{class:"token punctuation"},'"')]),e(),t("span",{class:"token punctuation"},"/>")]),e(` `),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),t("span",{class:"token class-name"},"Include")]),e(),t("span",{class:"token attr-name"},"src"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),e("features/include.md"),t("span",{class:"token punctuation"},'"')]),e(),t("span",{class:"token punctuation"},"/>")]),e(` -`)])],-1),oe=t("h3",null,"Metadata APIs Feature",-1),ae=t("p",null,[e("To support external clients from querying static markdown metadata you can export it to pre-rendered static "),t("code",null,"*.json"),e(" data structures by configuring "),t("code",null,"metadataPath"),e(" to the location you the "),t("code",null,"*.json"),e(" files published to, e.g:")],-1),le=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"export"),e(),t("span",{class:"token keyword"},"default"),e(),t("span",{class:"token function"},"defineConfig"),t("span",{class:"token punctuation"},"("),t("span",{class:"token punctuation"},"{"),e(` +`)])],-1),ae=t("h3",null,"Metadata APIs Feature",-1),le=t("p",null,[e("To support external clients from querying static markdown metadata you can export it to pre-rendered static "),t("code",null,"*.json"),e(" data structures by configuring "),t("code",null,"metadataPath"),e(" to the location you the "),t("code",null,"*.json"),e(" files published to, e.g:")],-1),re=t("pre",{class:"language-ts"},[t("code",{class:"language-ts"},[t("span",{class:"token keyword"},"export"),e(),t("span",{class:"token keyword"},"default"),e(),t("span",{class:"token function"},"defineConfig"),t("span",{class:"token punctuation"},"("),t("span",{class:"token punctuation"},"{"),e(` plugins`),t("span",{class:"token operator"},":"),e(),t("span",{class:"token punctuation"},"["),e(` `),t("span",{class:"token function"},"Press"),t("span",{class:"token punctuation"},"("),t("span",{class:"token punctuation"},"{"),e(` metadataPath`),t("span",{class:"token operator"},":"),e(),t("span",{class:"token string"},"'public/api'"),t("span",{class:"token punctuation"},","),e(` `),t("span",{class:"token punctuation"},"}"),t("span",{class:"token punctuation"},")"),t("span",{class:"token punctuation"},","),e(` `),t("span",{class:"token punctuation"},"]"),e(` `),t("span",{class:"token punctuation"},"}"),t("span",{class:"token punctuation"},")"),e(` -`)])],-1),re=t("p",null,[e("This will publish all the content of each content type in the year they were published in, along with an "),t("code",null,"all.json"),e(" containing all content published in that year as well aso for all time, e.g:")],-1),ie=t("p",null,[e("With this you can fetch the metadata of all the new "),t("strong",null,"Blog Posts"),e(" added in "),t("strong",null,"2023"),e(" from:")],-1),ce=t("p",null,[t("a",{href:"/api/2024/blog.json"},"/api/2024/blog.json")],-1),pe=t("p",null,[e("Or all the website content added in "),t("strong",null,"2024"),e(" from:")],-1),ue=t("p",null,[t("a",{href:"/api/2024/all.json"},"/api/2024/all.json")],-1),de=t("p",null,[e("Or "),t("strong",null,"ALL"),e(" the website metadata content from:")],-1),he=t("p",null,[t("a",{href:"/api/all.json"},"/api/all.json")],-1),ge=t("p",null,[e("This feature makes it possible to support use-cases like CreatorKit’s "),t("a",{href:"https://servicestack.net/creatorkit/portal-mailruns#generating-newsletters"},"Generating Newsletters"),e(" feature which generates a Monthly Newsletter Email with all new content added within a specified period.")],-1),me=t("h2",null,"Markdown Containers",-1),ke=t("p",null,[e("Most of "),t("a",{href:"https://vitepress.dev/guide/markdown#custom-containers"},"VitePress Containers"),e(" are also implemented, enabling rich markup to enhance markdown content and documentation universally across all Markdown App implementations:")],-1),be=t("h4",null,"Input",-1),_e=t("pre",null,[t("code",null,`:::info +`)])],-1),ie=t("p",null,[e("This will publish all the content of each content type in the year they were published in, along with an "),t("code",null,"all.json"),e(" containing all content published in that year as well aso for all time, e.g:")],-1),ce=t("p",null,[e("With this you can fetch the metadata of all the new "),t("strong",null,"Blog Posts"),e(" added in "),t("strong",null,"2023"),e(" from:")],-1),pe=t("p",null,[t("a",{href:"/api/2024/blog.json"},"/api/2024/blog.json")],-1),ue=t("p",null,[e("Or all the website content added in "),t("strong",null,"2024"),e(" from:")],-1),de=t("p",null,[t("a",{href:"/api/2024/all.json"},"/api/2024/all.json")],-1),he=t("p",null,[e("Or "),t("strong",null,"ALL"),e(" the website metadata content from:")],-1),ge=t("p",null,[t("a",{href:"/api/all.json"},"/api/all.json")],-1),me=t("p",null,[e("This feature makes it possible to support use-cases like CreatorKit’s "),t("a",{href:"https://servicestack.net/creatorkit/portal-mailruns#generating-newsletters"},"Generating Newsletters"),e(" feature which generates a Monthly Newsletter Email with all new content added within a specified period.")],-1),ke=t("h2",null,"Markdown Containers",-1),be=t("p",null,[e("Most of "),t("a",{href:"https://vitepress.dev/guide/markdown#custom-containers"},"VitePress Containers"),e(" are also implemented, enabling rich markup to enhance markdown content and documentation universally across all Markdown App implementations:")],-1),_e=t("h4",null,"Input",-1),fe=t("pre",null,[t("code",null,`:::info This is an info box. ::: @@ -99,20 +99,20 @@ This is a warning. :::danger This is a dangerous warning. ::: -`)],-1),fe=t("h4",null,"Output",-1),we=t("div",{class:"info custom-block"},[t("p",{class:"custom-block-title"},"INFO"),t("p",null,"This is an info box.")],-1),ye=t("div",{class:"tip custom-block"},[t("p",{class:"custom-block-title"},"TIP"),t("p",null,"This is a tip.")],-1),ve=t("div",{class:"warning custom-block"},[t("p",{class:"custom-block-title"},"WARNING"),t("p",null,"This is a warning.")],-1),xe=t("div",{class:"danger custom-block"},[t("p",{class:"custom-block-title"},"DANGER"),t("p",null,"This is a dangerous warning.")],-1),Ve=t("h3",null,"Custom Title",-1),Te=t("p",null,"You can specify a custom title by appending the text right after the container type:",-1),Me=t("h4",null,"Input",-1),Pe=t("pre",null,[t("code",null,`:::danger STOP +`)],-1),we=t("h4",null,"Output",-1),ye=t("div",{class:"info custom-block"},[t("p",{class:"custom-block-title"},"INFO"),t("p",null,"This is an info box.")],-1),ve=t("div",{class:"tip custom-block"},[t("p",{class:"custom-block-title"},"TIP"),t("p",null,"This is a tip.")],-1),xe=t("div",{class:"warning custom-block"},[t("p",{class:"custom-block-title"},"WARNING"),t("p",null,"This is a warning.")],-1),Ve=t("div",{class:"danger custom-block"},[t("p",{class:"custom-block-title"},"DANGER"),t("p",null,"This is a dangerous warning.")],-1),Te=t("h3",null,"Custom Title",-1),Me=t("p",null,"You can specify a custom title by appending the text right after the container type:",-1),Pe=t("h4",null,"Input",-1),Ce=t("pre",null,[t("code",null,`:::danger STOP Danger zone, do not proceed ::: -`)],-1),Ce=t("h4",null,"Output",-1),Ae=t("div",{class:"danger custom-block"},[t("p",{class:"custom-block-title"},"STOP"),t("p",null,"Danger zone, do not proceed")],-1),je=t("h3",null,"copy",-1),Be=t("p",null,[e("The "),t("strong",null,"copy"),e(" container is ideal for displaying text snippets in a component that allows for easy copying:")],-1),Ne=t("h4",null,"Input",-1),Se=t("pre",null,[t("code",null,`:::copy +`)],-1),Ae=t("h4",null,"Output",-1),je=t("div",{class:"danger custom-block"},[t("p",{class:"custom-block-title"},"STOP"),t("p",null,"Danger zone, do not proceed")],-1),Be=t("h3",null,"copy",-1),Ne=t("p",null,[e("The "),t("strong",null,"copy"),e(" container is ideal for displaying text snippets in a component that allows for easy copying:")],-1),Se=t("h4",null,"Input",-1),Ie=t("pre",null,[t("code",null,`:::copy Copy Me! ::: -`)],-1),Ie=t("h4",null,"Output",-1),Re=t("div",{class:"not-prose copy cp flex cursor-pointer mb-3",onclick:"copy(this)"},[t("div",{class:"flex-grow bg-gray-700"},[t("div",{class:"pl-4 py-1 pb-1.5 align-middle text-lg text-white"},[t("p",null,"Copy Me!")])]),t("div",{class:"flex"},[t("div",{class:"bg-sky-500 text-white p-1.5 pb-0"},[t("svg",{class:"copied w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"})]),t("svg",{class:"nocopy w-6 h-6",title:"copy",fill:"none",stroke:"white",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"1",d:"M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"})])])])],-1),ze=t("p",null,"HTML or XML fragments can also be copied by escaping them first:",-1),De=t("h4",null,"Input",-1),Le=t("pre",{class:"language-md"},[t("code",{class:"language-md"},[e(`:::copy +`)],-1),Re=t("h4",null,"Output",-1),ze=t("div",{class:"not-prose copy cp flex cursor-pointer mb-3",onclick:"copy(this)"},[t("div",{class:"flex-grow bg-gray-700"},[t("div",{class:"pl-4 py-1 pb-1.5 align-middle text-lg text-white"},[t("p",null,"Copy Me!")])]),t("div",{class:"flex"},[t("div",{class:"bg-sky-500 text-white p-1.5 pb-0"},[t("svg",{class:"copied w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"})]),t("svg",{class:"nocopy w-6 h-6",title:"copy",fill:"none",stroke:"white",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"1",d:"M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"})])])])],-1),De=t("p",null,"HTML or XML fragments can also be copied by escaping them first:",-1),Le=t("h4",null,"Input",-1),Fe=t("pre",{class:"language-md"},[t("code",{class:"language-md"},[e(`:::copy `),t("span",{class:"token code-snippet code keyword"},'``'),e(` ::: -`)])],-1),Fe=t("h4",null,"Output",-1),Ue=t("div",{class:"not-prose copy cp flex cursor-pointer mb-3",onclick:"copy(this)"},[t("div",{class:"flex-grow bg-gray-700"},[t("div",{class:"pl-4 py-1 pb-1.5 align-middle text-lg text-white"},[t("p",null,[t("code",null,'')])])]),t("div",{class:"flex"},[t("div",{class:"bg-sky-500 text-white p-1.5 pb-0"},[t("svg",{class:"copied w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"})]),t("svg",{class:"nocopy w-6 h-6",title:"copy",fill:"none",stroke:"white",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"1",d:"M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"})])])])],-1),$e=t("h3",null,"sh",-1),We=t("p",null,[e("Similarly the "),t("strong",null,"sh"),e(" container is ideal for displaying and copying shell commands:")],-1),Ee=t("h4",null,"Input",-1),Oe=t("pre",null,[t("code",null,`:::sh +`)])],-1),Ue=t("h4",null,"Output",-1),$e=t("div",{class:"not-prose copy cp flex cursor-pointer mb-3",onclick:"copy(this)"},[t("div",{class:"flex-grow bg-gray-700"},[t("div",{class:"pl-4 py-1 pb-1.5 align-middle text-lg text-white"},[t("p",null,[t("code",null,'')])])]),t("div",{class:"flex"},[t("div",{class:"bg-sky-500 text-white p-1.5 pb-0"},[t("svg",{class:"copied w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"})]),t("svg",{class:"nocopy w-6 h-6",title:"copy",fill:"none",stroke:"white",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"1",d:"M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"})])])])],-1),We=t("h3",null,"sh",-1),Ee=t("p",null,[e("Similarly the "),t("strong",null,"sh"),e(" container is ideal for displaying and copying shell commands:")],-1),Oe=t("h4",null,"Input",-1),qe=t("pre",null,[t("code",null,`:::sh npm run dev ::: -`)],-1),qe=t("h4",null,"Output",-1),Ye=t("div",{class:"not-prose sh-copy cp flex cursor-pointer mb-3",onclick:"copy(this)"},[t("div",{class:"flex-grow bg-gray-800"},[t("div",{class:"pl-4 py-1 pb-1.5 align-middle whitespace-pre text-base text-gray-100"},[t("p",null,"npm run dev")])]),t("div",{class:"flex"},[t("div",{class:"bg-green-600 text-white p-1.5 pb-0"},[t("svg",{class:"copied w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"})]),t("svg",{class:"nocopy w-6 h-6",title:"copy",fill:"none",stroke:"white",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"1",d:"M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"})])])])],-1),Ge=t("h3",null,"YouTube",-1),He=t("p",null,[e("For embedding YouTube Videos, optimally rendered using the "),t("code",null,""),e(" component, e.g:")],-1),Ze=t("h4",null,"Input",-1),Xe=t("pre",null,[t("code",null,`:::youtube YIa0w6whe2U::: -`)],-1),Ke=t("h4",null,"Output",-1),Je=t("h2",null,"Markdown Fenced Code Blocks",-1),Qe=t("p",null,[e("For more flexibility you can utilize custom fenced components like the "),t("code",null,"files"),e(" fenced code block which can be used to capture ascii representation of a structured documentation like a folder & file structure, e.g:")],-1),ts=t("pre",null,[t("code",null,`\`\`\`files +`)],-1),Ye=t("h4",null,"Output",-1),Ge=t("div",{class:"not-prose sh-copy cp flex cursor-pointer mb-3",onclick:"copy(this)"},[t("div",{class:"flex-grow bg-gray-800"},[t("div",{class:"pl-4 py-1 pb-1.5 align-middle whitespace-pre text-base text-gray-100"},[t("p",null,"npm run dev")])]),t("div",{class:"flex"},[t("div",{class:"bg-green-600 text-white p-1.5 pb-0"},[t("svg",{class:"copied w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"})]),t("svg",{class:"nocopy w-6 h-6",title:"copy",fill:"none",stroke:"white",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"1",d:"M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"})])])])],-1),He=t("h3",null,"YouTube",-1),Ze=t("p",null,[e("For embedding YouTube Videos, optimally rendered using the "),t("code",null,""),e(" component, e.g:")],-1),Xe=t("h4",null,"Input",-1),Ke=t("pre",null,[t("code",null,`:::youtube YIa0w6whe2U::: +`)],-1),Je=t("h4",null,"Output",-1),Qe=t("h2",null,"Markdown Fenced Code Blocks",-1),ts=t("p",null,[e("For more flexibility you can utilize custom fenced components like the "),t("code",null,"files"),e(" fenced code block which can be used to capture ascii representation of a structured documentation like a folder & file structure, e.g:")],-1),es=t("pre",null,[t("code",null,`\`\`\`files /_videos /vue admin.md @@ -123,22 +123,22 @@ npm run dev bookings.md nextjs.md \`\`\` -`)],-1),es=t("p",null,[e("That we can render into a more UX-friendly representation by calling the "),t("code",null,"Files"),e(" component with the body of the code-block to convert the structured ascii layout into a more familiar GUI layout:")],-1),ss=t("p",null,"The benefit of this approach of marking up documentation is that the markdown content still remains in an optimal human-readable form even when the markdown renderer lacks the custom fenced components to render the richer UI.",-1),ns=t("h2",null,"Components In Markdown",-1),os=t("p",null,"Up till now all above features will let you render the same markdown content in all available Vue, React, Razor or Blazor templates. At the cost of reduced portability, you’re also able to embed rich Interactive Vue or React components directly in markdown.",-1),rs="Vite Press Plugin",is="Introducing the Vite Press Plugin for Vite Vue & React Apps",cs="Lucy Bates",ps=["docs","markdown"],us="https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000",ds=[{property:"og:title",content:"Vite Press Plugin"},{name:"twitter:title",content:"Vite Press Plugin"},{property:"og:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}],hs={__name:"2024-03-01_vite-press-plugin",setup(m,{expose:n}){const c={title:"Vite Press Plugin",summary:"Introducing the Vite Press Plugin for Vite Vue & React Apps",author:"Lucy Bates",tags:["docs","markdown"],image:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000",meta:[{property:"og:title",content:"Vite Press Plugin"},{name:"twitter:title",content:"Vite Press Plugin"},{property:"og:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]};return n({frontmatter:c}),j({title:"Vite Press Plugin",meta:[{property:"og:title",content:"Vite Press Plugin"},{name:"twitter:title",content:"Vite Press Plugin"},{property:"og:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]}),(l,r)=>{const a=H,d=T("LiteYouTube"),h=N,u=P;return s(),g(u,{frontmatter:c},{default:B(()=>[t("div",Z,[X,K,J,Q,tt,et,st,nt,ot,at,lt,rt,it,ct,pt,ut,dt,ht,gt,mt,i(a,{body:`/_includes +`)],-1),ss=t("p",null,[e("That we can render into a more UX-friendly representation by calling the "),t("code",null,"Files"),e(" component with the body of the code-block to convert the structured ascii layout into a more familiar GUI layout:")],-1),ns=t("p",null,"The benefit of this approach of marking up documentation is that the markdown content still remains in an optimal human-readable form even when the markdown renderer lacks the custom fenced components to render the richer UI.",-1),os=t("h2",null,"Components In Markdown",-1),as=t("p",null,"Up till now all above features will let you render the same markdown content in all available Vue, React, Razor or Blazor templates. At the cost of reduced portability, you’re also able to embed rich Interactive Vue or React components directly in markdown.",-1),is="Vite Press Plugin",cs="Introducing the Vite Press Plugin for Vite Vue & React Apps",ps="Lucy Bates",us=["docs","markdown"],ds="https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000",hs=[{property:"og:title",content:"Vite Press Plugin"},{name:"twitter:title",content:"Vite Press Plugin"},{property:"og:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}],gs={__name:"2024-03-01_vite-press-plugin",setup(g,{expose:n}){const c={title:"Vite Press Plugin",summary:"Introducing the Vite Press Plugin for Vite Vue & React Apps",author:"Lucy Bates",tags:["docs","markdown"],image:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000",meta:[{property:"og:title",content:"Vite Press Plugin"},{name:"twitter:title",content:"Vite Press Plugin"},{property:"og:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]};return n({frontmatter:c}),B({title:"Vite Press Plugin",meta:[{property:"og:title",content:"Vite Press Plugin"},{name:"twitter:title",content:"Vite Press Plugin"},{property:"og:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:image",content:"https://images.unsplash.com/photo-1524668951403-d44b28200ce0?crop=entropy&fit=crop&h=1000&w=2000"},{name:"twitter:card",content:"summary_large_image"}]}),(l,r)=>{const a=Z,u=M("LiteYouTube"),m=S,d=C;return s(),h(d,{frontmatter:c},{default:N(()=>[t("div",X,[K,J,Q,tt,et,st,nt,ot,at,lt,rt,it,ct,pt,ut,dt,ht,gt,mt,kt,i(a,{body:`/_includes /_posts /_videos /_whatsnew -`}),kt,bt,_t,ft,wt,yt,vt,xt,Vt,Tt,Mt,Pt,Ct,At,jt,Bt,i(a,{body:`/_posts +`}),bt,_t,ft,wt,yt,vt,xt,Vt,Tt,Mt,Pt,Ct,At,jt,Bt,Nt,i(a,{body:`/_posts 2023-01-21_start.md 2024-02-11_jwt-identity-auth.md 2024-03-01_vite-press-plugin.md -`},null,8,["body"]),Nt,St,It,Rt,zt,Dt,Lt,Ft,Ut,$t,Wt,Et,Ot,qt,i(a,{body:`/_whatsnew +`},null,8,["body"]),St,It,Rt,zt,Dt,Lt,Ft,Ut,$t,Wt,Et,Ot,qt,Yt,i(a,{body:`/_whatsnew /2023-03-08_Animaginary feature1.md /2023-03-18_OpenShuttle feature1.md /2023-03-28_Planetaria feature1.md -`},null,8,["body"]),Yt,Gt,Ht,Zt,i(a,{body:`/_videos +`},null,8,["body"]),Gt,Ht,Zt,Xt,i(a,{body:`/_videos /vue admin.md autoquerygrid.md @@ -147,12 +147,12 @@ npm run dev locode.md bookings.md nextjs.md -`},null,8,["body"]),Xt,Kt,Jt,Qt,i(a,{body:`/_includes +`},null,8,["body"]),Kt,Jt,Qt,te,i(a,{body:`/_includes /features videos.md whatsnew.md privacy.md -`},null,8,["body"]),te,ee,se,ne,oe,ae,le,re,i(a,{body:`/meta +`},null,8,["body"]),ee,se,ne,oe,ae,le,re,ie,i(a,{body:`/meta /2022 all.json posts.json @@ -167,7 +167,7 @@ npm run dev whatsnew.json all.json index.json -`},null,8,["body"]),ie,ce,pe,ue,de,he,ge,me,ke,be,_e,fe,we,ye,ve,xe,Ve,Te,Me,Pe,Ce,Ae,je,Be,Ne,Se,Ie,Re,ze,De,Le,Fe,Ue,$e,We,Ee,Oe,qe,Ye,Ge,He,Ze,Xe,Ke,i(d,{id:"YIa0w6whe2U"}),Je,Qe,ts,es,i(a,{body:`/_videos +`},null,8,["body"]),ce,pe,ue,de,he,ge,me,ke,be,_e,fe,we,ye,ve,xe,Ve,Te,Me,Pe,Ce,Ae,je,Be,Ne,Se,Ie,Re,ze,De,Le,Fe,Ue,$e,We,Ee,Oe,qe,Ye,Ge,He,Ze,Xe,Ke,Je,i(u,{id:"YIa0w6whe2U"}),Qe,ts,es,ss,i(a,{body:`/_videos /vue admin.md autoquerygrid.md @@ -176,4 +176,4 @@ npm run dev locode.md bookings.md nextjs.md -`},null,8,["body"]),ss,ns,os,i(h,{src:"component-links.md"})])]),_:1})}}};export{cs as author,hs as default,us as image,ds as meta,is as summary,ps as tags,rs as title}; +`},null,8,["body"]),ns,os,as,i(m,{src:"component-links.md"})])]),_:1})}}};export{ps as author,gs as default,ds as image,hs as meta,cs as summary,us as tags,is as title}; diff --git a/assets/BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js b/assets/BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js similarity index 95% rename from assets/BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js rename to assets/BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js index 2849ae2..f9134f5 100644 --- a/assets/BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js +++ b/assets/BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js @@ -1 +1 @@ -import{d as h,x as u,i as f,r as p,o as r,c as n,F as k,g as b,a as t,t as o,h as w,w as y,e as v,u as d}from"./index-B-kKBcPB.js";import{d as L,a as T,g as C}from"./utils-D7bH4Tlo.js";const $={class:"mx-auto grid max-w-lg gap-5 lg:max-w-none lg:grid-cols-3"},B={class:"flex flex-col overflow-hidden rounded-lg shadow-lg"},j={class:"flex-shrink-0"},H=["href"],R=["src"],F={class:"flex flex-1 flex-col justify-between bg-white dark:bg-black p-6"},M={class:"flex-1"},N=t("p",{class:"text-sm font-medium text-indigo-600 dark:text-indigo-300"}," Article ",-1),P=["href"],S=["title"],U={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},V={class:"mt-6 flex items-center"},A={class:"flex-shrink-0"},D={href:""},E={class:"sr-only"},q=["src","alt"],z={class:"ml-3"},G={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},I={key:1},J={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},K=["datetime"],O=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),tt=h({__name:"BlogPosts",props:{posts:{}},setup(g){const l=u("press");f({title:l.blog.config.blogTitle});function i(s){return s&&l.blog.authors.some(a=>a.name.toLowerCase()==s.toLowerCase())?`/posts/author/${C(s)}`:null}function c(s){return`/posts/${s.slug}`}function _(s){return s?l.blog.authors.find(a=>a.name.toLowerCase()==s.toLowerCase()):void 0}function x(s){var a;return(a=_(s))==null?void 0:a.profileUrl}return(s,a)=>{const m=p("RouterLink");return r(),n("div",$,[(r(!0),n(k,null,b(s.posts,e=>(r(),n("div",B,[t("div",j,[t("a",{href:c(e)},[t("img",{class:"h-48 w-full object-cover",src:e.image,alt:""},null,8,R)],8,H)]),t("div",F,[t("div",M,[N,t("a",{href:c(e),class:"mt-2 block"},[t("p",{class:"text-xl font-semibold text-gray-900 dark:text-gray-50 whitespace-nowrap overflow-hidden text-ellipsis",title:e.title},o(e.title),9,S),t("p",U,o(e.summary),1)],8,P)]),t("div",V,[t("div",A,[t("a",D,[t("span",E,o(e.author),1),t("img",{class:"h-10 w-10 rounded-full",src:x(e.author),alt:`${e.title} background`},null,8,q)])]),t("div",z,[t("p",G,[i(e.author)?(r(),w(m,{key:0,to:i(e.author),class:"hover:underline"},{default:y(()=>[v(o(e.author),1)]),_:2},1032,["to"])):(r(),n("span",I,o(e.author),1))]),t("div",J,[t("time",{datetime:d(L)(e.date)},o(d(T)(e.date)),9,K),O,t("span",null,o(e.minutesToRead)+" min read",1)])])])])]))),256))])}}}),Q={class:"text-center"},W={class:"text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},X=["innerHTML"],et=h({__name:"BlogTitle",props:{heading:{}},setup(g){const i=u("press").blog.config.blogTitle;return(c,_)=>(r(),n("div",Q,[t("h2",W,o(d(i)),1),t("p",{class:"mx-auto mt-3 max-w-2xl text-xl text-gray-500 dark:text-gray-400 sm:mt-4",innerHTML:c.heading},null,8,X)]))}});export{et as _,tt as a}; +import{d as h,x as u,i as f,r as p,o as r,c as n,F as k,g as b,a as t,t as o,h as w,w as y,e as v,u as d}from"./index-CoFPLbfm.js";import{d as L,a as T,g as C}from"./utils-BDrlE94o.js";const $={class:"mx-auto grid max-w-lg gap-5 lg:max-w-none lg:grid-cols-3"},B={class:"flex flex-col overflow-hidden rounded-lg shadow-lg"},j={class:"flex-shrink-0"},H=["href"],R=["src"],F={class:"flex flex-1 flex-col justify-between bg-white dark:bg-black p-6"},M={class:"flex-1"},N=t("p",{class:"text-sm font-medium text-indigo-600 dark:text-indigo-300"}," Article ",-1),P=["href"],S=["title"],U={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},V={class:"mt-6 flex items-center"},A={class:"flex-shrink-0"},D={href:""},E={class:"sr-only"},q=["src","alt"],z={class:"ml-3"},G={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},I={key:1},J={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},K=["datetime"],O=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),tt=h({__name:"BlogPosts",props:{posts:{}},setup(g){const l=u("press");f({title:l.blog.config.blogTitle});function i(s){return s&&l.blog.authors.some(a=>a.name.toLowerCase()==s.toLowerCase())?`/posts/author/${C(s)}`:null}function c(s){return`/posts/${s.slug}`}function _(s){return s?l.blog.authors.find(a=>a.name.toLowerCase()==s.toLowerCase()):void 0}function x(s){var a;return(a=_(s))==null?void 0:a.profileUrl}return(s,a)=>{const m=p("RouterLink");return r(),n("div",$,[(r(!0),n(k,null,b(s.posts,e=>(r(),n("div",B,[t("div",j,[t("a",{href:c(e)},[t("img",{class:"h-48 w-full object-cover",src:e.image,alt:""},null,8,R)],8,H)]),t("div",F,[t("div",M,[N,t("a",{href:c(e),class:"mt-2 block"},[t("p",{class:"text-xl font-semibold text-gray-900 dark:text-gray-50 whitespace-nowrap overflow-hidden text-ellipsis",title:e.title},o(e.title),9,S),t("p",U,o(e.summary),1)],8,P)]),t("div",V,[t("div",A,[t("a",D,[t("span",E,o(e.author),1),t("img",{class:"h-10 w-10 rounded-full",src:x(e.author),alt:`${e.title} background`},null,8,q)])]),t("div",z,[t("p",G,[i(e.author)?(r(),w(m,{key:0,to:i(e.author),class:"hover:underline"},{default:y(()=>[v(o(e.author),1)]),_:2},1032,["to"])):(r(),n("span",I,o(e.author),1))]),t("div",J,[t("time",{datetime:d(L)(e.date)},o(d(T)(e.date)),9,K),O,t("span",null,o(e.minutesToRead)+" min read",1)])])])])]))),256))])}}}),Q={class:"text-center"},W={class:"text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},X=["innerHTML"],et=h({__name:"BlogTitle",props:{heading:{}},setup(g){const i=u("press").blog.config.blogTitle;return(c,_)=>(r(),n("div",Q,[t("h2",W,o(d(i)),1),t("p",{class:"mx-auto mt-3 max-w-2xl text-xl text-gray-500 dark:text-gray-400 sm:mt-4",innerHTML:c.heading},null,8,X)]))}});export{et as _,tt as a}; diff --git a/assets/ChartJs-I6khMjFE.js b/assets/ChartJs-ljXEK9mH.js similarity index 84% rename from assets/ChartJs-I6khMjFE.js rename to assets/ChartJs-ljXEK9mH.js index 5ac31a0..ebd0adc 100644 --- a/assets/ChartJs-I6khMjFE.js +++ b/assets/ChartJs-ljXEK9mH.js @@ -1 +1 @@ -import{p as e,d as o,j as r,q as d,s}from"./index-B-kKBcPB.js";const p=e("https://cdn.jsdelivr.net/npm/chart.js/dist/chart.umd.min.js"),c=o({props:["type","data","options"],setup(t){const a=r();return d(async()=>{await p;const n=t.options||{responsive:!0,legend:{position:"top"}};new Chart(a.value,{type:t.type||"bar",data:t.data,options:n})}),()=>s("div",{},[s("canvas",{ref:a})])}});export{c as C}; +import{p as e,d as o,j as r,q as d,s}from"./index-CoFPLbfm.js";const p=e("https://cdn.jsdelivr.net/npm/chart.js/dist/chart.umd.min.js"),c=o({props:["type","data","options"],setup(t){const a=r();return d(async()=>{await p;const n=t.options||{responsive:!0,legend:{position:"top"}};new Chart(a.value,{type:t.type||"bar",data:t.data,options:n})}),()=>s("div",{},[s("canvas",{ref:a})])}});export{c as C}; diff --git a/assets/Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js b/assets/Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js similarity index 70% rename from assets/Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js rename to assets/Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js index cf2248f..f669bd6 100644 --- a/assets/Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js +++ b/assets/Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js @@ -1 +1 @@ -import{d as n,j as o,o as r,c as s,t as a}from"./index-B-kKBcPB.js";const _=n({__name:"Counter",setup(c){const e=o(1);return(p,t)=>(r(),s("b",{onClick:t[0]||(t[0]=u=>e.value++)},"Counter "+a(e.value),1))}});export{_}; +import{d as n,j as o,o as r,c as s,t as a}from"./index-CoFPLbfm.js";const _=n({__name:"Counter",setup(c){const e=o(1);return(p,t)=>(r(),s("b",{onClick:t[0]||(t[0]=u=>e.value++)},"Counter "+a(e.value),1))}});export{_}; diff --git a/assets/GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js b/assets/GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js similarity index 98% rename from assets/GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js rename to assets/GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js index 7d33985..376d4a9 100644 --- a/assets/GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js +++ b/assets/GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js @@ -1 +1 @@ -import{d as h,j as x,r as f,o as u,c as p,a as e,y as b,u as _,b as l,t as v,m as k,k as w,l as S,v as $,w as d,e as m,f as j}from"./index-B-kKBcPB.js";const C={class:"lang relative bg-gray-700 text-gray-300 pl-5 py-3 sm:rounded flex"},N=e("span",null,"$ ",-1),V={class:"cursor-pointer"},z=e("small",{class:"text-xs text-gray-400 px-3 -mt-1"},"sh",-1),T={key:0,class:"absolute right-0 -mr-28 -mt-3 rounded-md bg-green-50 p-3"},A={class:"flex"},B={class:"flex-shrink-0"},D={class:"ml-3"},I={class:"text-sm font-medium text-green-800"},R=h({__name:"ShellCommand",setup(g){let s=x("");function i(c){var a,r;let o=document.createElement("input"),t=c.target.parentElement.querySelector("label");if(o.setAttribute("value",t.innerText),document.body.appendChild(o),o.select(),document.execCommand("copy"),document.body.removeChild(o),typeof window.getSelection=="function"){const n=document.createRange();n.selectNodeContents(t),(a=window.getSelection())==null||a.removeAllRanges(),(r=window.getSelection())==null||r.addRange(n)}s.value="copied",setTimeout(()=>s.value="",3e3)}return(c,o)=>{const t=f("Iconify");return u(),p("div",C,[e("div",{class:"flex ml-2 w-full justify-between cursor-pointer",onClick:i},[e("div",null,[N,e("label",V,[b(c.$slots,"default")])]),z]),_(s)?(u(),p("div",T,[e("div",A,[e("div",B,[l(t,{icon:"mdi:check-circle",class:"h-5 w-5 text-green-400"})]),e("div",D,[e("p",I,v(_(s)),1)])])])):k("",!0)])}}}),E={class:"flex flex-col w-96"},M=e("h4",{class:"py-6 text-center text-xl"},"Download New Project",-1),P={class:"w-full flex justify-center text-center"},U={class:"mb-2"},q={class:"flex justify-center text-center"},G=["href"],K={class:"bg-white dark:bg-gray-800 px-4 py-4 mr-4 mb-4 rounded-lg shadow-lg text-center items-center justify-center hover:shadow-2xl dark:border-2 dark:border-pink-600 dark:hover:border-blue-600",style:{"min-width":"150px"}},O={class:"text-center font-extrabold flex items-center justify-center mb-2"},W={class:"text-4xl text-blue-400 my-3"},Z=e("div",{class:"text-xl font-medium text-gray-700 dark:text-gray-300"},"Press Vue",-1),F=e("div",{class:"flex justify-center h-8"},null,-1),H={class:"archive-name px-4 pb-2 text-blue-600 dark:text-indigo-400"},J=e("div",{class:"count mt-1 text-gray-400 text-sm"},null,-1),L=e("h4",{class:"pb-4 text-center text-xl"},"or",-1),Q=j('

or

Open in StackBlitz

Run

',3),Y=h({__name:"GettingStarted",props:{template:{}},setup(g){const s=x("ProjectName"),i=w(()=>(s.value||"MyApp")+".zip"),c=t=>`https://account.servicestack.net/archive/${t}?Name=${s.value||"MyApp"}`;function o(t){if(t.key.match(/[\W]+/g))return t.preventDefault(),!1}return(t,a)=>{const r=f("Iconify"),n=R;return u(),p("div",E,[M,S(e("input",{type:"text","onUpdate:modelValue":a[0]||(a[0]=y=>s.value=y),autocomplete:"off",spellcheck:"false",onKeydown:o,class:"mb-8 sm:text-lg rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 border-gray-300 dark:bg-gray-800"},null,544),[[$,s.value]]),e("section",P,[e("div",U,[e("div",q,[e("a",{class:"hover:no-underline",href:c(`ServiceStack/${t.template}`)},[e("div",K,[e("div",O,[e("div",W,[l(r,{icon:"logos:vue",class:"w-12 h-12"})])]),Z,F,e("span",H,v(i.value),1),J])],8,G)])])]),L,l(n,{class:"mb-2"},{default:d(()=>[m("npx degit ServiceStack/press-vue")]),_:1}),Q,l(n,{class:"mb-2"},{default:d(()=>[m("npm install")]),_:1}),l(n,{class:"mb-2"},{default:d(()=>[m("npm run dev")]),_:1})])}}});export{Y as _}; +import{d as h,j as x,r as f,o as u,c as p,a as e,y as b,u as _,b as l,t as v,m as k,k as w,l as S,v as $,w as d,e as m,f as j}from"./index-CoFPLbfm.js";const C={class:"lang relative bg-gray-700 text-gray-300 pl-5 py-3 sm:rounded flex"},N=e("span",null,"$ ",-1),V={class:"cursor-pointer"},z=e("small",{class:"text-xs text-gray-400 px-3 -mt-1"},"sh",-1),T={key:0,class:"absolute right-0 -mr-28 -mt-3 rounded-md bg-green-50 p-3"},A={class:"flex"},B={class:"flex-shrink-0"},D={class:"ml-3"},I={class:"text-sm font-medium text-green-800"},R=h({__name:"ShellCommand",setup(g){let s=x("");function i(c){var a,r;let o=document.createElement("input"),t=c.target.parentElement.querySelector("label");if(o.setAttribute("value",t.innerText),document.body.appendChild(o),o.select(),document.execCommand("copy"),document.body.removeChild(o),typeof window.getSelection=="function"){const n=document.createRange();n.selectNodeContents(t),(a=window.getSelection())==null||a.removeAllRanges(),(r=window.getSelection())==null||r.addRange(n)}s.value="copied",setTimeout(()=>s.value="",3e3)}return(c,o)=>{const t=f("Iconify");return u(),p("div",C,[e("div",{class:"flex ml-2 w-full justify-between cursor-pointer",onClick:i},[e("div",null,[N,e("label",V,[b(c.$slots,"default")])]),z]),_(s)?(u(),p("div",T,[e("div",A,[e("div",B,[l(t,{icon:"mdi:check-circle",class:"h-5 w-5 text-green-400"})]),e("div",D,[e("p",I,v(_(s)),1)])])])):k("",!0)])}}}),E={class:"flex flex-col w-96"},M=e("h4",{class:"py-6 text-center text-xl"},"Download New Project",-1),P={class:"w-full flex justify-center text-center"},U={class:"mb-2"},q={class:"flex justify-center text-center"},G=["href"],K={class:"bg-white dark:bg-gray-800 px-4 py-4 mr-4 mb-4 rounded-lg shadow-lg text-center items-center justify-center hover:shadow-2xl dark:border-2 dark:border-pink-600 dark:hover:border-blue-600",style:{"min-width":"150px"}},O={class:"text-center font-extrabold flex items-center justify-center mb-2"},W={class:"text-4xl text-blue-400 my-3"},Z=e("div",{class:"text-xl font-medium text-gray-700 dark:text-gray-300"},"Press Vue",-1),F=e("div",{class:"flex justify-center h-8"},null,-1),H={class:"archive-name px-4 pb-2 text-blue-600 dark:text-indigo-400"},J=e("div",{class:"count mt-1 text-gray-400 text-sm"},null,-1),L=e("h4",{class:"pb-4 text-center text-xl"},"or",-1),Q=j('

or

Open in StackBlitz

Run

',3),Y=h({__name:"GettingStarted",props:{template:{}},setup(g){const s=x("ProjectName"),i=w(()=>(s.value||"MyApp")+".zip"),c=t=>`https://account.servicestack.net/archive/${t}?Name=${s.value||"MyApp"}`;function o(t){if(t.key.match(/[\W]+/g))return t.preventDefault(),!1}return(t,a)=>{const r=f("Iconify"),n=R;return u(),p("div",E,[M,S(e("input",{type:"text","onUpdate:modelValue":a[0]||(a[0]=y=>s.value=y),autocomplete:"off",spellcheck:"false",onKeydown:o,class:"mb-8 sm:text-lg rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 border-gray-300 dark:bg-gray-800"},null,544),[[$,s.value]]),e("section",P,[e("div",U,[e("div",q,[e("a",{class:"hover:no-underline",href:c(`ServiceStack/${t.template}`)},[e("div",K,[e("div",O,[e("div",W,[l(r,{icon:"logos:vue",class:"w-12 h-12"})])]),Z,F,e("span",H,v(i.value),1),J])],8,G)])])]),L,l(n,{class:"mb-2"},{default:d(()=>[m("npx degit ServiceStack/press-vue")]),_:1}),Q,l(n,{class:"mb-2"},{default:d(()=>[m("npm install")]),_:1}),l(n,{class:"mb-2"},{default:d(()=>[m("npm run dev")]),_:1})])}}});export{Y as _}; diff --git a/assets/HelloApi.vue_vue_type_script_setup_true_lang-BNRlbX2m.js b/assets/HelloApi.vue_vue_type_script_setup_true_lang-DrkDEcx3.js similarity index 95% rename from assets/HelloApi.vue_vue_type_script_setup_true_lang-BNRlbX2m.js rename to assets/HelloApi.vue_vue_type_script_setup_true_lang-DrkDEcx3.js index fd84e63..571bd18 100644 --- a/assets/HelloApi.vue_vue_type_script_setup_true_lang-BNRlbX2m.js +++ b/assets/HelloApi.vue_vue_type_script_setup_true_lang-DrkDEcx3.js @@ -1 +1 @@ -var w=Object.defineProperty;var h=(t,e,s)=>e in t?w(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s;var l=(t,e,s)=>(h(t,typeof e!="symbol"?e+"":e,s),s);import{d as i,o as r,c as m,t as v,j as u,r as p,b as f,w as d,e as k,h as H,m as V,a as g,J as b}from"./index-B-kKBcPB.js";const M=i({__name:"Hello",props:{name:{}},setup(t){return(e,s)=>(r(),m("b",null,"Hello, "+v(e.name)+"!",1))}}),B=g("div",{class:"p-8"},"Hello @servicestack/vue!",-1),O=i({__name:"Plugin",setup(t){const e=u(!1);return(s,n)=>{const c=p("PrimaryButton"),a=p("ModalDialog");return r(),m("div",null,[f(c,{onClick:n[0]||(n[0]=o=>e.value=!0)},{default:d(()=>[k("Open Modal")]),_:1}),e.value?(r(),H(a,{key:0,onDone:n[1]||(n[1]=o=>e.value=!1)},{default:d(()=>[B]),_:1})):V("",!0)])}}});class C{constructor(e){l(this,"result");l(this,"responseStatus");Object.assign(this,e)}}class j{constructor(e){l(this,"name");Object.assign(this,e)}getTypeName(){return"Hello"}getMethod(){return"GET"}createResponse(){return new C}}const N={class:"flex flex-wrap justify-center"},T={class:"ml-3 mt-2 text-lg"},P=i({__name:"HelloApi",props:{value:{}},setup(t){const s=u(t.value),n=u(""),c=new b("https://blazor-gallery.jamstacks.net");async function a(){let o=await c.api(new j({name:s.value}));o.succeeded&&(n.value=o.response.result)}return a(),(o,_)=>{const x=p("TextInput");return r(),m("div",N,[f(x,{modelValue:s.value,"onUpdate:modelValue":_[0]||(_[0]=y=>s.value=y),onKeyup:a},null,8,["modelValue"]),g("div",T,v(n.value),1)])}}});export{M as _,O as a,P as b}; +var w=Object.defineProperty;var h=(t,e,s)=>e in t?w(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s;var l=(t,e,s)=>(h(t,typeof e!="symbol"?e+"":e,s),s);import{d as i,o as r,c as m,t as v,j as u,r as p,b as f,w as d,e as k,h as H,m as V,a as g,J as b}from"./index-CoFPLbfm.js";const M=i({__name:"Hello",props:{name:{}},setup(t){return(e,s)=>(r(),m("b",null,"Hello, "+v(e.name)+"!",1))}}),B=g("div",{class:"p-8"},"Hello @servicestack/vue!",-1),O=i({__name:"Plugin",setup(t){const e=u(!1);return(s,n)=>{const c=p("PrimaryButton"),a=p("ModalDialog");return r(),m("div",null,[f(c,{onClick:n[0]||(n[0]=o=>e.value=!0)},{default:d(()=>[k("Open Modal")]),_:1}),e.value?(r(),H(a,{key:0,onDone:n[1]||(n[1]=o=>e.value=!1)},{default:d(()=>[B]),_:1})):V("",!0)])}}});class C{constructor(e){l(this,"result");l(this,"responseStatus");Object.assign(this,e)}}class j{constructor(e){l(this,"name");Object.assign(this,e)}getTypeName(){return"Hello"}getMethod(){return"GET"}createResponse(){return new C}}const N={class:"flex flex-wrap justify-center"},T={class:"ml-3 mt-2 text-lg"},P=i({__name:"HelloApi",props:{value:{}},setup(t){const s=u(t.value),n=u(""),c=new b("https://blazor-gallery.jamstacks.net");async function a(){let o=await c.api(new j({name:s.value}));o.succeeded&&(n.value=o.response.result)}return a(),(o,_)=>{const x=p("TextInput");return r(),m("div",N,[f(x,{modelValue:s.value,"onUpdate:modelValue":_[0]||(_[0]=y=>s.value=y),onKeyup:a},null,8,["modelValue"]),g("div",T,v(n.value),1)])}}});export{M as _,O as a,P as b}; diff --git a/assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js b/assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js similarity index 88% rename from assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js rename to assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js index 5f803ef..802add5 100644 --- a/assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js +++ b/assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js @@ -1 +1 @@ -import{d as u,x as l,u as c,o as s,h as m,D as d,c as p,E as i}from"./index-B-kKBcPB.js";const k=["innerHTML"],y=["innerHTML"],M=u({__name:"MarkdownComponent",props:{doc:{},type:{},group:{}},setup(a){const n=a,o=l("press").components[n.type]||{},r=n.group?o[n.group]&&o[n.group][n.doc.slug]:o[n.doc.slug],t=r?i(r):null;return(e,g)=>c(t)?(s(),m(d(c(t)),{key:0,name:e.doc.slug,frontmatter:{nowrap:!0}},null,8,["name"])):e.doc.preview?(s(),p("div",{key:1,innerHTML:e.doc.preview},null,8,k)):(s(),p("pre",{key:2,innerHTML:e.doc.content},null,8,y))}});export{M as _}; +import{d as u,x as l,u as c,o as s,h as m,D as d,c as p,E as i}from"./index-CoFPLbfm.js";const k=["innerHTML"],y=["innerHTML"],M=u({__name:"MarkdownComponent",props:{doc:{},type:{},group:{}},setup(a){const n=a,o=l("press").components[n.type]||{},r=n.group?o[n.group]&&o[n.group][n.doc.slug]:o[n.doc.slug],t=r?i(r):null;return(e,g)=>c(t)?(s(),m(d(c(t)),{key:0,name:e.doc.slug,frontmatter:{nowrap:!0}},null,8,["name"])):e.doc.preview?(s(),p("div",{key:1,innerHTML:e.doc.preview},null,8,k)):(s(),p("pre",{key:2,innerHTML:e.doc.content},null,8,y))}});export{M as _}; diff --git a/assets/MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js b/assets/MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js similarity index 78% rename from assets/MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js rename to assets/MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js index 08a0643..c3f45d2 100644 --- a/assets/MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js +++ b/assets/MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js @@ -1 +1 @@ -import{d as r,o,c as s,y as a,a as e,t as n}from"./index-B-kKBcPB.js";const l={key:0},i={key:1,class:"prose dark:prose-invert lg:prose-xl text-left mt-8 mb-20 mx-auto max-w-fit"},m={class:"mb-4 text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},c={class:"max-w-3xl mx-auto"},d={class:"max-w-none mb-32"},f=r({__name:"MarkdownPage",props:{frontmatter:{}},setup(_){return(t,p)=>t.frontmatter.nowrap?(o(),s("article",l,[a(t.$slots,"default")])):(o(),s("div",i,[e("h1",m,n(t.frontmatter.title),1),e("div",c,[e("article",d,[a(t.$slots,"default")])])]))}});export{f as _}; +import{d as r,o,c as s,y as a,a as e,t as n}from"./index-CoFPLbfm.js";const l={key:0},i={key:1,class:"prose dark:prose-invert lg:prose-xl text-left mt-8 mb-20 mx-auto max-w-fit"},m={class:"mb-4 text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},c={class:"max-w-3xl mx-auto"},d={class:"max-w-none mb-32"},f=r({__name:"MarkdownPage",props:{frontmatter:{}},setup(_){return(t,p)=>t.frontmatter.nowrap?(o(),s("article",l,[a(t.$slots,"default")])):(o(),s("div",i,[e("h1",m,n(t.frontmatter.title),1),e("div",c,[e("article",d,[a(t.$slots,"default")])])]))}});export{f as _}; diff --git a/assets/SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js b/assets/SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js similarity index 93% rename from assets/SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js rename to assets/SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js index 66e7dcb..e67da8d 100644 --- a/assets/SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js +++ b/assets/SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js @@ -1 +1 @@ -import{d as h,B as f,k as _,C as p,o as r,c,a as m,e as i,t as l,u as a,y as u,r as d,h as g,w as y,b as S}from"./index-B-kKBcPB.js";const k=["href"],x=["src"],v=["href"],b="https://github.com/ServiceStack/press-vue/blob/main",B=h({__name:"SrcLink",props:{href:{},iconSrc:{}},setup(n){const e=n,o=f(e.href,"/"),s=_(()=>e.href.includes("://")?e.href:p(b,e.href));return(t,w)=>t.iconSrc?(r(),c("a",{key:0,href:s.value,class:"mr-3 text-gray-500 hover:text-gray-600 text-decoration-none"},[m("img",{src:t.iconSrc,class:"w-5 h-5 inline-flex text-purple-800 mr-1",alt:"file icon"},null,8,x),i(l(a(o)),1)],8,k)):(r(),c("a",{key:1,href:s.value,class:"mr-3 text-gray-400 hover:text-gray-500 text-decoration-none"},[u(t.$slots,"default"),i(" "+l(a(o)),1)],8,v))}}),N=h({__name:"SrcPage",props:{path:{}},setup(n){return(e,o)=>{const s=d("Iconify"),t=B;return r(),g(t,{href:a(p)("/src/pages",e.path)},{default:y(()=>[S(s,{icon:"logos:vue",class:"w-5 h-5 inline"})]),_:1},8,["href"])}}});export{N as _}; +import{d as h,B as f,k as _,C as p,o as r,c,a as m,e as i,t as l,u as a,y as u,r as d,h as g,w as y,b as S}from"./index-CoFPLbfm.js";const k=["href"],x=["src"],v=["href"],b="https://github.com/ServiceStack/press-vue/blob/main",B=h({__name:"SrcLink",props:{href:{},iconSrc:{}},setup(n){const e=n,o=f(e.href,"/"),s=_(()=>e.href.includes("://")?e.href:p(b,e.href));return(t,w)=>t.iconSrc?(r(),c("a",{key:0,href:s.value,class:"mr-3 text-gray-500 hover:text-gray-600 text-decoration-none"},[m("img",{src:t.iconSrc,class:"w-5 h-5 inline-flex text-purple-800 mr-1",alt:"file icon"},null,8,x),i(l(a(o)),1)],8,k)):(r(),c("a",{key:1,href:s.value,class:"mr-3 text-gray-400 hover:text-gray-500 text-decoration-none"},[u(t.$slots,"default"),i(" "+l(a(o)),1)],8,v))}}),N=h({__name:"SrcPage",props:{path:{}},setup(n){return(e,o)=>{const s=d("Iconify"),t=B;return r(),g(t,{href:a(p)("/src/pages",e.path)},{default:y(()=>[S(s,{icon:"logos:vue",class:"w-5 h-5 inline"})]),_:1},8,["href"])}}});export{N as _}; diff --git a/assets/Templates.vue_vue_type_script_setup_true_lang-DajVBfQg.js b/assets/Templates.vue_vue_type_script_setup_true_lang-8Ivl7FzK.js similarity index 99% rename from assets/Templates.vue_vue_type_script_setup_true_lang-DajVBfQg.js rename to assets/Templates.vue_vue_type_script_setup_true_lang-8Ivl7FzK.js index b8ae97f..ea3d5c5 100644 --- a/assets/Templates.vue_vue_type_script_setup_true_lang-DajVBfQg.js +++ b/assets/Templates.vue_vue_type_script_setup_true_lang-8Ivl7FzK.js @@ -1 +1 @@ -import{d as b,j as f,k as _,o as c,c as i,a as e,l as k,v as z,F as p,g,n as y,t as n,m as M}from"./index-B-kKBcPB.js";const v={ServiceStack:'',Blazor:'',Razor:'',Windows:'',Vue:'',Nextjs:'',React:'',Angular:'',Svelte:''};function t(l,o,d,h=[],u){return{repo:l,name:o,icon:d,tags:h??[],demo:u??`${l}.web-templates.io`}}const F=[t("blazor","Blazor","Blazor",["tailwind"]),t("blazor-vue","Blazor Vue","Blazor",["tailwind"]),t("mvc","MVC","Windows",["tailwind"]),t("razor","Razor Pages","Razor",["tailwind"]),t("mvc-bootstrap","MVC","Windows",["bootstrap"]),t("razor-bootstrap","Razor Pages","Razor",["bootstrap"]),t("vue-mjs","Razor Pages","Razor",["tailwind","autoquery"]),t("nextjs","Next.js","Nextjs",["tailwind","autoquery"]),t("vue-vite","Vue Vite","Vue",["tailwind","autoquery"]),t("vue-ssg","Vue SSG","Vue",["tailwind","autoquery"]),t("razor-pages","Razor Pages","Razor",["bootstrap"]),t("mvcauth","MVC","Windows",["bootstrap"]),t("script","MVC","Windows",["bootstrap"]),t("vue-spa","Vue SPA","Vue",["bootstrap"]),t("react-spa","React SPA","React",["bootstrap"]),t("angular-spa","Angular SPA","Angular",["bootstrap"]),t("svelte-spa","Svelte SPA","Angular",["bootstrap"])].reduce((l,o)=>(l[o.repo]=o,l),{}),V={class:"w-full flex flex-col justify-center text-center"},C={id:"empty",class:"mt-4 mb-2"},L={class:"flex justify-center mb-8"},B={class:"w-70"},j={class:"mb-2"},A={class:"flex justify-center text-center"},S=["href"],R={class:"bg-white dark:bg-gray-800 px-4 py-4 mr-4 mb-4 rounded-lg shadow-lg text-center items-center justify-center hover:shadow-2xl dark:border-2 dark:border-pink-600 dark:hover:border-blue-600 dark:border-2 dark:border-pink-600 dark:hover:border-blue-600",style:{"min-width":"150px"}},q={class:"text-center font-extrabold flex items-center justify-center mb-2"},H=["innerHTML"],N={class:"text-xl font-medium text-gray-700"},P={class:"flex justify-center h-8"},Z={class:"mr-1"},T={class:"px-2 h-8 rounded-lg bg-blue-50 dark:bg-blue-900 text-blue-500 dark:text-blue-400 text-sm"},W={class:"archive-name px-4 pb-2 text-blue-600 dark:text-indigo-400"},I=e("div",{class:"count mt-1 text-gray-400 text-sm"},null,-1),D=["href"],U=b({__name:"Templates",props:{templates:{},hide:{}},setup(l){const o=f("MyApp"),d=_(()=>(o.value||"MyApp")+".zip"),h=a=>`https://account.servicestack.net/archive/${a}?Name=${o.value||"MyApp"}`,u=a=>{const s=a.charCode;s>=65&&s<=90||s>=97&&s<=122||s>=48&&s<=57||s===95||a.preventDefault()},w=v,m=a=>w[a]??v.ServiceStack;return(a,s)=>(c(),i("div",null,[e("section",V,[e("div",C,[e("div",L,[e("div",B,[k(e("input",{"onUpdate:modelValue":s[0]||(s[0]=r=>o.value=r),type:"text",placeholder:"Project Name",autocorrect:"off",spellcheck:"false",onKeypress:u,class:"mt-1 text-lg block w-full px-3 py-2 bg-white dark:bg-black border border-slate-300 dark:border-slate-700 rounded-md text-sm shadow-sm placeholder-slate-400 focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500"},null,544),[[z,o.value]])])])])]),e("section",{class:y(["w-full flex grid gap-4 text-center",a.templates.length===1?"grid-cols-1":a.templates.length===2?"grid-cols-2 max-w-md mx-auto":"grid-cols-3"])},[(c(!0),i(p,null,g(a.templates,r=>(c(),i("div",j,[e("div",A,[e("a",{class:"archive-url hover:no-underline",href:h("NetCoreTemplates/"+r.repo)},[e("div",R,[e("div",q,[e("div",{class:"text-4xl text-blue-400 my-3",innerHTML:m(r.icon)},null,8,H)]),e("div",N,n(r.name),1),e("div",P,[(c(!0),i(p,null,g(r.tags,x=>(c(),i("div",Z,[e("span",T,n(x),1)]))),256))]),e("span",W,n(d.value),1),I])],8,S)]),r.demo&&a.hide!=="demo"?(c(),i("a",{key:0,href:"https://"+r.demo},n(r.demo),9,D)):M("",!0)]))),256))],2)]))}});export{F as I,U as _}; +import{d as b,j as f,k as _,o as c,c as i,a as e,l as k,v as z,F as p,g,n as y,t as n,m as M}from"./index-CoFPLbfm.js";const v={ServiceStack:'',Blazor:'',Razor:'',Windows:'',Vue:'',Nextjs:'',React:'',Angular:'',Svelte:''};function t(l,o,d,h=[],u){return{repo:l,name:o,icon:d,tags:h??[],demo:u??`${l}.web-templates.io`}}const F=[t("blazor","Blazor","Blazor",["tailwind"]),t("blazor-vue","Blazor Vue","Blazor",["tailwind"]),t("mvc","MVC","Windows",["tailwind"]),t("razor","Razor Pages","Razor",["tailwind"]),t("mvc-bootstrap","MVC","Windows",["bootstrap"]),t("razor-bootstrap","Razor Pages","Razor",["bootstrap"]),t("vue-mjs","Razor Pages","Razor",["tailwind","autoquery"]),t("nextjs","Next.js","Nextjs",["tailwind","autoquery"]),t("vue-vite","Vue Vite","Vue",["tailwind","autoquery"]),t("vue-ssg","Vue SSG","Vue",["tailwind","autoquery"]),t("razor-pages","Razor Pages","Razor",["bootstrap"]),t("mvcauth","MVC","Windows",["bootstrap"]),t("script","MVC","Windows",["bootstrap"]),t("vue-spa","Vue SPA","Vue",["bootstrap"]),t("react-spa","React SPA","React",["bootstrap"]),t("angular-spa","Angular SPA","Angular",["bootstrap"]),t("svelte-spa","Svelte SPA","Angular",["bootstrap"])].reduce((l,o)=>(l[o.repo]=o,l),{}),V={class:"w-full flex flex-col justify-center text-center"},C={id:"empty",class:"mt-4 mb-2"},L={class:"flex justify-center mb-8"},B={class:"w-70"},j={class:"mb-2"},A={class:"flex justify-center text-center"},S=["href"],R={class:"bg-white dark:bg-gray-800 px-4 py-4 mr-4 mb-4 rounded-lg shadow-lg text-center items-center justify-center hover:shadow-2xl dark:border-2 dark:border-pink-600 dark:hover:border-blue-600 dark:border-2 dark:border-pink-600 dark:hover:border-blue-600",style:{"min-width":"150px"}},q={class:"text-center font-extrabold flex items-center justify-center mb-2"},H=["innerHTML"],N={class:"text-xl font-medium text-gray-700"},P={class:"flex justify-center h-8"},Z={class:"mr-1"},T={class:"px-2 h-8 rounded-lg bg-blue-50 dark:bg-blue-900 text-blue-500 dark:text-blue-400 text-sm"},W={class:"archive-name px-4 pb-2 text-blue-600 dark:text-indigo-400"},I=e("div",{class:"count mt-1 text-gray-400 text-sm"},null,-1),D=["href"],U=b({__name:"Templates",props:{templates:{},hide:{}},setup(l){const o=f("MyApp"),d=_(()=>(o.value||"MyApp")+".zip"),h=a=>`https://account.servicestack.net/archive/${a}?Name=${o.value||"MyApp"}`,u=a=>{const s=a.charCode;s>=65&&s<=90||s>=97&&s<=122||s>=48&&s<=57||s===95||a.preventDefault()},w=v,m=a=>w[a]??v.ServiceStack;return(a,s)=>(c(),i("div",null,[e("section",V,[e("div",C,[e("div",L,[e("div",B,[k(e("input",{"onUpdate:modelValue":s[0]||(s[0]=r=>o.value=r),type:"text",placeholder:"Project Name",autocorrect:"off",spellcheck:"false",onKeypress:u,class:"mt-1 text-lg block w-full px-3 py-2 bg-white dark:bg-black border border-slate-300 dark:border-slate-700 rounded-md text-sm shadow-sm placeholder-slate-400 focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500"},null,544),[[z,o.value]])])])])]),e("section",{class:y(["w-full flex grid gap-4 text-center",a.templates.length===1?"grid-cols-1":a.templates.length===2?"grid-cols-2 max-w-md mx-auto":"grid-cols-3"])},[(c(!0),i(p,null,g(a.templates,r=>(c(),i("div",j,[e("div",A,[e("a",{class:"archive-url hover:no-underline",href:h("NetCoreTemplates/"+r.repo)},[e("div",R,[e("div",q,[e("div",{class:"text-4xl text-blue-400 my-3",innerHTML:m(r.icon)},null,8,H)]),e("div",N,n(r.name),1),e("div",P,[(c(!0),i(p,null,g(r.tags,x=>(c(),i("div",Z,[e("span",T,n(x),1)]))),256))]),e("span",W,n(d.value),1),I])],8,S)]),r.demo&&a.hide!=="demo"?(c(),i("a",{key:0,href:"https://"+r.demo},n(r.demo),9,D)):M("",!0)]))),256))],2)]))}});export{F as I,U as _}; diff --git a/assets/VideoGroup.vue_vue_type_script_setup_true_lang-yt9KRqcL.js b/assets/VideoGroup.vue_vue_type_script_setup_true_lang-Cko02hll.js similarity index 94% rename from assets/VideoGroup.vue_vue_type_script_setup_true_lang-yt9KRqcL.js rename to assets/VideoGroup.vue_vue_type_script_setup_true_lang-Cko02hll.js index 7d6e644..60e6692 100644 --- a/assets/VideoGroup.vue_vue_type_script_setup_true_lang-yt9KRqcL.js +++ b/assets/VideoGroup.vue_vue_type_script_setup_true_lang-Cko02hll.js @@ -1 +1 @@ -import{_ as y}from"./MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js";import{d as f,x as k,k as v,r as b,o as a,c as r,a as t,t as o,e as n,m as w,F as l,g as i,b as d,n as L,B as V}from"./index-B-kKBcPB.js";const B={class:"mx-auto max-w-7xl px-6 lg:px-8"},C={class:"mx-auto max-w-5xl"},N={class:"text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},D={class:"mt-2 text-lg leading-8 text-gray-600 dark:text-gray-400"},F=["href"],M=t("span",{"aria-hidden":"true"},"→",-1),S={class:"mt-16 space-y-20 lg:mt-20 lg:space-y-20"},T={class:"relative isolate flex flex-col gap-8 lg:flex-row"},z={class:"relative lg:w-1/2 lg:shrink-0"},Y={class:"flex items-center gap-x-4 text-xs"},j={datetime:"2020-03-16",class:"text-gray-500 dark:text-gray-400"},E={class:"relative z-10 rounded-full bg-gray-50 dark:bg-gray-800 py-1.5 px-3 font-medium text-gray-600 dark:text-gray-300"},G={class:"group relative max-w-xl"},I={class:"mt-3 text-lg font-semibold leading-6 text-gray-900 dark:text-gray-50 group-hover:text-gray-600 dark:group-hover:text-gray-400"},P=["href"],R={class:"mt-5 text-sm leading-6 text-gray-600 dark:text-gray-400"},U={class:"prose dark:prose-invert"},H=f({__name:"VideoGroup",props:{group:{},title:{},background:{},summary:{},border:{},learnMore:{}},setup(c){const g=c;function m(e){return V(e,"/")}function u(e){return new Date(e).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}const p=k("press"),_=v(()=>p.videos[g.group]);return(e,$)=>{const x=b("LiteYouTube");return a(),r("div",{class:L([e.background,"py-24 sm:py-32"])},[t("div",B,[t("div",C,[t("h2",N,o(e.title),1),t("p",D,[n(o(e.summary)+" ",1),e.learnMore?(a(),r("a",{key:0,href:e.learnMore,class:"ml-2 text-sm font-semibold leading-6"},[n("Learn more "),M],8,F)):w("",!0)]),t("div",S,[(a(!0),r(l,null,i(_.value,s=>(a(),r("article",T,[t("div",z,[d(x,{id:m(s.url),title:s.title},null,8,["id","title"])]),t("div",null,[t("div",Y,[t("time",j,o(u(s.date)),1),(a(!0),r(l,null,i(s.tags,h=>(a(),r("span",E,o(h),1))),256))]),t("div",G,[t("h3",I,[t("a",{href:s.url},o(s.title),9,P)]),t("div",R,[t("div",U,[d(y,{type:"videos",doc:s,group:e.group},null,8,["doc","group"])])])])])]))),256))])])])],2)}}});export{H as _}; +import{_ as y}from"./MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js";import{d as f,x as k,k as v,r as b,o as a,c as r,a as t,t as o,e as n,m as w,F as l,g as i,b as d,n as L,B as V}from"./index-CoFPLbfm.js";const B={class:"mx-auto max-w-7xl px-6 lg:px-8"},C={class:"mx-auto max-w-5xl"},N={class:"text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},D={class:"mt-2 text-lg leading-8 text-gray-600 dark:text-gray-400"},F=["href"],M=t("span",{"aria-hidden":"true"},"→",-1),S={class:"mt-16 space-y-20 lg:mt-20 lg:space-y-20"},T={class:"relative isolate flex flex-col gap-8 lg:flex-row"},z={class:"relative lg:w-1/2 lg:shrink-0"},Y={class:"flex items-center gap-x-4 text-xs"},j={datetime:"2020-03-16",class:"text-gray-500 dark:text-gray-400"},E={class:"relative z-10 rounded-full bg-gray-50 dark:bg-gray-800 py-1.5 px-3 font-medium text-gray-600 dark:text-gray-300"},G={class:"group relative max-w-xl"},I={class:"mt-3 text-lg font-semibold leading-6 text-gray-900 dark:text-gray-50 group-hover:text-gray-600 dark:group-hover:text-gray-400"},P=["href"],R={class:"mt-5 text-sm leading-6 text-gray-600 dark:text-gray-400"},U={class:"prose dark:prose-invert"},H=f({__name:"VideoGroup",props:{group:{},title:{},background:{},summary:{},border:{},learnMore:{}},setup(c){const g=c;function m(e){return V(e,"/")}function u(e){return new Date(e).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}const p=k("press"),_=v(()=>p.videos[g.group]);return(e,$)=>{const x=b("LiteYouTube");return a(),r("div",{class:L([e.background,"py-24 sm:py-32"])},[t("div",B,[t("div",C,[t("h2",N,o(e.title),1),t("p",D,[n(o(e.summary)+" ",1),e.learnMore?(a(),r("a",{key:0,href:e.learnMore,class:"ml-2 text-sm font-semibold leading-6"},[n("Learn more "),M],8,F)):w("",!0)]),t("div",S,[(a(!0),r(l,null,i(_.value,s=>(a(),r("article",T,[t("div",z,[d(x,{id:m(s.url),title:s.title},null,8,["id","title"])]),t("div",null,[t("div",Y,[t("time",j,o(u(s.date)),1),(a(!0),r(l,null,i(s.tags,h=>(a(),r("span",E,o(h),1))),256))]),t("div",G,[t("h3",I,[t("a",{href:s.url},o(s.title),9,P)]),t("div",R,[t("div",U,[d(y,{type:"videos",doc:s,group:e.group},null,8,["doc","group"])])])])])]))),256))])])])],2)}}});export{H as _}; diff --git a/assets/_...all_-ByINYo4N.js b/assets/_...all_-DOrRbYkV.js similarity index 92% rename from assets/_...all_-ByINYo4N.js rename to assets/_...all_-DOrRbYkV.js index 8c5e868..1124933 100644 --- a/assets/_...all_-ByINYo4N.js +++ b/assets/_...all_-DOrRbYkV.js @@ -1 +1 @@ -import{d as r,z as c,r as a,o as i,c as l,a as e,u as f,b as d,e as u}from"./index-B-kKBcPB.js";const m=e("div",{class:"flex items-center"},[e("h1",{class:"inline-block border-gray-300 border-r m-0 mr-5 py-2 pr-4 text-2xl font-medium"},"404"),e("div",{class:"inline-block text-left"},[e("h2",{class:"text-sm font-normal"},"This page does not exist.")])],-1),p={class:"mt-2"},x=r({__name:"[...all]",setup(_){const s=c();return(b,o)=>{const n=a("Iconify");return i(),l("div",null,[m,e("div",p,[e("button",{onClick:o[0]||(o[0]=y=>f(s).back()),class:"inline-flex justify-center py-1 px-2 shadow rounded-sm text-sm hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"},[d(n,{icon:"mdi:arrow-left-thin",class:"w-5 h-5"}),u(" back ")])])])}}}),t={};typeof t=="function"&&t(x);export{x as default}; +import{d as r,z as c,r as a,o as i,c as l,a as e,u as f,b as d,e as u}from"./index-CoFPLbfm.js";const m=e("div",{class:"flex items-center"},[e("h1",{class:"inline-block border-gray-300 border-r m-0 mr-5 py-2 pr-4 text-2xl font-medium"},"404"),e("div",{class:"inline-block text-left"},[e("h2",{class:"text-sm font-normal"},"This page does not exist.")])],-1),p={class:"mt-2"},x=r({__name:"[...all]",setup(_){const s=c();return(b,o)=>{const n=a("Iconify");return i(),l("div",null,[m,e("div",p,[e("button",{onClick:o[0]||(o[0]=y=>f(s).back()),class:"inline-flex justify-center py-1 px-2 shadow rounded-sm text-sm hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"},[d(n,{icon:"mdi:arrow-left-thin",class:"w-5 h-5"}),u(" back ")])])])}}}),t={};typeof t=="function"&&t(x);export{x as default}; diff --git a/assets/_name_-D0WdA550.js b/assets/_name_-D5H8wJy-.js similarity index 90% rename from assets/_name_-D0WdA550.js rename to assets/_name_-D5H8wJy-.js index a76015b..c016956 100644 --- a/assets/_name_-D0WdA550.js +++ b/assets/_name_-D5H8wJy-.js @@ -1 +1 @@ -import{_ as g,a as h}from"./BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js";import{g as b}from"./utils-D7bH4Tlo.js";import{d as f,A as x,x as v,i as k,r as l,u as o,o as c,c as w,a as t,b as a,w as y,e as B,h as C}from"./index-B-kKBcPB.js";const $={key:0,class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},L=t("div",{class:"absolute inset-0"},[t("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),N={class:"relative mx-auto max-w-7xl"},A={class:"mt-12 relative mx-auto max-w-7xl"},E={class:"mt-8 text-center"},F=f({__name:"[name]",setup(R){var r;const m=(r=x().params)==null?void 0:r.name,n=v("press"),e=n.blog.authors.find(s=>b(s.name)==m),i=e?n.blog.posts.filter(s=>s.author.toLowerCase()==e.name.toLowerCase()):[];return e&&k({title:`${e.name} posts`}),(s,V)=>{const u=g,p=h,_=l("RouterLink"),d=l("ErrorSummary");return o(e)?(c(),w("div",$,[L,t("div",N,[a(u,{heading:`All posts written by ${o(e).name}`},null,8,["heading"])]),t("div",A,[a(p,{posts:o(i)},null,8,["posts"]),t("div",E,[a(_,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:y(()=>[B("view all posts")]),_:1})])])])):(c(),C(d,{key:1,status:{errorCode:"NotFound",message:`Author ${s.$route.params.name} was not found`}},null,8,["status"]))}}});export{F as default}; +import{_ as g,a as h}from"./BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js";import{g as b}from"./utils-BDrlE94o.js";import{d as f,A as x,x as v,i as k,r as l,u as o,o as c,c as w,a as t,b as a,w as y,e as B,h as C}from"./index-CoFPLbfm.js";const $={key:0,class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},L=t("div",{class:"absolute inset-0"},[t("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),N={class:"relative mx-auto max-w-7xl"},A={class:"mt-12 relative mx-auto max-w-7xl"},E={class:"mt-8 text-center"},F=f({__name:"[name]",setup(R){var r;const m=(r=x().params)==null?void 0:r.name,n=v("press"),e=n.blog.authors.find(s=>b(s.name)==m),i=e?n.blog.posts.filter(s=>s.author.toLowerCase()==e.name.toLowerCase()):[];return e&&k({title:`${e.name} posts`}),(s,V)=>{const u=g,p=h,_=l("RouterLink"),d=l("ErrorSummary");return o(e)?(c(),w("div",$,[L,t("div",N,[a(u,{heading:`All posts written by ${o(e).name}`},null,8,["heading"])]),t("div",A,[a(p,{posts:o(i)},null,8,["posts"]),t("div",E,[a(_,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:y(()=>[B("view all posts")]),_:1})])])])):(c(),C(d,{key:1,status:{errorCode:"NotFound",message:`Author ${s.$route.params.name} was not found`}},null,8,["status"]))}}});export{F as default}; diff --git a/assets/_slug_-D0R-lY2g.js b/assets/_slug_-BaiPQcvV.js similarity index 98% rename from assets/_slug_-D0R-lY2g.js rename to assets/_slug_-BaiPQcvV.js index 3a9486c..3e92138 100644 --- a/assets/_slug_-D0R-lY2g.js +++ b/assets/_slug_-BaiPQcvV.js @@ -1 +1 @@ -import{_ as q}from"./MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js";import{d as T,o as e,c as l,a as t,m as d,A as N,x as R,k as m,q as E,i as S,r as M,t as n,h as g,w as h,e as w,b as x,F as k,g as V,u as p}from"./index-B-kKBcPB.js";import{d as B,a as H,g as y}from"./utils-D7bH4Tlo.js";const D={key:0,role:"list",class:"flex"},G={key:0},W=["href"],I=t("svg",{viewBox:"0 0 24 24","aria-hidden":"true",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500"},[t("path",{d:"M20.055 7.983c.011.174.011.347.011.523 0 5.338-3.92 11.494-11.09 11.494v-.003A10.755 10.755 0 0 1 3 18.186c.308.038.618.057.928.058a7.655 7.655 0 0 0 4.841-1.733c-1.668-.032-3.13-1.16-3.642-2.805a3.753 3.753 0 0 0 1.76-.07C5.07 13.256 3.76 11.6 3.76 9.676v-.05a3.77 3.77 0 0 0 1.77.505C3.816 8.945 3.288 6.583 4.322 4.737c1.98 2.524 4.9 4.058 8.034 4.22a4.137 4.137 0 0 1 1.128-3.86A3.807 3.807 0 0 1 19 5.274a7.657 7.657 0 0 0 2.475-.98c-.29.934-.9 1.729-1.713 2.233A7.54 7.54 0 0 0 22 5.89a8.084 8.084 0 0 1-1.945 2.093Z"})],-1),J=[I],K={key:1},O=["href"],Q=t("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M19 7.5c-1.333-3-3.667-4.5-7-4.5c-5 0-8 2.5-8 9s3.5 9 8 9s7-3 7-5s-1-5-7-5c-2.5 0-3 1.25-3 2.5C9 15 10 16 11.5 16c2.5 0 3.5-1.5 3.5-5s-2-4-3-4s-1.833.333-2.5 1"})],-1),X=[Q],Y={key:2},P=["href"],tt=t("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"currentColor",d:"M20.94 14c-.28 1.41-2.44 2.96-4.97 3.26c-1.31.15-2.6.3-3.97.24c-2.25-.11-4-.54-4-.54v.62c.32 2.22 2.22 2.35 4.03 2.42c1.82.05 3.44-.46 3.44-.46l.08 1.65s-1.28.68-3.55.81c-1.25.07-2.81-.03-4.62-.5c-3.92-1.05-4.6-5.24-4.7-9.5l-.01-3.43c0-4.34 2.83-5.61 2.83-5.61C6.95 2.3 9.41 2 11.97 2h.06c2.56 0 5.02.3 6.47.96c0 0 2.83 1.27 2.83 5.61c0 0 .04 3.21-.39 5.43M18 8.91c0-1.08-.3-1.91-.85-2.56c-.56-.63-1.3-.96-2.23-.96c-1.06 0-1.87.41-2.42 1.23l-.5.88l-.5-.88c-.56-.82-1.36-1.23-2.43-1.23c-.92 0-1.66.33-2.23.96C6.29 7 6 7.83 6 8.91v5.26h2.1V9.06c0-1.06.45-1.62 1.36-1.62c1 0 1.5.65 1.5 1.93v2.79h2.07V9.37c0-1.28.5-1.93 1.51-1.93c.9 0 1.35.56 1.35 1.62v5.11H18V8.91Z"})],-1),et=[tt],st={key:3},ot=["href"],lt=t("svg",{viewBox:"0 0 24 24","aria-hidden":"true",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500"},[t("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 2C6.475 2 2 6.588 2 12.253c0 4.537 2.862 8.369 6.838 9.727.5.09.687-.218.687-.487 0-.243-.013-1.05-.013-1.91C7 20.059 6.35 18.957 6.15 18.38c-.113-.295-.6-1.205-1.025-1.448-.35-.192-.85-.667-.013-.68.788-.012 1.35.744 1.538 1.051.9 1.551 2.338 1.116 2.912.846.088-.666.35-1.115.638-1.371-2.225-.256-4.55-1.14-4.55-5.062 0-1.115.387-2.038 1.025-2.756-.1-.256-.45-1.307.1-2.717 0 0 .837-.269 2.75 1.051.8-.23 1.65-.346 2.5-.346.85 0 1.7.115 2.5.346 1.912-1.333 2.75-1.05 2.75-1.05.55 1.409.2 2.46.1 2.716.637.718 1.025 1.628 1.025 2.756 0 3.934-2.337 4.806-4.562 5.062.362.32.675.936.675 1.897 0 1.371-.013 2.473-.013 2.82 0 .268.188.589.688.486a10.039 10.039 0 0 0 4.932-3.74A10.447 10.447 0 0 0 22 12.253C22 6.588 17.525 2 12 2Z"})],-1),at=[lt],it={key:4},nt=["title","href"],rt=t("svg",{class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500",xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"currentColor",d:"M4 20q-.825 0-1.413-.588T2 18V6q0-.825.588-1.413T4 4h16q.825 0 1.413.588T22 6v12q0 .825-.588 1.413T20 20H4Zm8-7L4 8v10h16V8l-8 5Zm0-2l8-5H4l8 5ZM4 8V6v12V8Z"})],-1),dt=[rt],ct=T({__name:"AuthorLinks",props:{author:{}},setup(A){return(a,f)=>a.author.twitterUrl||a.author.threadsUrl||a.author.mastodonUrl||a.author.gitHubUrl?(e(),l("ul",D,[a.author.twitterUrl?(e(),l("li",G,[t("a",{title:"Follow on Twitter",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.twitterUrl},J,8,W)])):d("",!0),a.author.threadsUrl?(e(),l("li",K,[t("a",{title:"Follow on threads.net",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.threadsUrl},X,8,O)])):d("",!0),a.author.mastodonUrl?(e(),l("li",Y,[t("a",{title:"Follow on Mastodon",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.mastodonUrl},et,8,P)])):d("",!0),a.author.gitHubUrl?(e(),l("li",st,[t("a",{title:"Follow on GitHub",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.gitHubUrl},at,8,ot)])):d("",!0),a.author.email?(e(),l("li",it,[t("a",{title:`Email ${a.author.name}`,href:`mailto:@${a.author.email}`,class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500"},dt,8,nt)])):d("",!0)])):d("",!0)}}),ut={class:"container px-5 mb-32 mx-auto"},ht={class:"mt-20"},_t={class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"},mt={class:"flex justify-between"},xt={class:"md:mb-12 flex items-center"},vt=["src"],gt=["src"],ft={key:2,class:"flex flex-col"},pt={key:1,class:"text-xl font-semibold"},wt={class:"mb-8 md:mb-16 sm:mx-0"},kt={class:"sm:mx-0"},yt=["src","alt"],bt={class:"flex max-w-3xl mx-auto justify-between"},$t={class:"mb-4 flex flex-wrap"},Ct={key:0,class:"max-w-3xl mx-auto"},zt={class:"mb-6 text-lg text-gray-500 dark:text-gray-400"},Lt=["datetime"],Ut=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),Mt={class:"max-w-3xl mx-auto"},Vt={id:"post",class:"prose dark:prose-invert lg:prose-xl max-w-none mb-32"},Bt={key:0,class:"bg-gray-50 dark:bg-gray-900 py-20"},Ht={class:"max-w-3xl mx-auto"},Tt={class:"flex justify-between"},At=["src"],jt=["src"],Ft={class:"mt-2 font-medium text-2xl"},Zt={class:"text-gray-600 dark:text-gray-300"},qt={class:"flex items-end"},Nt={class:"mt-4 border-t"},Rt={class:"py-8 text-lg text-gray-700 dark:text-gray-200 font-medium"},Et={class:"grid grid-cols-2 gap-8"},St={class:"flex flex-col overflow-hidden"},Dt={class:"flex-shrink-0"},Gt=["src"],Wt={class:"flex flex-1 flex-col justify-between bg-white dark:bg-black p-6"},It={class:"flex-1"},Jt=t("p",{class:"text-sm font-medium text-indigo-600 dark:text-indigo-300"}," Article ",-1),Kt=["title"],Ot={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},Qt={class:"mt-6 flex items-center"},Xt={class:"flex-shrink-0"},Yt={class:"sr-only"},Pt=["src","alt"],te={class:"ml-3"},ee={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},se={key:1},oe={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},le=["datetime"],ae=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),ie={key:1,class:"mt-3 mb-20 mx-auto max-w-fit"},ce=T({__name:"[slug]",setup(A){const a=N(),f=R("press"),b=m(()=>{var s;return(s=a.params)==null?void 0:s.slug}),$=f.blog.posts,i=m(()=>$.find(s=>s.slug==b.value)),r=m(()=>i.value?f.blog.authors.find(s=>{var c;return s.name.toLowerCase()==((c=i.value.author)==null?void 0:c.toLowerCase())}):null),C=m(()=>r.value?$.filter(s=>{var c;return((c=s.author)==null?void 0:c.toLowerCase())==r.value.name.toLowerCase()}).slice(0,4):[]),v=m(()=>{var s;return((s=r.value)==null?void 0:s.profileUrl)??"/img/profiles/user1.svg"}),_=m(()=>r.value?`/posts/author/${y(r.value.name)}`:null);function z(s){return`/posts/${s.slug}`}function j(s){return`/posts/tagged/${y(s)}`}function L(s){return s&&f.blog.authors.some(c=>c.name.toLowerCase()==s.toLowerCase())?`/posts/author/${y(s)}`:null}return E(()=>{i.value&&S({title:i.value.title})}),(s,c)=>{const u=M("RouterLink"),U=ct,F=q,Z=M("ErrorSummary");return i.value?(e(),l(k,{key:0},[t("div",ut,[t("article",ht,[t("h1",_t,n(i.value.title),1),t("div",mt,[t("div",xt,[_.value?(e(),g(u,{key:0,to:_.value},{default:h(()=>[t("img",{class:"w-12 h-12 rounded-full mr-4 text-cyan-600",src:v.value},null,8,vt)]),_:1},8,["to"])):(e(),l("img",{key:1,class:"w-12 h-12 rounded-full mr-4 text-cyan-600",src:v.value},null,8,gt)),r.value?(e(),l("div",ft,[_.value?(e(),g(u,{key:0,class:"text-xl font-semibold hover:underline",to:_.value},{default:h(()=>[w(n(i.value.author),1)]),_:1},8,["to"])):(e(),l("span",pt,n(i.value.author),1)),x(U,{author:r.value},null,8,["author"])])):d("",!0)])]),t("div",wt,[t("div",kt,[t("img",{src:i.value.image,alt:`${i.value.title} Background`,class:"shadow-small"},null,8,yt)])]),t("div",bt,[t("div",null,[t("div",$t,[(e(!0),l(k,null,V(i.value.tags,o=>(e(),g(u,{to:j(o),class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-slate-400/10 dark:bg-slate-400/30 rounded-full py-1 px-3 flex items-center space-x-2 hover:bg-slate-400/20 dark:hover:bg-slate-400/40 dark:highlight-white/5"},{default:h(()=>[w(n(o),1)]),_:2},1032,["to"]))),256))]),i.value.date?(e(),l("div",Ct,[t("div",zt,[t("time",{datetime:p(B)(i.value.date)},n(p(H)(i.value.date)),9,Lt),Ut,t("span",null,n(i.value.minutesToRead)+" min read",1)])])):d("",!0)])]),t("div",Mt,[t("div",Vt,[x(F,{type:"blog",doc:i.value},null,8,["doc"])])])])]),r.value&&C.value.length?(e(),l("div",Bt,[t("div",Ht,[t("div",Tt,[t("div",null,[_.value?(e(),g(u,{key:0,to:_.value},{default:h(()=>[t("img",{class:"w-20 h-20 rounded-full text-cyan-600",src:v.value},null,8,At)]),_:1},8,["to"])):(e(),l("img",{key:1,class:"w-20 h-20 rounded-full text-cyan-600",src:v.value},null,8,jt)),t("div",Ft," Written by "+n(r.value.name),1),t("div",Zt,n(r.value.bio),1)]),t("div",qt,[x(U,{author:r.value},null,8,["author"])])]),t("div",Nt,[t("div",Rt," More from "+n(r.value.name),1),t("div",Et,[(e(!0),l(k,null,V(C.value,o=>(e(),l("div",null,[t("div",St,[t("div",Dt,[x(u,{to:z(o)},{default:h(()=>[t("img",{class:"h-48 w-full object-cover",src:o.image,alt:""},null,8,Gt)]),_:2},1032,["to"])]),t("div",Wt,[t("div",It,[Jt,x(u,{to:z(o),class:"mt-2 block"},{default:h(()=>[t("p",{class:"text-xl font-semibold text-gray-900 dark:text-gray-50 whitespace-nowrap overflow-hidden text-ellipsis",title:o.title},n(o.title),9,Kt),t("p",Ot,n(o.summary),1)]),_:2},1032,["to"])]),t("div",Qt,[t("div",Xt,[t("span",Yt,n(o.author),1),t("img",{class:"h-10 w-10 rounded-full",src:v.value,alt:`${o.title} background`},null,8,Pt)]),t("div",te,[t("p",ee,[L(o.author)?(e(),g(u,{key:0,to:L(o.author),class:"hover:underline"},{default:h(()=>[w(n(o.author),1)]),_:2},1032,["to"])):(e(),l("span",se,n(o.author),1))]),t("div",oe,[t("time",{datetime:p(B)(o.date)},n(p(H)(o.date)),9,le),ae,t("span",null,n(o.minutesToRead)+" min read",1)])])])])])]))),256))])])])])):d("",!0)],64)):(e(),l("div",ie,[x(Z,{status:{errorCode:"NotFound",message:`Post ${b.value} was not found`}},null,8,["status"])]))}}});export{ce as default}; +import{_ as q}from"./MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js";import{d as T,o as e,c as l,a as t,m as d,A as N,x as R,k as m,q as E,i as S,r as M,t as n,h as g,w as h,e as w,b as x,F as k,g as V,u as p}from"./index-CoFPLbfm.js";import{d as B,a as H,g as y}from"./utils-BDrlE94o.js";const D={key:0,role:"list",class:"flex"},G={key:0},W=["href"],I=t("svg",{viewBox:"0 0 24 24","aria-hidden":"true",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500"},[t("path",{d:"M20.055 7.983c.011.174.011.347.011.523 0 5.338-3.92 11.494-11.09 11.494v-.003A10.755 10.755 0 0 1 3 18.186c.308.038.618.057.928.058a7.655 7.655 0 0 0 4.841-1.733c-1.668-.032-3.13-1.16-3.642-2.805a3.753 3.753 0 0 0 1.76-.07C5.07 13.256 3.76 11.6 3.76 9.676v-.05a3.77 3.77 0 0 0 1.77.505C3.816 8.945 3.288 6.583 4.322 4.737c1.98 2.524 4.9 4.058 8.034 4.22a4.137 4.137 0 0 1 1.128-3.86A3.807 3.807 0 0 1 19 5.274a7.657 7.657 0 0 0 2.475-.98c-.29.934-.9 1.729-1.713 2.233A7.54 7.54 0 0 0 22 5.89a8.084 8.084 0 0 1-1.945 2.093Z"})],-1),J=[I],K={key:1},O=["href"],Q=t("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M19 7.5c-1.333-3-3.667-4.5-7-4.5c-5 0-8 2.5-8 9s3.5 9 8 9s7-3 7-5s-1-5-7-5c-2.5 0-3 1.25-3 2.5C9 15 10 16 11.5 16c2.5 0 3.5-1.5 3.5-5s-2-4-3-4s-1.833.333-2.5 1"})],-1),X=[Q],Y={key:2},P=["href"],tt=t("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"currentColor",d:"M20.94 14c-.28 1.41-2.44 2.96-4.97 3.26c-1.31.15-2.6.3-3.97.24c-2.25-.11-4-.54-4-.54v.62c.32 2.22 2.22 2.35 4.03 2.42c1.82.05 3.44-.46 3.44-.46l.08 1.65s-1.28.68-3.55.81c-1.25.07-2.81-.03-4.62-.5c-3.92-1.05-4.6-5.24-4.7-9.5l-.01-3.43c0-4.34 2.83-5.61 2.83-5.61C6.95 2.3 9.41 2 11.97 2h.06c2.56 0 5.02.3 6.47.96c0 0 2.83 1.27 2.83 5.61c0 0 .04 3.21-.39 5.43M18 8.91c0-1.08-.3-1.91-.85-2.56c-.56-.63-1.3-.96-2.23-.96c-1.06 0-1.87.41-2.42 1.23l-.5.88l-.5-.88c-.56-.82-1.36-1.23-2.43-1.23c-.92 0-1.66.33-2.23.96C6.29 7 6 7.83 6 8.91v5.26h2.1V9.06c0-1.06.45-1.62 1.36-1.62c1 0 1.5.65 1.5 1.93v2.79h2.07V9.37c0-1.28.5-1.93 1.51-1.93c.9 0 1.35.56 1.35 1.62v5.11H18V8.91Z"})],-1),et=[tt],st={key:3},ot=["href"],lt=t("svg",{viewBox:"0 0 24 24","aria-hidden":"true",class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500"},[t("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 2C6.475 2 2 6.588 2 12.253c0 4.537 2.862 8.369 6.838 9.727.5.09.687-.218.687-.487 0-.243-.013-1.05-.013-1.91C7 20.059 6.35 18.957 6.15 18.38c-.113-.295-.6-1.205-1.025-1.448-.35-.192-.85-.667-.013-.68.788-.012 1.35.744 1.538 1.051.9 1.551 2.338 1.116 2.912.846.088-.666.35-1.115.638-1.371-2.225-.256-4.55-1.14-4.55-5.062 0-1.115.387-2.038 1.025-2.756-.1-.256-.45-1.307.1-2.717 0 0 .837-.269 2.75 1.051.8-.23 1.65-.346 2.5-.346.85 0 1.7.115 2.5.346 1.912-1.333 2.75-1.05 2.75-1.05.55 1.409.2 2.46.1 2.716.637.718 1.025 1.628 1.025 2.756 0 3.934-2.337 4.806-4.562 5.062.362.32.675.936.675 1.897 0 1.371-.013 2.473-.013 2.82 0 .268.188.589.688.486a10.039 10.039 0 0 0 4.932-3.74A10.447 10.447 0 0 0 22 12.253C22 6.588 17.525 2 12 2Z"})],-1),at=[lt],it={key:4},nt=["title","href"],rt=t("svg",{class:"h-6 w-6 flex-none text-zinc-500 fill-zinc-500 transition group-hover:fill-indigo-500",xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},[t("path",{fill:"currentColor",d:"M4 20q-.825 0-1.413-.588T2 18V6q0-.825.588-1.413T4 4h16q.825 0 1.413.588T22 6v12q0 .825-.588 1.413T20 20H4Zm8-7L4 8v10h16V8l-8 5Zm0-2l8-5H4l8 5ZM4 8V6v12V8Z"})],-1),dt=[rt],ct=T({__name:"AuthorLinks",props:{author:{}},setup(A){return(a,f)=>a.author.twitterUrl||a.author.threadsUrl||a.author.mastodonUrl||a.author.gitHubUrl?(e(),l("ul",D,[a.author.twitterUrl?(e(),l("li",G,[t("a",{title:"Follow on Twitter",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.twitterUrl},J,8,W)])):d("",!0),a.author.threadsUrl?(e(),l("li",K,[t("a",{title:"Follow on threads.net",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.threadsUrl},X,8,O)])):d("",!0),a.author.mastodonUrl?(e(),l("li",Y,[t("a",{title:"Follow on Mastodon",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.mastodonUrl},et,8,P)])):d("",!0),a.author.gitHubUrl?(e(),l("li",st,[t("a",{title:"Follow on GitHub",class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500",href:a.author.gitHubUrl},at,8,ot)])):d("",!0),a.author.email?(e(),l("li",it,[t("a",{title:`Email ${a.author.name}`,href:`mailto:@${a.author.email}`,class:"mr-1 group flex text-sm font-medium text-zinc-800 transition hover:text-indigo-500 dark:text-zinc-200 dark:hover:text-indigo-500"},dt,8,nt)])):d("",!0)])):d("",!0)}}),ut={class:"container px-5 mb-32 mx-auto"},ht={class:"mt-20"},_t={class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"},mt={class:"flex justify-between"},xt={class:"md:mb-12 flex items-center"},vt=["src"],gt=["src"],ft={key:2,class:"flex flex-col"},pt={key:1,class:"text-xl font-semibold"},wt={class:"mb-8 md:mb-16 sm:mx-0"},kt={class:"sm:mx-0"},yt=["src","alt"],bt={class:"flex max-w-3xl mx-auto justify-between"},$t={class:"mb-4 flex flex-wrap"},Ct={key:0,class:"max-w-3xl mx-auto"},zt={class:"mb-6 text-lg text-gray-500 dark:text-gray-400"},Lt=["datetime"],Ut=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),Mt={class:"max-w-3xl mx-auto"},Vt={id:"post",class:"prose dark:prose-invert lg:prose-xl max-w-none mb-32"},Bt={key:0,class:"bg-gray-50 dark:bg-gray-900 py-20"},Ht={class:"max-w-3xl mx-auto"},Tt={class:"flex justify-between"},At=["src"],jt=["src"],Ft={class:"mt-2 font-medium text-2xl"},Zt={class:"text-gray-600 dark:text-gray-300"},qt={class:"flex items-end"},Nt={class:"mt-4 border-t"},Rt={class:"py-8 text-lg text-gray-700 dark:text-gray-200 font-medium"},Et={class:"grid grid-cols-2 gap-8"},St={class:"flex flex-col overflow-hidden"},Dt={class:"flex-shrink-0"},Gt=["src"],Wt={class:"flex flex-1 flex-col justify-between bg-white dark:bg-black p-6"},It={class:"flex-1"},Jt=t("p",{class:"text-sm font-medium text-indigo-600 dark:text-indigo-300"}," Article ",-1),Kt=["title"],Ot={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},Qt={class:"mt-6 flex items-center"},Xt={class:"flex-shrink-0"},Yt={class:"sr-only"},Pt=["src","alt"],te={class:"ml-3"},ee={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},se={key:1},oe={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},le=["datetime"],ae=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),ie={key:1,class:"mt-3 mb-20 mx-auto max-w-fit"},ce=T({__name:"[slug]",setup(A){const a=N(),f=R("press"),b=m(()=>{var s;return(s=a.params)==null?void 0:s.slug}),$=f.blog.posts,i=m(()=>$.find(s=>s.slug==b.value)),r=m(()=>i.value?f.blog.authors.find(s=>{var c;return s.name.toLowerCase()==((c=i.value.author)==null?void 0:c.toLowerCase())}):null),C=m(()=>r.value?$.filter(s=>{var c;return((c=s.author)==null?void 0:c.toLowerCase())==r.value.name.toLowerCase()}).slice(0,4):[]),v=m(()=>{var s;return((s=r.value)==null?void 0:s.profileUrl)??"/img/profiles/user1.svg"}),_=m(()=>r.value?`/posts/author/${y(r.value.name)}`:null);function z(s){return`/posts/${s.slug}`}function j(s){return`/posts/tagged/${y(s)}`}function L(s){return s&&f.blog.authors.some(c=>c.name.toLowerCase()==s.toLowerCase())?`/posts/author/${y(s)}`:null}return E(()=>{i.value&&S({title:i.value.title})}),(s,c)=>{const u=M("RouterLink"),U=ct,F=q,Z=M("ErrorSummary");return i.value?(e(),l(k,{key:0},[t("div",ut,[t("article",ht,[t("h1",_t,n(i.value.title),1),t("div",mt,[t("div",xt,[_.value?(e(),g(u,{key:0,to:_.value},{default:h(()=>[t("img",{class:"w-12 h-12 rounded-full mr-4 text-cyan-600",src:v.value},null,8,vt)]),_:1},8,["to"])):(e(),l("img",{key:1,class:"w-12 h-12 rounded-full mr-4 text-cyan-600",src:v.value},null,8,gt)),r.value?(e(),l("div",ft,[_.value?(e(),g(u,{key:0,class:"text-xl font-semibold hover:underline",to:_.value},{default:h(()=>[w(n(i.value.author),1)]),_:1},8,["to"])):(e(),l("span",pt,n(i.value.author),1)),x(U,{author:r.value},null,8,["author"])])):d("",!0)])]),t("div",wt,[t("div",kt,[t("img",{src:i.value.image,alt:`${i.value.title} Background`,class:"shadow-small"},null,8,yt)])]),t("div",bt,[t("div",null,[t("div",$t,[(e(!0),l(k,null,V(i.value.tags,o=>(e(),g(u,{to:j(o),class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-slate-400/10 dark:bg-slate-400/30 rounded-full py-1 px-3 flex items-center space-x-2 hover:bg-slate-400/20 dark:hover:bg-slate-400/40 dark:highlight-white/5"},{default:h(()=>[w(n(o),1)]),_:2},1032,["to"]))),256))]),i.value.date?(e(),l("div",Ct,[t("div",zt,[t("time",{datetime:p(B)(i.value.date)},n(p(H)(i.value.date)),9,Lt),Ut,t("span",null,n(i.value.minutesToRead)+" min read",1)])])):d("",!0)])]),t("div",Mt,[t("div",Vt,[x(F,{type:"blog",doc:i.value},null,8,["doc"])])])])]),r.value&&C.value.length?(e(),l("div",Bt,[t("div",Ht,[t("div",Tt,[t("div",null,[_.value?(e(),g(u,{key:0,to:_.value},{default:h(()=>[t("img",{class:"w-20 h-20 rounded-full text-cyan-600",src:v.value},null,8,At)]),_:1},8,["to"])):(e(),l("img",{key:1,class:"w-20 h-20 rounded-full text-cyan-600",src:v.value},null,8,jt)),t("div",Ft," Written by "+n(r.value.name),1),t("div",Zt,n(r.value.bio),1)]),t("div",qt,[x(U,{author:r.value},null,8,["author"])])]),t("div",Nt,[t("div",Rt," More from "+n(r.value.name),1),t("div",Et,[(e(!0),l(k,null,V(C.value,o=>(e(),l("div",null,[t("div",St,[t("div",Dt,[x(u,{to:z(o)},{default:h(()=>[t("img",{class:"h-48 w-full object-cover",src:o.image,alt:""},null,8,Gt)]),_:2},1032,["to"])]),t("div",Wt,[t("div",It,[Jt,x(u,{to:z(o),class:"mt-2 block"},{default:h(()=>[t("p",{class:"text-xl font-semibold text-gray-900 dark:text-gray-50 whitespace-nowrap overflow-hidden text-ellipsis",title:o.title},n(o.title),9,Kt),t("p",Ot,n(o.summary),1)]),_:2},1032,["to"])]),t("div",Qt,[t("div",Xt,[t("span",Yt,n(o.author),1),t("img",{class:"h-10 w-10 rounded-full",src:v.value,alt:`${o.title} background`},null,8,Pt)]),t("div",te,[t("p",ee,[L(o.author)?(e(),g(u,{key:0,to:L(o.author),class:"hover:underline"},{default:h(()=>[w(n(o.author),1)]),_:2},1032,["to"])):(e(),l("span",se,n(o.author),1))]),t("div",oe,[t("time",{datetime:p(B)(o.date)},n(p(H)(o.date)),9,le),ae,t("span",null,n(o.minutesToRead)+" min read",1)])])])])])]))),256))])])])])):d("",!0)],64)):(e(),l("div",ie,[x(Z,{status:{errorCode:"NotFound",message:`Post ${b.value} was not found`}},null,8,["status"])]))}}});export{ce as default}; diff --git a/assets/_tag_-A7_HVUVC.js b/assets/_tag_-Bl8Dgnay.js similarity index 91% rename from assets/_tag_-A7_HVUVC.js rename to assets/_tag_-Bl8Dgnay.js index 27e9ae1..996ac68 100644 --- a/assets/_tag_-A7_HVUVC.js +++ b/assets/_tag_-Bl8Dgnay.js @@ -1 +1 @@ -import{_ as C,a as E}from"./BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js";import{d as L,A as N,k as d,x as P,q as T,i as F,r as _,o as a,c as n,a as s,b as g,F as x,g as R,t as f,h,w as v,e as b}from"./index-B-kKBcPB.js";import{g as V}from"./utils-D7bH4Tlo.js";const j={key:0,class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},A=s("div",{class:"absolute inset-0"},[s("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),M={class:"relative mx-auto max-w-7xl"},q={class:"relative my-4 mx-auto max-w-7xl"},D={class:"flex flex-wrap justify-center"},H={key:0,class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-indigo-600 text-white rounded-full py-1 px-3 flex items-center space-x-2"},z={class:"mt-12 relative mx-auto max-w-7xl"},G={class:"mt-8 text-center"},Q=L({__name:"[tag]",setup(I){const k=N(),u=d(()=>{var t;return(t=k.params)==null?void 0:t.tag}),m=P("press"),e=d(()=>m.blog.tagSlugs[u.value]),r=m.blog.posts,w=d(()=>e?r.filter(t=>t.tags.includes(e.value)):[]),i=[...new Set(r.flatMap(t=>t.tags))],c={};i.forEach(t=>c[t]=r.filter(o=>o.tags.includes(t)).length),i.sort((t,o)=>c[o]-c[t]);function y(t){return`/posts/tagged/${V(t)}`}return T(()=>{e&&F({title:`${e.value} tagged posts`})}),(t,o)=>{const B=C,p=_("RouterLink"),S=E,$=_("ErrorSummary");return e.value?(a(),n("div",j,[A,s("div",M,[g(B,{heading:`All posts tagged in ${e.value}`},null,8,["heading"])]),s("div",q,[s("div",D,[(a(),n(x,null,R(i,l=>(a(),n(x,null,[l==e.value?(a(),n("span",H,f(l),1)):(a(),h(p,{key:1,to:y(l),class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-slate-400/10 dark:bg-slate-400/30 rounded-full py-1 px-3 flex items-center space-x-2 hover:bg-slate-400/20 dark:hover:bg-slate-400/40 dark:highlight-white/5"},{default:v(()=>[b(f(l),1)]),_:2},1032,["to"]))],64))),64))])]),s("div",z,[g(S,{posts:w.value},null,8,["posts"]),s("div",G,[g(p,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:v(()=>[b("view all posts")]),_:1})])])])):(a(),h($,{key:1,status:{errorCode:"NotFound",message:`Posts tagged with ${u.value} was not found`}},null,8,["status"]))}}});export{Q as default}; +import{_ as C,a as E}from"./BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js";import{d as L,A as N,k as d,x as P,q as T,i as F,r as _,o as a,c as n,a as s,b as g,F as x,g as R,t as f,h,w as v,e as b}from"./index-CoFPLbfm.js";import{g as V}from"./utils-BDrlE94o.js";const j={key:0,class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},A=s("div",{class:"absolute inset-0"},[s("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),M={class:"relative mx-auto max-w-7xl"},q={class:"relative my-4 mx-auto max-w-7xl"},D={class:"flex flex-wrap justify-center"},H={key:0,class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-indigo-600 text-white rounded-full py-1 px-3 flex items-center space-x-2"},z={class:"mt-12 relative mx-auto max-w-7xl"},G={class:"mt-8 text-center"},Q=L({__name:"[tag]",setup(I){const k=N(),u=d(()=>{var t;return(t=k.params)==null?void 0:t.tag}),m=P("press"),e=d(()=>m.blog.tagSlugs[u.value]),r=m.blog.posts,w=d(()=>e?r.filter(t=>t.tags.includes(e.value)):[]),i=[...new Set(r.flatMap(t=>t.tags))],c={};i.forEach(t=>c[t]=r.filter(o=>o.tags.includes(t)).length),i.sort((t,o)=>c[o]-c[t]);function y(t){return`/posts/tagged/${V(t)}`}return T(()=>{e&&F({title:`${e.value} tagged posts`})}),(t,o)=>{const B=C,p=_("RouterLink"),S=E,$=_("ErrorSummary");return e.value?(a(),n("div",j,[A,s("div",M,[g(B,{heading:`All posts tagged in ${e.value}`},null,8,["heading"])]),s("div",q,[s("div",D,[(a(),n(x,null,R(i,l=>(a(),n(x,null,[l==e.value?(a(),n("span",H,f(l),1)):(a(),h(p,{key:1,to:y(l),class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-slate-400/10 dark:bg-slate-400/30 rounded-full py-1 px-3 flex items-center space-x-2 hover:bg-slate-400/20 dark:hover:bg-slate-400/40 dark:highlight-white/5"},{default:v(()=>[b(f(l),1)]),_:2},1032,["to"]))],64))),64))])]),s("div",z,[g(S,{posts:w.value},null,8,["posts"]),s("div",G,[g(p,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:v(()=>[b("view all posts")]),_:1})])])])):(a(),h($,{key:1,status:{errorCode:"NotFound",message:`Posts tagged with ${u.value} was not found`}},null,8,["status"]))}}});export{Q as default}; diff --git a/assets/_year_-bjfw_pb5.js b/assets/_year_-C2Zxurez.js similarity index 93% rename from assets/_year_-bjfw_pb5.js rename to assets/_year_-C2Zxurez.js index 4c3759a..24f890b 100644 --- a/assets/_year_-bjfw_pb5.js +++ b/assets/_year_-C2Zxurez.js @@ -1 +1 @@ -import{_ as B,a as $}from"./BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js";import{d as D,A as F,k as p,x as C,q as L,i as N,r as _,o,c as l,a as t,b as c,F as g,g as P,t as v,h as x,w as h,e as f}from"./index-B-kKBcPB.js";import"./utils-D7bH4Tlo.js";const S={key:0,class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},T=t("div",{class:"absolute inset-0"},[t("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),Y={class:"relative mx-auto max-w-7xl"},E={class:"mt-4 relative mb-8 mx-auto max-w-7xl"},R={class:"flex flex-wrap justify-center"},V={key:0,class:"ml-3 text-sm font-semibold"},j={class:"mt-12 relative mx-auto max-w-7xl"},A={class:"mt-8 text-center"},G=D({__name:"[year]",setup(q){const b=F(),a=p(()=>{var e;return parseInt(((e=b.params)==null?void 0:e.year)??0)}),d=C("press").blog.posts,u=[...new Set(d.map(e=>new Date(e.date).getFullYear()))];u.sort((e,s)=>s-e);const r=p(()=>{const e=d.filter(s=>new Date(s.date).getFullYear()==a.value);return e.sort((s,i)=>new Date(i.date).getTime()-new Date(s.date).getTime()),e});function k(e){return`/posts/year/${e}`}return L(()=>{r.value.length&&N({title:`${a.value} posts`})}),(e,s)=>{const i=B,m=_("RouterLink"),w=$,y=_("ErrorSummary");return r.value.length?(o(),l("div",S,[T,t("div",Y,[c(i,{heading:`All posts published in ${a.value}`},null,8,["heading"])]),t("div",E,[t("div",R,[(o(),l(g,null,P(u,n=>(o(),l(g,null,[a.value==n?(o(),l("b",V,v(n),1)):(o(),x(m,{key:1,class:"ml-3 text-sm text-indigo-700 dark:text-indigo-300 font-semibold hover:underline",to:k(n)},{default:h(()=>[f(v(n),1)]),_:2},1032,["to"]))],64))),64))])]),t("div",j,[c(w,{posts:r.value},null,8,["posts"]),t("div",A,[c(m,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:h(()=>[f("view all posts")]),_:1})])])])):(o(),x(y,{key:1,status:{errorCode:"NotFound",message:`Posts published in ${a.value} was not found`}},null,8,["status"]))}}});export{G as default}; +import{_ as B,a as $}from"./BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js";import{d as D,A as F,k as p,x as C,q as L,i as N,r as _,o,c as l,a as t,b as c,F as g,g as P,t as v,h as x,w as h,e as f}from"./index-CoFPLbfm.js";import"./utils-BDrlE94o.js";const S={key:0,class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},T=t("div",{class:"absolute inset-0"},[t("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),Y={class:"relative mx-auto max-w-7xl"},E={class:"mt-4 relative mb-8 mx-auto max-w-7xl"},R={class:"flex flex-wrap justify-center"},V={key:0,class:"ml-3 text-sm font-semibold"},j={class:"mt-12 relative mx-auto max-w-7xl"},A={class:"mt-8 text-center"},G=D({__name:"[year]",setup(q){const b=F(),a=p(()=>{var e;return parseInt(((e=b.params)==null?void 0:e.year)??0)}),d=C("press").blog.posts,u=[...new Set(d.map(e=>new Date(e.date).getFullYear()))];u.sort((e,s)=>s-e);const r=p(()=>{const e=d.filter(s=>new Date(s.date).getFullYear()==a.value);return e.sort((s,i)=>new Date(i.date).getTime()-new Date(s.date).getTime()),e});function k(e){return`/posts/year/${e}`}return L(()=>{r.value.length&&N({title:`${a.value} posts`})}),(e,s)=>{const i=B,m=_("RouterLink"),w=$,y=_("ErrorSummary");return r.value.length?(o(),l("div",S,[T,t("div",Y,[c(i,{heading:`All posts published in ${a.value}`},null,8,["heading"])]),t("div",E,[t("div",R,[(o(),l(g,null,P(u,n=>(o(),l(g,null,[a.value==n?(o(),l("b",V,v(n),1)):(o(),x(m,{key:1,class:"ml-3 text-sm text-indigo-700 dark:text-indigo-300 font-semibold hover:underline",to:k(n)},{default:h(()=>[f(v(n),1)]),_:2},1032,["to"]))],64))),64))])]),t("div",j,[c(w,{posts:r.value},null,8,["posts"]),t("div",A,[c(m,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:h(()=>[f("view all posts")]),_:1})])])])):(o(),x(y,{key:1,status:{errorCode:"NotFound",message:`Posts published in ${a.value} was not found`}},null,8,["status"]))}}});export{G as default}; diff --git a/assets/about-C5lL5M9L.js b/assets/about-CSevwr_F.js similarity index 98% rename from assets/about-C5lL5M9L.js rename to assets/about-CSevwr_F.js index b539d1b..a19156e 100644 --- a/assets/about-C5lL5M9L.js +++ b/assets/about-CSevwr_F.js @@ -1,4 +1,4 @@ -import{_ as c}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as u,o as p,h as l,w as i,a as n,b as r,e as t,_ as m}from"./index-B-kKBcPB.js";const k={class:"markdown-body"},d=n("p",null,"This template contains our essential recommendations for a modern Vue Single Page App optimal for both productivity and performance.",-1),g=n("h2",null,"Vue Plugins",-1),h=n("p",null,[t("The Vite plugins registered in "),n("code",null,"vite.config.ts"),t(" improves productivity by adopting popular conventions that automating-away manual tasks & configurations.")],-1),_=n("h3",null,[n("a",{href:"https://github.com/antfu/unplugin-vue-components"},"unplugin-vue-components")],-1),f=n("p",null,[t("For Auto Registering Vue Components, either "),n("code",null,".vue"),t(" SFC’s, "),n("code",null,".md"),t(" Markdown components or Iconify’s icons as Vue3 components.")],-1),v=n("pre",{class:"language-ts"},[n("code",{class:"language-ts"},[n("span",{class:"token function"},"Components"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},"{"),t(` +import{_ as c}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as u,o as p,h as l,w as i,a as n,b as r,e as t,_ as m}from"./index-CoFPLbfm.js";const k={class:"markdown-body"},d=n("p",null,"This template contains our essential recommendations for a modern Vue Single Page App optimal for both productivity and performance.",-1),g=n("h2",null,"Vue Plugins",-1),h=n("p",null,[t("The Vite plugins registered in "),n("code",null,"vite.config.ts"),t(" improves productivity by adopting popular conventions that automating-away manual tasks & configurations.")],-1),_=n("h3",null,[n("a",{href:"https://github.com/antfu/unplugin-vue-components"},"unplugin-vue-components")],-1),f=n("p",null,[t("For Auto Registering Vue Components, either "),n("code",null,".vue"),t(" SFC’s, "),n("code",null,".md"),t(" Markdown components or Iconify’s icons as Vue3 components.")],-1),v=n("pre",{class:"language-ts"},[n("code",{class:"language-ts"},[n("span",{class:"token function"},"Components"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},"{"),t(` `),n("span",{class:"token comment"},"// allow auto load markdown components under `./src/components/`"),t(` extensions`),n("span",{class:"token operator"},":"),t(),n("span",{class:"token punctuation"},"["),n("span",{class:"token string"},"'vue'"),n("span",{class:"token punctuation"},","),t(),n("span",{class:"token string"},"'md'"),n("span",{class:"token punctuation"},"]"),n("span",{class:"token punctuation"},","),t(` diff --git a/assets/admin-ddEAmk2a.js b/assets/admin-DfK6L5xt.js similarity index 91% rename from assets/admin-ddEAmk2a.js rename to assets/admin-DfK6L5xt.js index 0169533..801c500 100644 --- a/assets/admin-ddEAmk2a.js +++ b/assets/admin-DfK6L5xt.js @@ -1 +1 @@ -import{_ as u}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as o,o as s,h as a,w as m,a as e}from"./index-B-kKBcPB.js";const r=e("div",{class:"markdown-body"},[e("p",null,"In this video we explore the Server Multi Razor Page and Client rendered Admin UI Pages in the latest .NET blazor-vue and razor-vue project templates to see how to use the new SidebarLayout and AutoQueryGrid Vue Tailwind components to build beautiful Admin UI Pages within minutes.")],-1),b="Build beautiful custom .NET Admin UIs in minutes",w="https://youtu.be/wlRA4_owEsc",h=["vue","autoquery"],A="14-06-2023",B=3,E=[{property:"og:title",content:"Build beautiful custom .NET Admin UIs in minutes"},{name:"twitter:title",content:"Build beautiful custom .NET Admin UIs in minutes"}],I={__name:"admin",setup(l,{expose:i}){const t={title:"Build beautiful custom .NET Admin UIs in minutes",url:"https://youtu.be/wlRA4_owEsc",tags:["vue","autoquery"],date:"14-06-2023",order:3,meta:[{property:"og:title",content:"Build beautiful custom .NET Admin UIs in minutes"},{name:"twitter:title",content:"Build beautiful custom .NET Admin UIs in minutes"}]};return i({frontmatter:t}),o({title:"Build beautiful custom .NET Admin UIs in minutes",meta:[{property:"og:title",content:"Build beautiful custom .NET Admin UIs in minutes"},{name:"twitter:title",content:"Build beautiful custom .NET Admin UIs in minutes"}]}),(c,p)=>{const n=u;return s(),a(n,{frontmatter:t},{default:m(()=>[r]),_:1})}}};export{A as date,I as default,E as meta,B as order,h as tags,b as title,w as url}; +import{_ as u}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as o,o as s,h as a,w as m,a as e}from"./index-CoFPLbfm.js";const r=e("div",{class:"markdown-body"},[e("p",null,"In this video we explore the Server Multi Razor Page and Client rendered Admin UI Pages in the latest .NET blazor-vue and razor-vue project templates to see how to use the new SidebarLayout and AutoQueryGrid Vue Tailwind components to build beautiful Admin UI Pages within minutes.")],-1),b="Build beautiful custom .NET Admin UIs in minutes",w="https://youtu.be/wlRA4_owEsc",h=["vue","autoquery"],A="14-06-2023",B=3,E=[{property:"og:title",content:"Build beautiful custom .NET Admin UIs in minutes"},{name:"twitter:title",content:"Build beautiful custom .NET Admin UIs in minutes"}],I={__name:"admin",setup(l,{expose:i}){const t={title:"Build beautiful custom .NET Admin UIs in minutes",url:"https://youtu.be/wlRA4_owEsc",tags:["vue","autoquery"],date:"14-06-2023",order:3,meta:[{property:"og:title",content:"Build beautiful custom .NET Admin UIs in minutes"},{name:"twitter:title",content:"Build beautiful custom .NET Admin UIs in minutes"}]};return i({frontmatter:t}),o({title:"Build beautiful custom .NET Admin UIs in minutes",meta:[{property:"og:title",content:"Build beautiful custom .NET Admin UIs in minutes"},{name:"twitter:title",content:"Build beautiful custom .NET Admin UIs in minutes"}]}),(c,p)=>{const n=u;return s(),a(n,{frontmatter:t},{default:m(()=>[r]),_:1})}}};export{A as date,I as default,E as meta,B as order,h as tags,b as title,w as url}; diff --git a/assets/autoquerygrid-B8jP3C5m.js b/assets/autoquerygrid-CYIg7oz6.js similarity index 92% rename from assets/autoquerygrid-B8jP3C5m.js rename to assets/autoquerygrid-CYIg7oz6.js index 2a97668..7534de9 100644 --- a/assets/autoquerygrid-B8jP3C5m.js +++ b/assets/autoquerygrid-CYIg7oz6.js @@ -1 +1 @@ -import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o as u,h as s,w as i,a as t}from"./index-B-kKBcPB.js";const l=t("div",{class:"markdown-body"},[t("p",null,"This walkthrough explores the ServiceStack Vue 3 library and the functionality of the AutoQueryGrid component. The AutoQueryGrid component simplifies the integration of AutoQuery services by generating a customizable UI."),t("p",null,"By following this guide, you’ll learn how to effectively utilize these tools to enhance your application’s user interface and overall user experience.")],-1),h="Instantly Manage your data using AutoQueryGrid Vue",f="https://youtu.be/znCoC-Ct0Ps",_=["vue","autoquery"],A="16-03-2023",Q=1,G=[{property:"og:title",content:"Instantly Manage your data using AutoQueryGrid Vue"},{name:"twitter:title",content:"Instantly Manage your data using AutoQueryGrid Vue"}],V={__name:"autoquerygrid",setup(y,{expose:a}){const e={title:"Instantly Manage your data using AutoQueryGrid Vue",url:"https://youtu.be/znCoC-Ct0Ps",tags:["vue","autoquery"],date:"16-03-2023",order:1,meta:[{property:"og:title",content:"Instantly Manage your data using AutoQueryGrid Vue"},{name:"twitter:title",content:"Instantly Manage your data using AutoQueryGrid Vue"}]};return a({frontmatter:e}),r({title:"Instantly Manage your data using AutoQueryGrid Vue",meta:[{property:"og:title",content:"Instantly Manage your data using AutoQueryGrid Vue"},{name:"twitter:title",content:"Instantly Manage your data using AutoQueryGrid Vue"}]}),(d,g)=>{const n=o;return u(),s(n,{frontmatter:e},{default:i(()=>[l]),_:1})}}};export{A as date,V as default,G as meta,Q as order,_ as tags,h as title,f as url}; +import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o as u,h as s,w as i,a as t}from"./index-CoFPLbfm.js";const l=t("div",{class:"markdown-body"},[t("p",null,"This walkthrough explores the ServiceStack Vue 3 library and the functionality of the AutoQueryGrid component. The AutoQueryGrid component simplifies the integration of AutoQuery services by generating a customizable UI."),t("p",null,"By following this guide, you’ll learn how to effectively utilize these tools to enhance your application’s user interface and overall user experience.")],-1),h="Instantly Manage your data using AutoQueryGrid Vue",f="https://youtu.be/znCoC-Ct0Ps",_=["vue","autoquery"],A="16-03-2023",Q=1,G=[{property:"og:title",content:"Instantly Manage your data using AutoQueryGrid Vue"},{name:"twitter:title",content:"Instantly Manage your data using AutoQueryGrid Vue"}],V={__name:"autoquerygrid",setup(y,{expose:a}){const e={title:"Instantly Manage your data using AutoQueryGrid Vue",url:"https://youtu.be/znCoC-Ct0Ps",tags:["vue","autoquery"],date:"16-03-2023",order:1,meta:[{property:"og:title",content:"Instantly Manage your data using AutoQueryGrid Vue"},{name:"twitter:title",content:"Instantly Manage your data using AutoQueryGrid Vue"}]};return a({frontmatter:e}),r({title:"Instantly Manage your data using AutoQueryGrid Vue",meta:[{property:"og:title",content:"Instantly Manage your data using AutoQueryGrid Vue"},{name:"twitter:title",content:"Instantly Manage your data using AutoQueryGrid Vue"}]}),(d,g)=>{const n=o;return u(),s(n,{frontmatter:e},{default:i(()=>[l]),_:1})}}};export{A as date,V as default,G as meta,Q as order,_ as tags,h as title,f as url}; diff --git a/assets/blog-DsWHVwkJ.js b/assets/blog-NLNSyVmF.js similarity index 98% rename from assets/blog-DsWHVwkJ.js rename to assets/blog-NLNSyVmF.js index b9b23f0..c3901d5 100644 --- a/assets/blog-DsWHVwkJ.js +++ b/assets/blog-NLNSyVmF.js @@ -1 +1 @@ -import{_ as V}from"./SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js";import{_ as Z}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o,c as n,f as j,d as F,x as H,i as I,r as N,a as t,u as s,b as c,w as d,e as f,t as a,h as b,m as g,F as k,g as L}from"./index-B-kKBcPB.js";import{L as S}from"./logo-DspwJfOt.js";import{d as w,a as y,g as T}from"./utils-D7bH4Tlo.js";const P={},R={role:"list"},U=j('
  • Follow on Twitter
  • Follow on Instagram
  • Follow on GitHub
  • Follow on LinkedIn
  • spencer@planetaria.tech
  • ',5),D=[U];function E(A,u){return o(),n("ul",R,D)}const G=Z(P,[["render",E]]),Y={class:"container mx-auto px-5 mt-24 mb-24"},q={key:0},J={class:"mb-8 md:mb-16"},K={class:"sm:mx-0"},O=["src","alt"],Q={class:"md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28"},W={class:"mb-4 text-4xl lg:text-6xl leading-tight"},X={class:"mb-4 md:mb-0 text-lg"},tt=["datetime"],et={class:"text-lg leading-relaxed mb-4"},st=["src"],at={key:1,class:"flex items-center text-xl font-bold"},ot=["src"],lt={key:1},nt=t("h2",{class:"mb-8 text-6xl md:text-7xl font-bold tracking-tighter leading-tight"},"More from the blog",-1),it={class:"mx-auto mt-12 grid max-w-lg gap-5 lg:max-w-none lg:grid-cols-3"},rt={class:"flex flex-col overflow-hidden rounded-lg shadow-lg"},ct={class:"flex-shrink-0"},dt=["src"],ht={class:"flex flex-1 flex-col justify-between bg-white dark:bg-black p-6"},_t={class:"flex-1"},mt=t("p",{class:"text-sm font-medium text-indigo-600 dark:text-indigo-300"}," Article ",-1),ut={class:"text-xl font-semibold text-gray-900 dark:text-gray-50"},xt={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},ft={class:"mt-6 flex items-center"},gt={class:"flex-shrink-0"},vt={class:"sr-only"},pt=["src","alt"],bt={class:"ml-3"},kt={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},wt={key:1},yt={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},Ct=["datetime"],zt=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),Lt={key:2,class:"mt-24 flex justify-center"},At={class:"flex max-w-screen-lg"},Mt={class:"w-2/3"},$t={class:"border-b pb-4 mb-4"},Bt={class:"flex justify-between"},Vt={class:"w-3/4"},Zt={class:"text-xl font-semibold text-gray-900 dark:text-gray-50"},jt={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},Ft={class:"mt-6 flex items-center"},Ht={class:"flex-shrink-0"},It={class:"sr-only"},Nt=["src","alt"],St={class:"ml-3"},Tt={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},Pt={key:1},Rt={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},Ut=["datetime"],Dt=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),Et={class:"w-1/4"},Gt=["src"],Yt={key:0,class:"mt-8 text-center"},qt=t("a",{class:"text-sm font-semibold hover:underline",href:"/posts/"},"view all posts",-1),Jt=[qt],Kt={class:"w-1/3"},Ot={class:"pl-8"},Qt={class:"flex items-center"},Wt=t("span",{class:"hidden sm:block text-lg font-semibold"},"MyApp",-1),Xt={class:"p-2"},te=t("p",{class:"text-gray-500"},"I’m Spencer Sharp. I live in New York City, where I design the future.",-1),ee={class:"p-4"},se={class:"my-8 flex justify-center gap-x-4"},re=F({__name:"blog",setup(A){const u=H("press");I({title:u.blog.config.blogTitle});function _(i){return i&&u.blog.authors.some(h=>h.name.toLowerCase()==i.toLowerCase())?`/posts/author/${T(i)}`:null}function m(i){return`/posts/${i.slug}`}function M(i){return i?u.blog.authors.filter(h=>h.name.toLowerCase()==i.toLowerCase())[0]:null}function x(i){var h;return((h=M(i))==null?void 0:h.profileUrl)??"/img/profiles/user1.svg"}const v=u.blog.posts,l=v[0],C=l.author,z=v.slice(1,7),p=v.slice(7,22);return(i,h)=>{const r=N("RouterLink"),$=G,B=V;return o(),n(k,null,[t("div",Y,[s(l)?(o(),n("section",q,[t("div",J,[t("div",K,[c(r,{"aria-label":s(l).title,to:m(s(l))},{default:d(()=>[t("img",{src:s(l).image,alt:`Cover Image for ${s(l).title}`,class:"shadow-sm hover:shadow-2xl transition-shadow duration-200"},null,8,O)]),_:1},8,["aria-label","to"])])]),t("div",Q,[t("div",null,[t("h3",W,[c(r,{class:"hover:underline",to:m(s(l))},{default:d(()=>[f(a(s(l).title),1)]),_:1},8,["to"])]),t("div",X,[t("time",{datetime:s(w)(s(l).date)},a(s(y)(s(l).date)),9,tt)])]),t("div",null,[t("p",et,a(s(l).summary),1),_(s(l).author)?(o(),b(r,{key:0,class:"flex items-center text-xl font-bold",to:_(s(l).author)},{default:d(()=>[t("img",{src:x(s(l).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,st),t("span",null,a(s(C)),1)]),_:1},8,["to"])):(o(),n("span",at,[t("img",{src:x(s(l).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,ot),t("span",null,a(s(C)),1)]))])])])):g("",!0),s(z).length?(o(),n("section",lt,[nt,t("div",it,[(o(!0),n(k,null,L(s(z),e=>(o(),n("div",rt,[t("div",ct,[c(r,{to:m(e)},{default:d(()=>[t("img",{class:"h-48 w-full object-cover",src:e.image,alt:""},null,8,dt)]),_:2},1032,["to"])]),t("div",ht,[t("div",_t,[mt,c(r,{to:m(e),class:"mt-2 block"},{default:d(()=>[t("p",ut,a(e.title),1),t("p",xt,a(e.summary),1)]),_:2},1032,["to"])]),t("div",ft,[t("div",gt,[t("span",null,[t("span",vt,a(e.author),1),t("img",{class:"h-10 w-10 rounded-full",src:x(e.author),alt:`${e.title} background`},null,8,pt)])]),t("div",bt,[t("p",kt,[_(e.author)?(o(),b(r,{key:0,to:_(e.author),class:"hover:underline"},{default:d(()=>[f(a(e.author),1)]),_:2},1032,["to"])):(o(),n("span",wt,a(e.author),1))]),t("div",yt,[t("time",{datetime:s(w)(e.date)},a(s(y)(e.date)),9,Ct),zt,t("span",null,a(e.minutesToRead)+" min read",1)])])])])]))),256))])])):g("",!0),s(p).length?(o(),n("section",Lt,[t("div",At,[t("div",Mt,[(o(!0),n(k,null,L(s(p),e=>(o(),n("div",$t,[t("div",Bt,[t("div",Vt,[c(r,{to:m(e),class:"mt-2 block"},{default:d(()=>[t("p",Zt,a(e.title),1),t("p",jt,a(e.summary),1)]),_:2},1032,["to"]),t("div",Ft,[t("div",Ht,[t("span",null,[t("span",It,a(e.author),1),t("img",{class:"h-10 w-10 rounded-full",src:x(e.author),alt:`${e.title} background`},null,8,Nt)])]),t("div",St,[t("p",Tt,[_(e.author)?(o(),b(r,{key:0,to:_(e.author),class:"hover:underline"},{default:d(()=>[f(a(e.author),1)]),_:2},1032,["to"])):(o(),n("span",Pt,a(e.author),1))]),t("div",Rt,[t("time",{datetime:s(w)(e.date)},a(s(y)(e.date)),9,Ut),Dt,t("span",null,a(e.minutesToRead)+" min read",1)])])])]),t("div",Et,[c(r,{to:m(e),class:"pt-4"},{default:d(()=>[t("img",{class:"w-full object-cover max-h-[130px]",src:e.image,alt:""},null,8,Gt)]),_:2},1032,["to"])])])]))),256)),s(p).length>=15?(o(),n("div",Yt,Jt)):g("",!0)]),t("div",Kt,[t("div",Ot,[t("div",Qt,[c(s(S),{class:"w-8 h-8 mr-1",alt:"MyApp logo"}),Wt]),t("div",Xt,[te,c(r,{to:"/about",class:"text-sm font-medium text-gray-900 hover:underline"},{default:d(()=>[f("more information")]),_:1})]),t("div",ee,[c($)])])])])])):g("",!0)]),t("div",se,[c(B,{path:"blog.vue"})])],64)}}});export{re as default}; +import{_ as V}from"./SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js";import{_ as Z}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o,c as n,f as j,d as F,x as H,i as I,r as N,a as t,u as s,b as c,w as d,e as f,t as a,h as b,m as g,F as k,g as L}from"./index-CoFPLbfm.js";import{L as S}from"./logo-BG60RFri.js";import{d as w,a as y,g as T}from"./utils-BDrlE94o.js";const P={},R={role:"list"},U=j('
  • Follow on Twitter
  • Follow on Instagram
  • Follow on GitHub
  • Follow on LinkedIn
  • spencer@planetaria.tech
  • ',5),D=[U];function E(A,u){return o(),n("ul",R,D)}const G=Z(P,[["render",E]]),Y={class:"container mx-auto px-5 mt-24 mb-24"},q={key:0},J={class:"mb-8 md:mb-16"},K={class:"sm:mx-0"},O=["src","alt"],Q={class:"md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28"},W={class:"mb-4 text-4xl lg:text-6xl leading-tight"},X={class:"mb-4 md:mb-0 text-lg"},tt=["datetime"],et={class:"text-lg leading-relaxed mb-4"},st=["src"],at={key:1,class:"flex items-center text-xl font-bold"},ot=["src"],lt={key:1},nt=t("h2",{class:"mb-8 text-6xl md:text-7xl font-bold tracking-tighter leading-tight"},"More from the blog",-1),it={class:"mx-auto mt-12 grid max-w-lg gap-5 lg:max-w-none lg:grid-cols-3"},rt={class:"flex flex-col overflow-hidden rounded-lg shadow-lg"},ct={class:"flex-shrink-0"},dt=["src"],ht={class:"flex flex-1 flex-col justify-between bg-white dark:bg-black p-6"},_t={class:"flex-1"},mt=t("p",{class:"text-sm font-medium text-indigo-600 dark:text-indigo-300"}," Article ",-1),ut={class:"text-xl font-semibold text-gray-900 dark:text-gray-50"},xt={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},ft={class:"mt-6 flex items-center"},gt={class:"flex-shrink-0"},vt={class:"sr-only"},pt=["src","alt"],bt={class:"ml-3"},kt={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},wt={key:1},yt={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},Ct=["datetime"],zt=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),Lt={key:2,class:"mt-24 flex justify-center"},At={class:"flex max-w-screen-lg"},Mt={class:"w-2/3"},$t={class:"border-b pb-4 mb-4"},Bt={class:"flex justify-between"},Vt={class:"w-3/4"},Zt={class:"text-xl font-semibold text-gray-900 dark:text-gray-50"},jt={class:"mt-3 text-base text-gray-500 dark:text-gray-400"},Ft={class:"mt-6 flex items-center"},Ht={class:"flex-shrink-0"},It={class:"sr-only"},Nt=["src","alt"],St={class:"ml-3"},Tt={class:"text-sm font-medium text-gray-900 dark:text-gray-50"},Pt={key:1},Rt={class:"flex space-x-1 text-sm text-gray-500 dark:text-gray-400"},Ut=["datetime"],Dt=t("span",{class:"px-1","aria-hidden":"true"},"·",-1),Et={class:"w-1/4"},Gt=["src"],Yt={key:0,class:"mt-8 text-center"},qt=t("a",{class:"text-sm font-semibold hover:underline",href:"/posts/"},"view all posts",-1),Jt=[qt],Kt={class:"w-1/3"},Ot={class:"pl-8"},Qt={class:"flex items-center"},Wt=t("span",{class:"hidden sm:block text-lg font-semibold"},"MyApp",-1),Xt={class:"p-2"},te=t("p",{class:"text-gray-500"},"I’m Spencer Sharp. I live in New York City, where I design the future.",-1),ee={class:"p-4"},se={class:"my-8 flex justify-center gap-x-4"},re=F({__name:"blog",setup(A){const u=H("press");I({title:u.blog.config.blogTitle});function _(i){return i&&u.blog.authors.some(h=>h.name.toLowerCase()==i.toLowerCase())?`/posts/author/${T(i)}`:null}function m(i){return`/posts/${i.slug}`}function M(i){return i?u.blog.authors.filter(h=>h.name.toLowerCase()==i.toLowerCase())[0]:null}function x(i){var h;return((h=M(i))==null?void 0:h.profileUrl)??"/img/profiles/user1.svg"}const v=u.blog.posts,l=v[0],C=l.author,z=v.slice(1,7),p=v.slice(7,22);return(i,h)=>{const r=N("RouterLink"),$=G,B=V;return o(),n(k,null,[t("div",Y,[s(l)?(o(),n("section",q,[t("div",J,[t("div",K,[c(r,{"aria-label":s(l).title,to:m(s(l))},{default:d(()=>[t("img",{src:s(l).image,alt:`Cover Image for ${s(l).title}`,class:"shadow-sm hover:shadow-2xl transition-shadow duration-200"},null,8,O)]),_:1},8,["aria-label","to"])])]),t("div",Q,[t("div",null,[t("h3",W,[c(r,{class:"hover:underline",to:m(s(l))},{default:d(()=>[f(a(s(l).title),1)]),_:1},8,["to"])]),t("div",X,[t("time",{datetime:s(w)(s(l).date)},a(s(y)(s(l).date)),9,tt)])]),t("div",null,[t("p",et,a(s(l).summary),1),_(s(l).author)?(o(),b(r,{key:0,class:"flex items-center text-xl font-bold",to:_(s(l).author)},{default:d(()=>[t("img",{src:x(s(l).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,st),t("span",null,a(s(C)),1)]),_:1},8,["to"])):(o(),n("span",at,[t("img",{src:x(s(l).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,ot),t("span",null,a(s(C)),1)]))])])])):g("",!0),s(z).length?(o(),n("section",lt,[nt,t("div",it,[(o(!0),n(k,null,L(s(z),e=>(o(),n("div",rt,[t("div",ct,[c(r,{to:m(e)},{default:d(()=>[t("img",{class:"h-48 w-full object-cover",src:e.image,alt:""},null,8,dt)]),_:2},1032,["to"])]),t("div",ht,[t("div",_t,[mt,c(r,{to:m(e),class:"mt-2 block"},{default:d(()=>[t("p",ut,a(e.title),1),t("p",xt,a(e.summary),1)]),_:2},1032,["to"])]),t("div",ft,[t("div",gt,[t("span",null,[t("span",vt,a(e.author),1),t("img",{class:"h-10 w-10 rounded-full",src:x(e.author),alt:`${e.title} background`},null,8,pt)])]),t("div",bt,[t("p",kt,[_(e.author)?(o(),b(r,{key:0,to:_(e.author),class:"hover:underline"},{default:d(()=>[f(a(e.author),1)]),_:2},1032,["to"])):(o(),n("span",wt,a(e.author),1))]),t("div",yt,[t("time",{datetime:s(w)(e.date)},a(s(y)(e.date)),9,Ct),zt,t("span",null,a(e.minutesToRead)+" min read",1)])])])])]))),256))])])):g("",!0),s(p).length?(o(),n("section",Lt,[t("div",At,[t("div",Mt,[(o(!0),n(k,null,L(s(p),e=>(o(),n("div",$t,[t("div",Bt,[t("div",Vt,[c(r,{to:m(e),class:"mt-2 block"},{default:d(()=>[t("p",Zt,a(e.title),1),t("p",jt,a(e.summary),1)]),_:2},1032,["to"]),t("div",Ft,[t("div",Ht,[t("span",null,[t("span",It,a(e.author),1),t("img",{class:"h-10 w-10 rounded-full",src:x(e.author),alt:`${e.title} background`},null,8,Nt)])]),t("div",St,[t("p",Tt,[_(e.author)?(o(),b(r,{key:0,to:_(e.author),class:"hover:underline"},{default:d(()=>[f(a(e.author),1)]),_:2},1032,["to"])):(o(),n("span",Pt,a(e.author),1))]),t("div",Rt,[t("time",{datetime:s(w)(e.date)},a(s(y)(e.date)),9,Ut),Dt,t("span",null,a(e.minutesToRead)+" min read",1)])])])]),t("div",Et,[c(r,{to:m(e),class:"pt-4"},{default:d(()=>[t("img",{class:"w-full object-cover max-h-[130px]",src:e.image,alt:""},null,8,Gt)]),_:2},1032,["to"])])])]))),256)),s(p).length>=15?(o(),n("div",Yt,Jt)):g("",!0)]),t("div",Kt,[t("div",Ot,[t("div",Qt,[c(s(S),{class:"w-8 h-8 mr-1",alt:"MyApp logo"}),Wt]),t("div",Xt,[te,c(r,{to:"/about",class:"text-sm font-medium text-gray-900 hover:underline"},{default:d(()=>[f("more information")]),_:1})]),t("div",ee,[c($)])])])])])):g("",!0)]),t("div",se,[c(B,{path:"blog.vue"})])],64)}}});export{re as default}; diff --git a/assets/component-links-B0AHB4nY.js b/assets/component-links-B6Jg27wb.js similarity index 85% rename from assets/component-links-B0AHB4nY.js rename to assets/component-links-B6Jg27wb.js index 87adc32..ad41d90 100644 --- a/assets/component-links-B0AHB4nY.js +++ b/assets/component-links-B6Jg27wb.js @@ -1 +1 @@ -import{_ as n}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as s,o as r,h as p,w as c,a as e}from"./index-B-kKBcPB.js";const l=e("div",{class:"markdown-body"},[e("ul",null,[e("li",null,[e("a",{href:"/posts/markdown-components-in-vue"},"Vue Components in Markdown")]),e("li",null,[e("a",{href:"https://press-react.servicestack.net/posts/markdown-components-in-react"},"React Components in Markdown")]),e("li",null,[e("a",{href:"https://razor-ssg.web-templates.io/posts/javascript"},".NET Razor SSG Vue Components in Markdown")]),e("li",null,[e("a",{href:"https://blazor-vue.web-templates.io/posts/javascript"},".NET Blazor Vue Components in Markdown")])])],-1),f=[],k={__name:"component-links",setup(m,{expose:o}){const t={meta:[]};return o({frontmatter:t}),s({meta:[]}),(d,u)=>{const a=n;return r(),p(a,{frontmatter:t},{default:c(()=>[l]),_:1})}}};export{k as default,f as meta}; +import{_ as n}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as s,o as r,h as p,w as c,a as e}from"./index-CoFPLbfm.js";const l=e("div",{class:"markdown-body"},[e("ul",null,[e("li",null,[e("a",{href:"/posts/markdown-components-in-vue"},"Vue Components in Markdown")]),e("li",null,[e("a",{href:"https://press-react.servicestack.net/posts/markdown-components-in-react"},"React Components in Markdown")]),e("li",null,[e("a",{href:"https://razor-ssg.web-templates.io/posts/javascript"},".NET Razor SSG Vue Components in Markdown")]),e("li",null,[e("a",{href:"https://blazor-vue.web-templates.io/posts/javascript"},".NET Blazor Vue Components in Markdown")])])],-1),f=[],k={__name:"component-links",setup(m,{expose:o}){const t={meta:[]};return o({frontmatter:t}),s({meta:[]}),(d,u)=>{const a=n;return r(),p(a,{frontmatter:t},{default:c(()=>[l]),_:1})}}};export{k as default,f as meta}; diff --git a/assets/components-D8n2u9I9.js b/assets/components-Q0dmsTg-.js similarity index 91% rename from assets/components-D8n2u9I9.js rename to assets/components-Q0dmsTg-.js index b1052de..3211236 100644 --- a/assets/components-D8n2u9I9.js +++ b/assets/components-Q0dmsTg-.js @@ -1 +1 @@ -import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o as s,h as l,w as c,a as e,e as o}from"./index-B-kKBcPB.js";const u=e("div",{class:"markdown-body"},[e("p",null,[o("In this video, we demonstrate using the @servicestack/vue components library for Vue.js 3 Multipage Apps (MPAs) along with the "),e("code",null,"vue-mjs"),o(" template.")]),e("p",null,"The template illustrates building content-heavy or complex sites while avoiding the intricacies of Single Page Apps (SPAs) through the use of JavaScript Modules, Tailwind, Vue.js, Razor Pages, and ServiceStack.")],-1),_="Vue 3 Tailwind Components Library",g="https://youtu.be/YIa0w6whe2U",b=["vue","autoquery"],V="14-02-2023",T=2,f=[{property:"og:title",content:"Vue 3 Tailwind Components Library"},{name:"twitter:title",content:"Vue 3 Tailwind Components Library"}],v={__name:"components",setup(p,{expose:n}){const t={title:"Vue 3 Tailwind Components Library",url:"https://youtu.be/YIa0w6whe2U",tags:["vue","autoquery"],date:"14-02-2023",order:2,meta:[{property:"og:title",content:"Vue 3 Tailwind Components Library"},{name:"twitter:title",content:"Vue 3 Tailwind Components Library"}]};return n({frontmatter:t}),r({title:"Vue 3 Tailwind Components Library",meta:[{property:"og:title",content:"Vue 3 Tailwind Components Library"},{name:"twitter:title",content:"Vue 3 Tailwind Components Library"}]}),(m,w)=>{const a=i;return s(),l(a,{frontmatter:t},{default:c(()=>[u]),_:1})}}};export{V as date,v as default,f as meta,T as order,b as tags,_ as title,g as url}; +import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o as s,h as l,w as c,a as e,e as o}from"./index-CoFPLbfm.js";const u=e("div",{class:"markdown-body"},[e("p",null,[o("In this video, we demonstrate using the @servicestack/vue components library for Vue.js 3 Multipage Apps (MPAs) along with the "),e("code",null,"vue-mjs"),o(" template.")]),e("p",null,"The template illustrates building content-heavy or complex sites while avoiding the intricacies of Single Page Apps (SPAs) through the use of JavaScript Modules, Tailwind, Vue.js, Razor Pages, and ServiceStack.")],-1),_="Vue 3 Tailwind Components Library",g="https://youtu.be/YIa0w6whe2U",b=["vue","autoquery"],V="14-02-2023",T=2,f=[{property:"og:title",content:"Vue 3 Tailwind Components Library"},{name:"twitter:title",content:"Vue 3 Tailwind Components Library"}],v={__name:"components",setup(p,{expose:n}){const t={title:"Vue 3 Tailwind Components Library",url:"https://youtu.be/YIa0w6whe2U",tags:["vue","autoquery"],date:"14-02-2023",order:2,meta:[{property:"og:title",content:"Vue 3 Tailwind Components Library"},{name:"twitter:title",content:"Vue 3 Tailwind Components Library"}]};return n({frontmatter:t}),r({title:"Vue 3 Tailwind Components Library",meta:[{property:"og:title",content:"Vue 3 Tailwind Components Library"},{name:"twitter:title",content:"Vue 3 Tailwind Components Library"}]}),(m,w)=>{const a=i;return s(),l(a,{frontmatter:t},{default:c(()=>[u]),_:1})}}};export{V as date,v as default,f as meta,T as order,b as tags,_ as title,g as url}; diff --git a/assets/counter-BqsUn9iq.js b/assets/counter-DSxYdCIG.js similarity index 82% rename from assets/counter-BqsUn9iq.js rename to assets/counter-DSxYdCIG.js index 9288c1b..f099e53 100644 --- a/assets/counter-BqsUn9iq.js +++ b/assets/counter-DSxYdCIG.js @@ -1 +1 @@ -import{_ as c}from"./SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js";import{d as r,i,j as m,r as _,o as u,c as l,a as t,t as d,b as o,w as p,e as x}from"./index-B-kKBcPB.js";const f={class:"mt-8 mb-20 mx-auto max-w-fit"},C=t("h1",{class:"mb-4 text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},"Counter",-1),h={class:"my-4"},g={class:"mt-8 flex justify-center gap-x-4"},w=r({__name:"counter",setup(y){i({title:"Counter"});const e=m(0),a=()=>e.value++;return(k,v)=>{const s=_("PrimaryButton"),n=c;return u(),l("div",f,[C,t("p",h,"Current count: "+d(e.value),1),o(s,{onClick:a},{default:p(()=>[x("Click me")]),_:1}),t("div",g,[o(n,{path:"counter.vue"})])])}}});export{w as default}; +import{_ as c}from"./SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js";import{d as r,i,j as m,r as _,o as u,c as l,a as t,t as d,b as o,w as p,e as x}from"./index-CoFPLbfm.js";const f={class:"mt-8 mb-20 mx-auto max-w-fit"},C=t("h1",{class:"mb-4 text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 sm:text-4xl"},"Counter",-1),h={class:"my-4"},g={class:"mt-8 flex justify-center gap-x-4"},w=r({__name:"counter",setup(y){i({title:"Counter"});const e=m(0),a=()=>e.value++;return(k,v)=>{const s=_("PrimaryButton"),n=c;return u(),l("div",f,[C,t("p",h,"Current count: "+d(e.value),1),o(s,{onClick:a},{default:p(()=>[x("Click me")]),_:1}),t("div",g,[o(n,{path:"counter.vue"})])])}}});export{w as default}; diff --git a/assets/default-Bpx-Aajc.js b/assets/default-Caiy_OVN.js similarity index 96% rename from assets/default-Bpx-Aajc.js rename to assets/default-Caiy_OVN.js index 0299442..b2539df 100644 --- a/assets/default-Bpx-Aajc.js +++ b/assets/default-Caiy_OVN.js @@ -1 +1 @@ -import{L as _}from"./logo-DspwJfOt.js";import{d as x,r as l,o as c,c as i,a as e,b as t,w as s,u,e as r,f as m,F as h}from"./index-B-kKBcPB.js";import{_ as p}from"./_plugin-vue_export-helper-DlAUqK2U.js";const v={class:"border-b border-gray-200 dark:border-gray-800 pr-3"},g={class:"flex flex-wrap items-center"},b={class:"absolute z-10 top-2 left-2 sm:static flex-shrink flex-grow-0"},k={class:"cursor-pointer"},y=e("span",{class:"hidden ml-2 sm:block text-2xl font-semibold"},"My App",-1),w={class:"flex flex-grow flex-shrink flex-nowrap justify-end items-center"},j={class:"relative flex flex-grow leading-6 font-semibold text-slate-700 dark:text-slate-200"},$={class:"flex flex-wrap items-center justify-end w-full m-0"},A={class:"relative flex flex-wrap just-fu-start m-0"},C={class:"relative flex flex-wrap just-fu-start m-0"},N={class:"relative flex flex-wrap just-fu-start m-0"},V={class:"relative flex flex-wrap just-fu-start m-0"},R={class:"relative flex flex-wrap just-fu-start m-0"},L=x({__name:"NavHeader",setup(n){return(d,o)=>{const a=l("RouterLink"),f=l("DarkModeToggle");return c(),i("header",v,[e("div",g,[e("div",b,[e("div",k,[t(a,{to:"/",class:"navbar-brand flex items-center"},{default:s(()=>[t(u(_),{class:"w-8 h-8 sm:ml-2 sm:w-12 sm:h-12",alt:"MyApp logo"}),y]),_:1})])]),e("div",w,[e("nav",j,[e("ul",$,[e("li",A,[t(a,{to:"/counter",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("Counter")]),_:1})]),e("li",C,[t(a,{to:"/whatsnew",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("What's New")]),_:1})]),e("li",N,[t(a,{to:"/blog",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("Blog")]),_:1})]),e("li",V,[t(a,{to:"/videos",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("Videos")]),_:1})]),e("li",R,[t(f)])])])])])])}}}),B={},F={class:"bg-slate-50 dark:bg-slate-900 border-t border-slate-200 dark:border-slate-800"},M={class:"pt-8 columns-2 sm:flex sm:justify-center sm:space-x-12","aria-label":"Footer"},T={class:"pb-6"},D={class:"pb-6"},S={class:"pb-6"},H=m('',1);function P(n,d){const o=l("RouterLink");return c(),i("footer",F,[e("nav",M,[e("div",T,[t(o,{to:"/about",class:"text-sm leading-6 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-50"},{default:s(()=>[r("About")]),_:1})]),e("div",D,[t(o,{to:"/posts",class:"text-sm leading-6 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-50"},{default:s(()=>[r("Archive")]),_:1})]),e("div",S,[t(o,{to:"/privacy",class:"text-sm leading-6 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-50"},{default:s(()=>[r("Privacy")]),_:1})])]),H])}const z=p(B,[["render",P]]),E={class:"min-h-screen"},G={role:"main"},J=x({__name:"default",setup(n){return(d,o)=>{const a=l("RouterView");return c(),i(h,null,[t(L),e("div",E,[e("main",G,[t(a)])]),t(z)],64)}}});export{J as default}; +import{L as _}from"./logo-BG60RFri.js";import{d as x,r as l,o as c,c as i,a as e,b as t,w as s,u,e as r,f as m,F as h}from"./index-CoFPLbfm.js";import{_ as p}from"./_plugin-vue_export-helper-DlAUqK2U.js";const v={class:"border-b border-gray-200 dark:border-gray-800 pr-3"},g={class:"flex flex-wrap items-center"},b={class:"absolute z-10 top-2 left-2 sm:static flex-shrink flex-grow-0"},k={class:"cursor-pointer"},y=e("span",{class:"hidden ml-2 sm:block text-2xl font-semibold"},"My App",-1),w={class:"flex flex-grow flex-shrink flex-nowrap justify-end items-center"},j={class:"relative flex flex-grow leading-6 font-semibold text-slate-700 dark:text-slate-200"},$={class:"flex flex-wrap items-center justify-end w-full m-0"},A={class:"relative flex flex-wrap just-fu-start m-0"},C={class:"relative flex flex-wrap just-fu-start m-0"},N={class:"relative flex flex-wrap just-fu-start m-0"},V={class:"relative flex flex-wrap just-fu-start m-0"},R={class:"relative flex flex-wrap just-fu-start m-0"},L=x({__name:"NavHeader",setup(n){return(d,o)=>{const a=l("RouterLink"),f=l("DarkModeToggle");return c(),i("header",v,[e("div",g,[e("div",b,[e("div",k,[t(a,{to:"/",class:"navbar-brand flex items-center"},{default:s(()=>[t(u(_),{class:"w-8 h-8 sm:ml-2 sm:w-12 sm:h-12",alt:"MyApp logo"}),y]),_:1})])]),e("div",w,[e("nav",j,[e("ul",$,[e("li",A,[t(a,{to:"/counter",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("Counter")]),_:1})]),e("li",C,[t(a,{to:"/whatsnew",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("What's New")]),_:1})]),e("li",N,[t(a,{to:"/blog",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("Blog")]),_:1})]),e("li",V,[t(a,{to:"/videos",class:"p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400",ActiveClass:"text-blue-700 dark:text-blue-300"},{default:s(()=>[r("Videos")]),_:1})]),e("li",R,[t(f)])])])])])])}}}),B={},F={class:"bg-slate-50 dark:bg-slate-900 border-t border-slate-200 dark:border-slate-800"},M={class:"pt-8 columns-2 sm:flex sm:justify-center sm:space-x-12","aria-label":"Footer"},T={class:"pb-6"},D={class:"pb-6"},S={class:"pb-6"},H=m('',1);function P(n,d){const o=l("RouterLink");return c(),i("footer",F,[e("nav",M,[e("div",T,[t(o,{to:"/about",class:"text-sm leading-6 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-50"},{default:s(()=>[r("About")]),_:1})]),e("div",D,[t(o,{to:"/posts",class:"text-sm leading-6 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-50"},{default:s(()=>[r("Archive")]),_:1})]),e("div",S,[t(o,{to:"/privacy",class:"text-sm leading-6 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-50"},{default:s(()=>[r("Privacy")]),_:1})])]),H])}const z=p(B,[["render",P]]),E={class:"min-h-screen"},G={role:"main"},J=x({__name:"default",setup(n){return(d,o)=>{const a=l("RouterView");return c(),i(h,null,[t(L),e("div",E,[e("main",G,[t(a)])]),t(z)],64)}}});export{J as default}; diff --git a/assets/empty-BlQdiYK7.js b/assets/empty-u1n3FCjQ.js similarity index 81% rename from assets/empty-BlQdiYK7.js rename to assets/empty-u1n3FCjQ.js index 7012222..4358f87 100644 --- a/assets/empty-BlQdiYK7.js +++ b/assets/empty-u1n3FCjQ.js @@ -1 +1 @@ -import{_ as t}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{r as o,o as c,c as r,b as n}from"./index-B-kKBcPB.js";const s={},a={class:"h-screen px-4 text-black bg-white text-center flex flex-col items-center justify-center"};function _(i,m){const e=o("router-view");return c(),r("main",a,[n(e)])}const p=t(s,[["render",_]]);export{p as default}; +import{_ as t}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{r as o,o as c,c as r,b as n}from"./index-CoFPLbfm.js";const s={},a={class:"h-screen px-4 text-black bg-white text-center flex flex-col items-center justify-center"};function _(i,m){const e=o("router-view");return c(),r("main",a,[n(e)])}const p=t(s,[["render",_]]);export{p as default}; diff --git a/assets/feature1-BJlXHRzt.js b/assets/feature1-CYSjmA7I.js similarity index 94% rename from assets/feature1-BJlXHRzt.js rename to assets/feature1-CYSjmA7I.js index 1f3444d..55fafe3 100644 --- a/assets/feature1-BJlXHRzt.js +++ b/assets/feature1-CYSjmA7I.js @@ -1 +1 @@ -import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o as i,h as s,w as l,a as e}from"./index-B-kKBcPB.js";const c=e("div",{class:"markdown-body"},[e("p",null,"Welcome to the world of Planetaria, a groundbreaking new product that is poised to revolutionize the way we explore space. At Planetaria, we believe that the wonders of space should be accessible to everyone, not just a privileged few. That’s why we’ve created technology that empowers civilians to explore space on their own terms, without needing to rely on government agencies or billionaire entrepreneurs."),e("p",null,"Our mission is to democratize space exploration and enable people from all walks of life to experience the thrill of venturing beyond our planet. With Planetaria, you’ll have the tools and resources you need to embark on your own space missions, whether you’re a hobbyist, a scientist, or an adventurer. From designing and building your own spacecraft to conducting experiments in microgravity, the possibilities are endless.")],-1),u="Planetaria",y="http://planetaria.tech",_="/img/whatsnew/planetaria.svg",v=[{property:"og:title",content:"Planetaria"},{name:"twitter:title",content:"Planetaria"},{property:"og:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:card",content:"summary_large_image"}],f={__name:"feature1",setup(m,{expose:a}){const t={title:"Planetaria",url:"http://planetaria.tech",image:"/img/whatsnew/planetaria.svg",meta:[{property:"og:title",content:"Planetaria"},{name:"twitter:title",content:"Planetaria"},{property:"og:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:card",content:"summary_large_image"}]};return a({frontmatter:t}),r({title:"Planetaria",meta:[{property:"og:title",content:"Planetaria"},{name:"twitter:title",content:"Planetaria"},{property:"og:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:card",content:"summary_large_image"}]}),(g,w)=>{const n=o;return i(),s(n,{frontmatter:t},{default:l(()=>[c]),_:1})}}};export{f as default,_ as image,v as meta,u as title,y as url}; +import{_ as o}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o as i,h as s,w as l,a as e}from"./index-CoFPLbfm.js";const c=e("div",{class:"markdown-body"},[e("p",null,"Welcome to the world of Planetaria, a groundbreaking new product that is poised to revolutionize the way we explore space. At Planetaria, we believe that the wonders of space should be accessible to everyone, not just a privileged few. That’s why we’ve created technology that empowers civilians to explore space on their own terms, without needing to rely on government agencies or billionaire entrepreneurs."),e("p",null,"Our mission is to democratize space exploration and enable people from all walks of life to experience the thrill of venturing beyond our planet. With Planetaria, you’ll have the tools and resources you need to embark on your own space missions, whether you’re a hobbyist, a scientist, or an adventurer. From designing and building your own spacecraft to conducting experiments in microgravity, the possibilities are endless.")],-1),u="Planetaria",y="http://planetaria.tech",_="/img/whatsnew/planetaria.svg",v=[{property:"og:title",content:"Planetaria"},{name:"twitter:title",content:"Planetaria"},{property:"og:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:card",content:"summary_large_image"}],f={__name:"feature1",setup(m,{expose:a}){const t={title:"Planetaria",url:"http://planetaria.tech",image:"/img/whatsnew/planetaria.svg",meta:[{property:"og:title",content:"Planetaria"},{name:"twitter:title",content:"Planetaria"},{property:"og:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:card",content:"summary_large_image"}]};return a({frontmatter:t}),r({title:"Planetaria",meta:[{property:"og:title",content:"Planetaria"},{name:"twitter:title",content:"Planetaria"},{property:"og:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:image",content:"/img/whatsnew/planetaria.svg"},{name:"twitter:card",content:"summary_large_image"}]}),(g,w)=>{const n=o;return i(),s(n,{frontmatter:t},{default:l(()=>[c]),_:1})}}};export{f as default,_ as image,v as meta,u as title,y as url}; diff --git a/assets/feature1-B0cK-EMF.js b/assets/feature1-CvHTx5Sl.js similarity index 94% rename from assets/feature1-B0cK-EMF.js rename to assets/feature1-CvHTx5Sl.js index 8d9d352..c4d02e7 100644 --- a/assets/feature1-B0cK-EMF.js +++ b/assets/feature1-CvHTx5Sl.js @@ -1 +1 @@ -import{_ as a}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as s,o as i,h as r,w as l,a as t}from"./index-B-kKBcPB.js";const h=t("div",{class:"markdown-body"},[t("p",null,"Introducing OpenShuttle, the revolutionary new product that is set to change the space industry forever. OpenShuttle is a cutting-edge platform that provides detailed schematics for the very first rocket designed by me, which successfully made it to orbit. This incredible product is designed to give space enthusiasts and professionals alike access to the groundbreaking technology that was used to achieve this monumental feat."),t("p",null,"OpenShuttle is the result of years of hard work and dedication, and I am thrilled to finally be able to share it with the world. With its detailed schematics, OpenShuttle provides an unprecedented level of insight into the inner workings of the rocket, allowing users to explore the technology that made history.")],-1),w="OpenShuttle",_="https://example.org",f="/img/whatsnew/open-shuttle.svg",y=[{property:"og:title",content:"OpenShuttle"},{name:"twitter:title",content:"OpenShuttle"},{property:"og:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:card",content:"summary_large_image"}],v={__name:"feature1",setup(c,{expose:n}){const e={title:"OpenShuttle",url:"https://example.org",image:"/img/whatsnew/open-shuttle.svg",meta:[{property:"og:title",content:"OpenShuttle"},{name:"twitter:title",content:"OpenShuttle"},{property:"og:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:card",content:"summary_large_image"}]};return n({frontmatter:e}),s({title:"OpenShuttle",meta:[{property:"og:title",content:"OpenShuttle"},{name:"twitter:title",content:"OpenShuttle"},{property:"og:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:card",content:"summary_large_image"}]}),(p,g)=>{const o=a;return i(),r(o,{frontmatter:e},{default:l(()=>[h]),_:1})}}};export{v as default,f as image,y as meta,w as title,_ as url}; +import{_ as a}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as s,o as i,h as r,w as l,a as t}from"./index-CoFPLbfm.js";const h=t("div",{class:"markdown-body"},[t("p",null,"Introducing OpenShuttle, the revolutionary new product that is set to change the space industry forever. OpenShuttle is a cutting-edge platform that provides detailed schematics for the very first rocket designed by me, which successfully made it to orbit. This incredible product is designed to give space enthusiasts and professionals alike access to the groundbreaking technology that was used to achieve this monumental feat."),t("p",null,"OpenShuttle is the result of years of hard work and dedication, and I am thrilled to finally be able to share it with the world. With its detailed schematics, OpenShuttle provides an unprecedented level of insight into the inner workings of the rocket, allowing users to explore the technology that made history.")],-1),w="OpenShuttle",_="https://example.org",f="/img/whatsnew/open-shuttle.svg",y=[{property:"og:title",content:"OpenShuttle"},{name:"twitter:title",content:"OpenShuttle"},{property:"og:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:card",content:"summary_large_image"}],v={__name:"feature1",setup(c,{expose:n}){const e={title:"OpenShuttle",url:"https://example.org",image:"/img/whatsnew/open-shuttle.svg",meta:[{property:"og:title",content:"OpenShuttle"},{name:"twitter:title",content:"OpenShuttle"},{property:"og:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:card",content:"summary_large_image"}]};return n({frontmatter:e}),s({title:"OpenShuttle",meta:[{property:"og:title",content:"OpenShuttle"},{name:"twitter:title",content:"OpenShuttle"},{property:"og:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:image",content:"/img/whatsnew/open-shuttle.svg"},{name:"twitter:card",content:"summary_large_image"}]}),(p,g)=>{const o=a;return i(),r(o,{frontmatter:e},{default:l(()=>[h]),_:1})}}};export{v as default,f as image,y as meta,w as title,_ as url}; diff --git a/assets/feature1-B9tl-y8M.js b/assets/feature1-FhqPQYoT.js similarity index 93% rename from assets/feature1-B9tl-y8M.js rename to assets/feature1-FhqPQYoT.js index 753b199..65244a1 100644 --- a/assets/feature1-B9tl-y8M.js +++ b/assets/feature1-FhqPQYoT.js @@ -1 +1 @@ -import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o,h as m,w as s,a as t}from"./index-B-kKBcPB.js";const g=t("div",{class:"markdown-body"},[t("p",null,"Introducing Animaginary, the next generation web animation library that’s taking the world by storm. Animaginary is a high performance library that’s hand-written in optimized WebAssembly (WASM), making it one of the fastest and most efficient animation tools available today."),t("p",null,"Built with performance in mind, Animaginary delivers stunning animations that are both smooth and seamless, even on lower-end devices. The library is designed to provide developers with a powerful toolset that makes it easy to create complex animations that would otherwise be time-consuming and challenging to build.")],-1),p="Animaginary",_="/blog",u="/img/whatsnew/animaginary.svg",f=[{property:"og:title",content:"Animaginary"},{name:"twitter:title",content:"Animaginary"},{property:"og:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:card",content:"summary_large_image"}],v={__name:"feature1",setup(c,{expose:e}){const a={title:"Animaginary",url:"/blog",image:"/img/whatsnew/animaginary.svg",meta:[{property:"og:title",content:"Animaginary"},{name:"twitter:title",content:"Animaginary"},{property:"og:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:card",content:"summary_large_image"}]};return e({frontmatter:a}),r({title:"Animaginary",meta:[{property:"og:title",content:"Animaginary"},{name:"twitter:title",content:"Animaginary"},{property:"og:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:card",content:"summary_large_image"}]}),(w,y)=>{const n=i;return o(),m(n,{frontmatter:a},{default:s(()=>[g]),_:1})}}};export{v as default,u as image,f as meta,p as title,_ as url}; +import{_ as i}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o,h as m,w as s,a as t}from"./index-CoFPLbfm.js";const g=t("div",{class:"markdown-body"},[t("p",null,"Introducing Animaginary, the next generation web animation library that’s taking the world by storm. Animaginary is a high performance library that’s hand-written in optimized WebAssembly (WASM), making it one of the fastest and most efficient animation tools available today."),t("p",null,"Built with performance in mind, Animaginary delivers stunning animations that are both smooth and seamless, even on lower-end devices. The library is designed to provide developers with a powerful toolset that makes it easy to create complex animations that would otherwise be time-consuming and challenging to build.")],-1),p="Animaginary",_="/blog",u="/img/whatsnew/animaginary.svg",f=[{property:"og:title",content:"Animaginary"},{name:"twitter:title",content:"Animaginary"},{property:"og:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:card",content:"summary_large_image"}],v={__name:"feature1",setup(c,{expose:e}){const a={title:"Animaginary",url:"/blog",image:"/img/whatsnew/animaginary.svg",meta:[{property:"og:title",content:"Animaginary"},{name:"twitter:title",content:"Animaginary"},{property:"og:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:card",content:"summary_large_image"}]};return e({frontmatter:a}),r({title:"Animaginary",meta:[{property:"og:title",content:"Animaginary"},{name:"twitter:title",content:"Animaginary"},{property:"og:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:image",content:"/img/whatsnew/animaginary.svg"},{name:"twitter:card",content:"summary_large_image"}]}),(w,y)=>{const n=i;return o(),m(n,{frontmatter:a},{default:s(()=>[g]),_:1})}}};export{v as default,u as image,f as meta,p as title,_ as url}; diff --git a/assets/features-DgyWH2Q5.js b/assets/features-nHCxd1P1.js similarity index 95% rename from assets/features-DgyWH2Q5.js rename to assets/features-nHCxd1P1.js index cdf4f52..b9b66c6 100644 --- a/assets/features-DgyWH2Q5.js +++ b/assets/features-nHCxd1P1.js @@ -1 +1 @@ -import{_ as a}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as s,o,h as r,w as i,a as t}from"./index-B-kKBcPB.js";const u=t("div",{class:"markdown-body"},[t("table",null,[t("thead",null,[t("tr",null,[t("th"),t("th")])]),t("tbody",null,[t("tr",null,[t("td",null,[t("a",{href:"https://vitejs.dev"},"Vite")]),t("td",null,"Modern typed design, Lighting fast reloads, optimal builds")]),t("tr",null,[t("td",null,[t("a",{href:"https://v3.vuejs.org"},"Vue3")]),t("td",null,"Elegant, composable reactive typed fx for small & large Apps")]),t("tr",null,[t("td",null,[t("a",{href:"https://www.typescriptlang.org"},"TypeScript")]),t("td",null,"Advanced type-safety, static analysis and richer IDE tooling")]),t("tr",null,[t("td",null,[t("a",{href:"https://tailwindcss.com"},"Tailwindcss")]),t("td",null,"Productive responsive-first utility-based css framework")]),t("tr",null,[t("td",null,[t("a",{href:"https://tailwindcss-typography.vercel.app"},"tailwind/typography")]),t("td",null,"Beautiful css typography for markdown articles & blog posts")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/tailwindlabs/tailwindcss-forms"},"tailwind/forms")]),t("td",null,"Beautiful css form & input styles that’s easily overridable")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/markdown-it/markdown-it"},"Markdown")]),t("td",null,"Native Markdown integration")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/ServiceStack/vite-plugin-press"},"plugin/press")]),t("td",null,"Static markdown for creating blogs, videos and other content")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/posva/unplugin-vue-router"},"plugin/vue-router")]),t("td",null,"Conventional file system based routing for Vue 3 on Vite")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/JohnCampionJr/vite-plugin-vue-layouts"},"plugin/layouts")]),t("td",null,"Support for multiple page layouts")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/antfu/unplugin-vue-components"},"plugin/components")]),t("td",null,"Auto importing & registering of components on-demand")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/jpkleemans/vite-svg-loader"},"plugin/svg")]),t("td",null,"Load SVG files as Vue components")]),t("tr",null,[t("td",null,[t("a",{href:"https://iconify.design"},"Iconify")]),t("td",null,"Unified registry to access 100k+ high quality SVG icons")])])])],-1),m=[],y={__name:"features",setup(d,{expose:n}){const l={meta:[]};return n({frontmatter:l}),s({meta:[]}),(c,h)=>{const e=a;return o(),r(e,{frontmatter:l},{default:i(()=>[u]),_:1})}}};export{y as default,m as meta}; +import{_ as a}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as s,o,h as r,w as i,a as t}from"./index-CoFPLbfm.js";const u=t("div",{class:"markdown-body"},[t("table",null,[t("thead",null,[t("tr",null,[t("th"),t("th")])]),t("tbody",null,[t("tr",null,[t("td",null,[t("a",{href:"https://vitejs.dev"},"Vite")]),t("td",null,"Modern typed design, Lighting fast reloads, optimal builds")]),t("tr",null,[t("td",null,[t("a",{href:"https://v3.vuejs.org"},"Vue3")]),t("td",null,"Elegant, composable reactive typed fx for small & large Apps")]),t("tr",null,[t("td",null,[t("a",{href:"https://www.typescriptlang.org"},"TypeScript")]),t("td",null,"Advanced type-safety, static analysis and richer IDE tooling")]),t("tr",null,[t("td",null,[t("a",{href:"https://tailwindcss.com"},"Tailwindcss")]),t("td",null,"Productive responsive-first utility-based css framework")]),t("tr",null,[t("td",null,[t("a",{href:"https://tailwindcss-typography.vercel.app"},"tailwind/typography")]),t("td",null,"Beautiful css typography for markdown articles & blog posts")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/tailwindlabs/tailwindcss-forms"},"tailwind/forms")]),t("td",null,"Beautiful css form & input styles that’s easily overridable")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/markdown-it/markdown-it"},"Markdown")]),t("td",null,"Native Markdown integration")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/ServiceStack/vite-plugin-press"},"plugin/press")]),t("td",null,"Static markdown for creating blogs, videos and other content")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/posva/unplugin-vue-router"},"plugin/vue-router")]),t("td",null,"Conventional file system based routing for Vue 3 on Vite")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/JohnCampionJr/vite-plugin-vue-layouts"},"plugin/layouts")]),t("td",null,"Support for multiple page layouts")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/antfu/unplugin-vue-components"},"plugin/components")]),t("td",null,"Auto importing & registering of components on-demand")]),t("tr",null,[t("td",null,[t("a",{href:"https://github.com/jpkleemans/vite-svg-loader"},"plugin/svg")]),t("td",null,"Load SVG files as Vue components")]),t("tr",null,[t("td",null,[t("a",{href:"https://iconify.design"},"Iconify")]),t("td",null,"Unified registry to access 100k+ high quality SVG icons")])])])],-1),m=[],y={__name:"features",setup(d,{expose:n}){const l={meta:[]};return n({frontmatter:l}),s({meta:[]}),(c,h)=>{const e=a;return o(),r(e,{frontmatter:l},{default:i(()=>[u]),_:1})}}};export{y as default,m as meta}; diff --git a/assets/index-B-kKBcPB.js b/assets/index-CoFPLbfm.js similarity index 99% rename from assets/index-B-kKBcPB.js rename to assets/index-CoFPLbfm.js index 4deb2ba..cf444d6 100644 --- a/assets/index-B-kKBcPB.js +++ b/assets/index-CoFPLbfm.js @@ -50,11 +50,11 @@ var Zd=Object.defineProperty;var Xd=(e,t,n)=>t in e?Zd(e,t,{enumerable:!0,config `,"");function M(){if(r.length===0)return!1;const _=v.value,H=r.pop();return a.push({value:_.value,selectionStart:_.selectionStart,selectionEnd:_.selectionEnd}),A(H),!0}function U(){if(a.length===0)return!1;const _=v.value,H=a.pop();return r.push({value:_.value,selectionStart:_.selectionStart,selectionEnd:_.selectionEnd}),A(H),!0}const X=()=>null;return Ct(()=>{r=[],a=[];const _=v.value;_.onkeydown=H=>{if(H.key==="Escape"||H.keyCode===27){s("close");return}const de=String.fromCharCode(H.keyCode).toLowerCase();de===" "?(H.shiftKey?N("","","",{filterValue:(W,be)=>{let{selPos:R,beforeSel:ue,afterSel:E,prevCRPos:q,beforeCR:O,afterCR:I}=$();if(q>=0){let ae=I.replace(/\t/g," ").replace(/^ ? ? ? ?/,"");ue=O+ae,be.pos-=I.length-ae.length}return ue+E},filterSelection:W=>W.replace(/\t/g," ").replace(/^ ? ? ? ?/g,"").replace(/\n /g,` `)}):N("",""," ",{selectionAtEnd:!0,filterSelection:W=>" "+W.replace(/\n$/,"").replace(/\n/g,` `)+` -`}),H.preventDefault()):H.ctrlKey?de==="z"?H.shiftKey?U()&&H.preventDefault():M()&&H.preventDefault():de==="b"&&!H.shiftKey?(B(),H.preventDefault()):de==="h"&&!H.shiftKey?(pe(),H.preventDefault()):de==="i"&&!H.shiftKey?(D(),H.preventDefault()):de==="q"&&!H.shiftKey?(Z(),H.preventDefault()):de==="k"?H.shiftKey?(ge(),H.preventDefault()):(ne(),H.preventDefault()):de===","||H.key==="<"||H.key===">"||H.keyCode===188?(re(H),H.preventDefault()):de==="/"||H.key==="/"?(J(),H.preventDefault()):(de==="?"||H.key==="?")&&H.shiftKey&&(ie(),H.preventDefault()):H.altKey&&(H.key==="1"||H.key==="0"?(se(),H.preventDefault()):H.key==="-"?(ve(),H.preventDefault()):H.key==="s"&&(P(),H.preventDefault()))}}),(_,H)=>{var de;return h(),y("div",null,[he(_.$slots,"header",Ue({inputElement:v.value,id:_.id,modelValue:_.modelValue,status:_.status},_.$attrs)),u.value?(h(),y("label",{key:0,for:_.id,class:L(`mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300 ${_.labelClass??""}`)},te(u.value),11,FC)):F("",!0),_.disabled?F("",!0):(h(),y("div",UC,[d("div",WC,[f("bold")?(h(),y("svg",{key:0,class:L(xt),onClick:B,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},JC)):F("",!0),f("italics")?(h(),y("svg",{key:1,class:L(xt),onClick:D,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},YC)):F("",!0),f("link")?(h(),y("svg",{key:2,class:L(xt),onClick:ne,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},e5)):F("",!0),f("blockquote")?(h(),y("svg",{key:3,class:L(xt),onClick:Z,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},o5)):F("",!0),f("image")?(h(),y("svg",{key:4,class:L(xt),onClick:ge,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},a5)):F("",!0),f("code")?(h(),y("svg",{key:5,class:L(xt),onClick:re,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},u5)):F("",!0),f("heading")?(h(),y("svg",{key:6,class:L(xt),onClick:pe,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},p5)):F("",!0),f("orderedList")?(h(),y("svg",{key:7,class:L(xt),icon:"",onClick:se,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},m5)):F("",!0),f("unorderedList")?(h(),y("svg",{key:8,class:L(xt),onClick:ve,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},y5)):F("",!0),f("strikethrough")?(h(),y("svg",{key:9,class:L(xt),onClick:P,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},k5)):F("",!0),f("undo")?(h(),y("svg",{key:10,class:L(xt),onClick:M,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},S5)):F("",!0),f("redo")?(h(),y("svg",{key:11,class:L(xt),onClick:U,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},_5)):F("",!0),he(_.$slots,"toolbarbuttons",{instance:(de=Xe())==null?void 0:de.exposed})]),f("help")&&_.helpUrl?(h(),y("div",M5,[d("a",{title:"formatting help",target:"_blank",href:_.helpUrl,tabindex:"-1"},[(h(),y("svg",{class:L(xt),xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},I5))],8,P5)])):F("",!0)])),d("div",L5,[d("textarea",{ref_key:"txt",ref:v,name:_.id,id:_.id,class:L(m.value),label:_.label,value:_.modelValue,rows:_.rows||6,disabled:_.disabled,onInput:H[0]||(H[0]=W=>{var be;return w(((be=W.target)==null?void 0:be.value)||"")}),onKeydown:Tc(X,["tab"])},null,42,z5)]),i.value?(h(),y("p",{key:2,class:"mt-2 text-sm text-red-500",id:`${_.id}-error`},te(i.value),9,R5)):_.help?(h(),y("p",{key:3,class:"mt-2 text-sm text-gray-500",id:`${_.id}-description`},te(_.help),9,j5)):F("",!0),he(_.$slots,"footer",Ue({inputElement:v.value,id:_.id,modelValue:_.modelValue,status:_.status},_.$attrs))])}}}),O5={key:0,class:"relative z-10 lg:hidden",role:"dialog","aria-modal":"true"},B5={class:"fixed inset-0 flex"},D5=d("span",{class:"sr-only"},"Close sidebar",-1),H5=d("svg",{class:"h-6 w-6 text-white dark:text-black",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor","aria-hidden":"true"},[d("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M6 18L18 6M6 6l12 12"})],-1),$5=[D5,H5],N5={class:"flex grow flex-col gap-y-5 overflow-y-auto bg-white dark:bg-black px-6 pb-2"},F5={class:"hidden lg:fixed lg:inset-y-0 lg:z-10 lg:flex lg:w-72 lg:flex-col"},U5={class:"flex grow flex-col gap-y-5 overflow-y-auto border-r border-gray-200 dark:border-gray-700 bg-white dark:bg-black px-6"},W5={class:L(["sticky top-0 flex items-center gap-x-6 bg-white dark:bg-black px-4 py-4 shadow-sm sm:px-6 lg:hidden"])},q5=d("span",{class:"sr-only"},"Open sidebar",-1),G5=d("svg",{class:"h-6 w-6",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor","aria-hidden":"true"},[d("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"})],-1),J5=[q5,G5],Q5=Ce({__name:"SidebarLayout",setup(e,{expose:t}){const{transition:n}=Fc(),o=Y(!0),s=Y(""),r={entering:{cls:"transition-opacity ease-linear duration-300",from:"opacity-0",to:"opacity-100"},leaving:{cls:"transition-opacity ease-linear duration-300",from:"opacity-100",to:"opacity-0"}},a=Y(""),l={entering:{cls:"transition ease-in-out duration-300 transform",from:"-translate-x-full",to:"translate-x-0"},leaving:{cls:"transition ease-in-out duration-300 transform",from:"translate-x-0",to:"-translate-x-full"}},i=Y(""),u={entering:{cls:"ease-in-out duration-300",from:"opacity-0",to:"opacity-100"},leaving:{cls:"ease-in-out duration-300",from:"opacity-100",to:"opacity-0"}};function c(m){n(r,s,m),n(l,a,m),n(u,i,m),setTimeout(()=>o.value=m,300)}function p(){c(!0)}function f(){c(!1)}return t({show:p,hide:f,toggle:c}),(m,v)=>(h(),y("div",null,[o.value?(h(),y("div",O5,[d("div",{class:L(["fixed inset-0 bg-gray-900/80",s.value])},null,2),d("div",B5,[d("div",{class:L(["relative mr-16 flex w-full max-w-xs flex-1",a.value])},[d("div",{class:L(["absolute left-full top-0 flex w-16 justify-center pt-5",i.value])},[d("button",{type:"button",onClick:f,class:"-m-2.5 p-2.5"},$5)],2),d("div",N5,[he(m.$slots,"default")])],2)])])):F("",!0),d("div",F5,[d("div",U5,[he(m.$slots,"default")])]),d("div",W5,[d("button",{type:"button",onClick:p,class:"-m-2.5 p-2.5 text-gray-700 dark:text-gray-200 lg:hidden"},J5),he(m.$slots,"mobiletitlebar")])]))}}),K5={Alert:cg,AlertSuccess:xg,ErrorSummary:_g,InputDescription:Pg,Icon:md,Loading:B0,OutlineButton:$0,PrimaryButton:U0,SecondaryButton:G0,TextLink:J0,Breadcrumbs:ev,Breadcrumb:rv,NavList:lv,NavListItem:bv,AutoQueryGrid:Nb,SettingsIcons:n1,FilterViews:wi,FilterColumn:bi,QueryPrefs:ki,EnsureAccess:yd,EnsureAccessDialog:o1,TextInput:f1,TextareaInput:w1,SelectInput:A1,CheckboxInput:R1,TagInput:nw,FileInput:Tw,Autocomplete:$w,Combobox:Uw,DynamicInput:Ww,LookupInput:i2,AutoFormFields:l2,AutoForm:I2,AutoCreateForm:Z2,AutoEditForm:bk,ConfirmDelete:kk,FormLoading:_k,DataGrid:Lk,CellFormat:zk,PreviewFormat:Dk,HtmlFormat:Uk,CloseButton:Qk,SlideOver:ux,ModalDialog:gx,ModalLookup:uC,Tabs:yC,DarkModeToggle:CC,SignIn:NC,MarkdownInput:V5,SidebarLayout:Q5},Ur=K5,Y5={install(e){Object.keys(Ur).forEach(n=>{e.component(n,Ur[n])});function t(n){const o=Object.keys(n).filter(s=>n[s]).map(s=>`${encodeURIComponent(s)}=${encodeURIComponent(n[s])}`).join("&");return o?"?"+o:"./"}e.directive("href",function(n,o){n.href=t(o.value),n.onclick=s=>{s.preventDefault(),history.pushState(o.value,"",t(o.value))}})},component(e,t){return e?t?xe.components[e]=t:xe.components[e]||Ur[e]||null:null}},Gl=[{path:"/",name:"/",component:()=>Ve(()=>import("./index-BG5anPub.js"),__vite__mapDeps([0,1,2,3,4,5]))},{path:"/:all(.*)",name:"/[...all]",component:()=>Ve(()=>import("./_...all_-ByINYo4N.js"),__vite__mapDeps([])),meta:{layout:"empty"}},{path:"/about",name:"/about",component:()=>Ve(()=>import("./about-C5lL5M9L.js"),__vite__mapDeps([6,7])),meta:{crumbs:[],frontmatter:{title:"About this Template"}}},{path:"/blog",name:"/blog",component:()=>Ve(()=>import("./blog-DsWHVwkJ.js"),__vite__mapDeps([8,1,9,10,5]))},{path:"/counter",name:"/counter",component:()=>Ve(()=>import("./counter-BqsUn9iq.js"),__vite__mapDeps([11,1]))},{path:"/posts",children:[{path:"",name:"/posts/",component:()=>Ve(()=>import("./index-DB65REeY.js"),__vite__mapDeps([12,1,13,5]))},{path:":slug",name:"/posts/[slug]",component:()=>Ve(()=>import("./_slug_-D0R-lY2g.js"),__vite__mapDeps([14,3,5]))},{path:"author",children:[{path:":name",name:"/posts/author/[name]",component:()=>Ve(()=>import("./_name_-D0WdA550.js"),__vite__mapDeps([15,13,5]))}]},{path:"tagged",children:[{path:":tag",name:"/posts/tagged/[tag]",component:()=>Ve(()=>import("./_tag_-A7_HVUVC.js"),__vite__mapDeps([16,13,5]))}]},{path:"year",children:[{path:":year",name:"/posts/year/[year]",component:()=>Ve(()=>import("./_year_-bjfw_pb5.js"),__vite__mapDeps([17,13,5]))}]}]},{path:"/privacy",name:"/privacy",component:()=>Ve(()=>import("./privacy-CgZlqKfp.js"),__vite__mapDeps([18,7])),meta:{crumbs:[],frontmatter:{title:"Privacy Policy"}}},{path:"/videos",name:"/videos",component:()=>Ve(()=>import("./videos-B48T2Bqr.js"),__vite__mapDeps([19,1,2,3]))},{path:"/whatsnew",name:"/whatsnew",component:()=>Ve(()=>import("./whatsnew-DLwuVrUY.js"),__vite__mapDeps([20,3,9,21]))}];/*! +`}),H.preventDefault()):H.ctrlKey?de==="z"?H.shiftKey?U()&&H.preventDefault():M()&&H.preventDefault():de==="b"&&!H.shiftKey?(B(),H.preventDefault()):de==="h"&&!H.shiftKey?(pe(),H.preventDefault()):de==="i"&&!H.shiftKey?(D(),H.preventDefault()):de==="q"&&!H.shiftKey?(Z(),H.preventDefault()):de==="k"?H.shiftKey?(ge(),H.preventDefault()):(ne(),H.preventDefault()):de===","||H.key==="<"||H.key===">"||H.keyCode===188?(re(H),H.preventDefault()):de==="/"||H.key==="/"?(J(),H.preventDefault()):(de==="?"||H.key==="?")&&H.shiftKey&&(ie(),H.preventDefault()):H.altKey&&(H.key==="1"||H.key==="0"?(se(),H.preventDefault()):H.key==="-"?(ve(),H.preventDefault()):H.key==="s"&&(P(),H.preventDefault()))}}),(_,H)=>{var de;return h(),y("div",null,[he(_.$slots,"header",Ue({inputElement:v.value,id:_.id,modelValue:_.modelValue,status:_.status},_.$attrs)),u.value?(h(),y("label",{key:0,for:_.id,class:L(`mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300 ${_.labelClass??""}`)},te(u.value),11,FC)):F("",!0),_.disabled?F("",!0):(h(),y("div",UC,[d("div",WC,[f("bold")?(h(),y("svg",{key:0,class:L(xt),onClick:B,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},JC)):F("",!0),f("italics")?(h(),y("svg",{key:1,class:L(xt),onClick:D,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},YC)):F("",!0),f("link")?(h(),y("svg",{key:2,class:L(xt),onClick:ne,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},e5)):F("",!0),f("blockquote")?(h(),y("svg",{key:3,class:L(xt),onClick:Z,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},o5)):F("",!0),f("image")?(h(),y("svg",{key:4,class:L(xt),onClick:ge,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},a5)):F("",!0),f("code")?(h(),y("svg",{key:5,class:L(xt),onClick:re,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},u5)):F("",!0),f("heading")?(h(),y("svg",{key:6,class:L(xt),onClick:pe,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},p5)):F("",!0),f("orderedList")?(h(),y("svg",{key:7,class:L(xt),icon:"",onClick:se,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},m5)):F("",!0),f("unorderedList")?(h(),y("svg",{key:8,class:L(xt),onClick:ve,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},y5)):F("",!0),f("strikethrough")?(h(),y("svg",{key:9,class:L(xt),onClick:P,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},k5)):F("",!0),f("undo")?(h(),y("svg",{key:10,class:L(xt),onClick:M,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},S5)):F("",!0),f("redo")?(h(),y("svg",{key:11,class:L(xt),onClick:U,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},_5)):F("",!0),he(_.$slots,"toolbarbuttons",{instance:(de=Xe())==null?void 0:de.exposed})]),f("help")&&_.helpUrl?(h(),y("div",M5,[d("a",{title:"formatting help",target:"_blank",href:_.helpUrl,tabindex:"-1"},[(h(),y("svg",{class:L(xt),xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},I5))],8,P5)])):F("",!0)])),d("div",L5,[d("textarea",{ref_key:"txt",ref:v,name:_.id,id:_.id,class:L(m.value),label:_.label,value:_.modelValue,rows:_.rows||6,disabled:_.disabled,onInput:H[0]||(H[0]=W=>{var be;return w(((be=W.target)==null?void 0:be.value)||"")}),onKeydown:Tc(X,["tab"])},null,42,z5)]),i.value?(h(),y("p",{key:2,class:"mt-2 text-sm text-red-500",id:`${_.id}-error`},te(i.value),9,R5)):_.help?(h(),y("p",{key:3,class:"mt-2 text-sm text-gray-500",id:`${_.id}-description`},te(_.help),9,j5)):F("",!0),he(_.$slots,"footer",Ue({inputElement:v.value,id:_.id,modelValue:_.modelValue,status:_.status},_.$attrs))])}}}),O5={key:0,class:"relative z-10 lg:hidden",role:"dialog","aria-modal":"true"},B5={class:"fixed inset-0 flex"},D5=d("span",{class:"sr-only"},"Close sidebar",-1),H5=d("svg",{class:"h-6 w-6 text-white dark:text-black",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor","aria-hidden":"true"},[d("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M6 18L18 6M6 6l12 12"})],-1),$5=[D5,H5],N5={class:"flex grow flex-col gap-y-5 overflow-y-auto bg-white dark:bg-black px-6 pb-2"},F5={class:"hidden lg:fixed lg:inset-y-0 lg:z-10 lg:flex lg:w-72 lg:flex-col"},U5={class:"flex grow flex-col gap-y-5 overflow-y-auto border-r border-gray-200 dark:border-gray-700 bg-white dark:bg-black px-6"},W5={class:L(["sticky top-0 flex items-center gap-x-6 bg-white dark:bg-black px-4 py-4 shadow-sm sm:px-6 lg:hidden"])},q5=d("span",{class:"sr-only"},"Open sidebar",-1),G5=d("svg",{class:"h-6 w-6",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor","aria-hidden":"true"},[d("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"})],-1),J5=[q5,G5],Q5=Ce({__name:"SidebarLayout",setup(e,{expose:t}){const{transition:n}=Fc(),o=Y(!0),s=Y(""),r={entering:{cls:"transition-opacity ease-linear duration-300",from:"opacity-0",to:"opacity-100"},leaving:{cls:"transition-opacity ease-linear duration-300",from:"opacity-100",to:"opacity-0"}},a=Y(""),l={entering:{cls:"transition ease-in-out duration-300 transform",from:"-translate-x-full",to:"translate-x-0"},leaving:{cls:"transition ease-in-out duration-300 transform",from:"translate-x-0",to:"-translate-x-full"}},i=Y(""),u={entering:{cls:"ease-in-out duration-300",from:"opacity-0",to:"opacity-100"},leaving:{cls:"ease-in-out duration-300",from:"opacity-100",to:"opacity-0"}};function c(m){n(r,s,m),n(l,a,m),n(u,i,m),setTimeout(()=>o.value=m,300)}function p(){c(!0)}function f(){c(!1)}return t({show:p,hide:f,toggle:c}),(m,v)=>(h(),y("div",null,[o.value?(h(),y("div",O5,[d("div",{class:L(["fixed inset-0 bg-gray-900/80",s.value])},null,2),d("div",B5,[d("div",{class:L(["relative mr-16 flex w-full max-w-xs flex-1",a.value])},[d("div",{class:L(["absolute left-full top-0 flex w-16 justify-center pt-5",i.value])},[d("button",{type:"button",onClick:f,class:"-m-2.5 p-2.5"},$5)],2),d("div",N5,[he(m.$slots,"default")])],2)])])):F("",!0),d("div",F5,[d("div",U5,[he(m.$slots,"default")])]),d("div",W5,[d("button",{type:"button",onClick:p,class:"-m-2.5 p-2.5 text-gray-700 dark:text-gray-200 lg:hidden"},J5),he(m.$slots,"mobiletitlebar")])]))}}),K5={Alert:cg,AlertSuccess:xg,ErrorSummary:_g,InputDescription:Pg,Icon:md,Loading:B0,OutlineButton:$0,PrimaryButton:U0,SecondaryButton:G0,TextLink:J0,Breadcrumbs:ev,Breadcrumb:rv,NavList:lv,NavListItem:bv,AutoQueryGrid:Nb,SettingsIcons:n1,FilterViews:wi,FilterColumn:bi,QueryPrefs:ki,EnsureAccess:yd,EnsureAccessDialog:o1,TextInput:f1,TextareaInput:w1,SelectInput:A1,CheckboxInput:R1,TagInput:nw,FileInput:Tw,Autocomplete:$w,Combobox:Uw,DynamicInput:Ww,LookupInput:i2,AutoFormFields:l2,AutoForm:I2,AutoCreateForm:Z2,AutoEditForm:bk,ConfirmDelete:kk,FormLoading:_k,DataGrid:Lk,CellFormat:zk,PreviewFormat:Dk,HtmlFormat:Uk,CloseButton:Qk,SlideOver:ux,ModalDialog:gx,ModalLookup:uC,Tabs:yC,DarkModeToggle:CC,SignIn:NC,MarkdownInput:V5,SidebarLayout:Q5},Ur=K5,Y5={install(e){Object.keys(Ur).forEach(n=>{e.component(n,Ur[n])});function t(n){const o=Object.keys(n).filter(s=>n[s]).map(s=>`${encodeURIComponent(s)}=${encodeURIComponent(n[s])}`).join("&");return o?"?"+o:"./"}e.directive("href",function(n,o){n.href=t(o.value),n.onclick=s=>{s.preventDefault(),history.pushState(o.value,"",t(o.value))}})},component(e,t){return e?t?xe.components[e]=t:xe.components[e]||Ur[e]||null:null}},Gl=[{path:"/",name:"/",component:()=>Ve(()=>import("./index-Da1NoZ0N.js"),__vite__mapDeps([0,1,2,3,4,5]))},{path:"/:all(.*)",name:"/[...all]",component:()=>Ve(()=>import("./_...all_-DOrRbYkV.js"),__vite__mapDeps([])),meta:{layout:"empty"}},{path:"/about",name:"/about",component:()=>Ve(()=>import("./about-CSevwr_F.js"),__vite__mapDeps([6,7])),meta:{crumbs:[],frontmatter:{title:"About this Template"}}},{path:"/blog",name:"/blog",component:()=>Ve(()=>import("./blog-NLNSyVmF.js"),__vite__mapDeps([8,1,9,10,5]))},{path:"/counter",name:"/counter",component:()=>Ve(()=>import("./counter-DSxYdCIG.js"),__vite__mapDeps([11,1]))},{path:"/posts",children:[{path:"",name:"/posts/",component:()=>Ve(()=>import("./index-Db6kjhtf.js"),__vite__mapDeps([12,1,13,5]))},{path:":slug",name:"/posts/[slug]",component:()=>Ve(()=>import("./_slug_-BaiPQcvV.js"),__vite__mapDeps([14,3,5]))},{path:"author",children:[{path:":name",name:"/posts/author/[name]",component:()=>Ve(()=>import("./_name_-D5H8wJy-.js"),__vite__mapDeps([15,13,5]))}]},{path:"tagged",children:[{path:":tag",name:"/posts/tagged/[tag]",component:()=>Ve(()=>import("./_tag_-Bl8Dgnay.js"),__vite__mapDeps([16,13,5]))}]},{path:"year",children:[{path:":year",name:"/posts/year/[year]",component:()=>Ve(()=>import("./_year_-C2Zxurez.js"),__vite__mapDeps([17,13,5]))}]}]},{path:"/privacy",name:"/privacy",component:()=>Ve(()=>import("./privacy-BP3kbvHT.js"),__vite__mapDeps([18,7])),meta:{crumbs:[],frontmatter:{title:"Privacy Policy"}}},{path:"/videos",name:"/videos",component:()=>Ve(()=>import("./videos-DZLBdRXH.js"),__vite__mapDeps([19,1,2,3]))},{path:"/whatsnew",name:"/whatsnew",component:()=>Ve(()=>import("./whatsnew-CZ_1B3HR.js"),__vite__mapDeps([20,3,9,21]))}];/*! * vue-router v4.2.5 * (c) 2023 Eduardo San Martin Morote * @license MIT - */const eo=typeof window<"u";function Z5(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const Je=Object.assign;function Wr(e,t){const n={};for(const o in t){const s=t[o];n[o]=Vt(s)?s.map(e):e(s)}return n}const jo=()=>{},Vt=Array.isArray,X5=/\/$/,e3=e=>e.replace(X5,"");function qr(e,t,n="/"){let o,s={},r="",a="";const l=t.indexOf("#");let i=t.indexOf("?");return l=0&&(i=-1),i>-1&&(o=t.slice(0,i),r=t.slice(i+1,l>-1?l:t.length),s=e(r)),l>-1&&(o=o||t.slice(0,l),a=t.slice(l,t.length)),o=s3(o??t,n),{fullPath:o+(r&&"?")+r+a,path:o,query:s,hash:a}}function t3(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Jl(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function n3(e,t,n){const o=t.matched.length-1,s=n.matched.length-1;return o>-1&&o===s&&ho(t.matched[o],n.matched[s])&&bd(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function ho(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function bd(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!o3(e[n],t[n]))return!1;return!0}function o3(e,t){return Vt(e)?Ql(e,t):Vt(t)?Ql(t,e):e===t}function Ql(e,t){return Vt(t)?e.length===t.length&&e.every((n,o)=>n===t[o]):e.length===1&&e[0]===t}function s3(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),o=e.split("/"),s=o[o.length-1];(s===".."||s===".")&&o.push("");let r=n.length-1,a,l;for(a=0;a1&&r--;else break;return n.slice(0,r).join("/")+"/"+o.slice(a-(a===o.length?1:0)).join("/")}var Jo;(function(e){e.pop="pop",e.push="push"})(Jo||(Jo={}));var Vo;(function(e){e.back="back",e.forward="forward",e.unknown=""})(Vo||(Vo={}));function r3(e){if(!e)if(eo){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),e3(e)}const a3=/^[^#]+#/;function i3(e,t){return e.replace(a3,"#")+t}function l3(e,t){const n=document.documentElement.getBoundingClientRect(),o=e.getBoundingClientRect();return{behavior:t.behavior,left:o.left-n.left-(t.left||0),top:o.top-n.top-(t.top||0)}}const xr=()=>({left:window.pageXOffset,top:window.pageYOffset});function u3(e){let t;if("el"in e){const n=e.el,o=typeof n=="string"&&n.startsWith("#"),s=typeof n=="string"?o?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!s)return;t=l3(s,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.pageXOffset,t.top!=null?t.top:window.pageYOffset)}function Kl(e,t){return(history.state?history.state.position-t:-1)+e}const xa=new Map;function c3(e,t){xa.set(e,t)}function d3(e){const t=xa.get(e);return xa.delete(e),t}let p3=()=>location.protocol+"//"+location.host;function wd(e,t){const{pathname:n,search:o,hash:s}=t,r=e.indexOf("#");if(r>-1){let l=s.includes(e.slice(r))?e.slice(r).length:1,i=s.slice(l);return i[0]!=="/"&&(i="/"+i),Jl(i,"")}return Jl(n,e)+o+s}function f3(e,t,n,o){let s=[],r=[],a=null;const l=({state:f})=>{const m=wd(e,location),v=n.value,w=t.value;let S=0;if(f){if(n.value=m,t.value=f,a&&a===v){a=null;return}S=w?f.position-w.position:0}else o(m);s.forEach(z=>{z(n.value,v,{delta:S,type:Jo.pop,direction:S?S>0?Vo.forward:Vo.back:Vo.unknown})})};function i(){a=n.value}function u(f){s.push(f);const m=()=>{const v=s.indexOf(f);v>-1&&s.splice(v,1)};return r.push(m),m}function c(){const{history:f}=window;f.state&&f.replaceState(Je({},f.state,{scroll:xr()}),"")}function p(){for(const f of r)f();r=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",c)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",c,{passive:!0}),{pauseListeners:i,listen:u,destroy:p}}function Yl(e,t,n,o=!1,s=!1){return{back:e,current:t,forward:n,replaced:o,position:window.history.length,scroll:s?xr():null}}function h3(e){const{history:t,location:n}=window,o={value:wd(e,n)},s={value:t.state};s.value||r(o.value,{back:null,current:o.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(i,u,c){const p=e.indexOf("#"),f=p>-1?(n.host&&document.querySelector("base")?e:e.slice(p))+i:p3()+e+i;try{t[c?"replaceState":"pushState"](u,"",f),s.value=u}catch(m){console.error(m),n[c?"replace":"assign"](f)}}function a(i,u){const c=Je({},t.state,Yl(s.value.back,i,s.value.forward,!0),u,{position:s.value.position});r(i,c,!0),o.value=i}function l(i,u){const c=Je({},s.value,t.state,{forward:i,scroll:xr()});r(c.current,c,!0);const p=Je({},Yl(o.value,i,null),{position:c.position+1},u);r(i,p,!1),o.value=i}return{location:o,state:s,push:l,replace:a}}function m3(e){e=r3(e);const t=h3(e),n=f3(e,t.state,t.location,t.replace);function o(r,a=!0){a||n.pauseListeners(),history.go(r)}const s=Je({location:"",base:e,go:o,createHref:i3.bind(null,e)},t,n);return Object.defineProperty(s,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(s,"state",{enumerable:!0,get:()=>t.state.value}),s}function g3(e){return typeof e=="string"||e&&typeof e=="object"}function kd(e){return typeof e=="string"||typeof e=="symbol"}const ln={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},xd=Symbol("");var Zl;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Zl||(Zl={}));function mo(e,t){return Je(new Error,{type:e,[xd]:!0},t)}function Yt(e,t){return e instanceof Error&&xd in e&&(t==null||!!(e.type&t))}const Xl="[^/]+?",v3={sensitive:!1,strict:!1,start:!0,end:!0},y3=/[.+*?^${}()[\]/\\]/g;function b3(e,t){const n=Je({},v3,t),o=[];let s=n.start?"^":"";const r=[];for(const u of e){const c=u.length?[]:[90];n.strict&&!u.length&&(s+="/");for(let p=0;pt.length?t.length===1&&t[0]===80?1:-1:0}function k3(e,t){let n=0;const o=e.score,s=t.score;for(;n0&&t[t.length-1]<0}const x3={type:0,value:""},C3=/[a-zA-Z0-9_]/;function S3(e){if(!e)return[[]];if(e==="/")return[[x3]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${u}": ${m}`)}let n=0,o=n;const s=[];let r;function a(){r&&s.push(r),r=[]}let l=0,i,u="",c="";function p(){u&&(n===0?r.push({type:0,value:u}):n===1||n===2||n===3?(r.length>1&&(i==="*"||i==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),r.push({type:1,value:u,regexp:c,repeatable:i==="*"||i==="+",optional:i==="*"||i==="?"})):t("Invalid state to consume buffer"),u="")}function f(){u+=i}for(;l{a($)}:jo}function a(c){if(kd(c)){const p=o.get(c);p&&(o.delete(c),n.splice(n.indexOf(p),1),p.children.forEach(a),p.alias.forEach(a))}else{const p=n.indexOf(c);p>-1&&(n.splice(p,1),c.record.name&&o.delete(c.record.name),c.children.forEach(a),c.alias.forEach(a))}}function l(){return n}function i(c){let p=0;for(;p=0&&(c.record.path!==n[p].record.path||!Cd(c,n[p]));)p++;n.splice(p,0,c),c.record.name&&!nu(c)&&o.set(c.record.name,c)}function u(c,p){let f,m={},v,w;if("name"in c&&c.name){if(f=o.get(c.name),!f)throw mo(1,{location:c});w=f.record.name,m=Je(tu(p.params,f.keys.filter($=>!$.optional).map($=>$.name)),c.params&&tu(c.params,f.keys.map($=>$.name))),v=f.stringify(m)}else if("path"in c)v=c.path,f=n.find($=>$.re.test(v)),f&&(m=f.parse(v),w=f.record.name);else{if(f=p.name?o.get(p.name):n.find($=>$.re.test(p.path)),!f)throw mo(1,{location:c,currentLocation:p});w=f.record.name,m=Je({},p.params,c.params),v=f.stringify(m)}const S=[];let z=f;for(;z;)S.unshift(z.record),z=z.parent;return{name:w,path:v,params:m,matched:S,meta:P3(S)}}return e.forEach(c=>r(c)),{addRoute:r,resolve:u,removeRoute:a,getRoutes:l,getRecordMatcher:s}}function tu(e,t){const n={};for(const o of t)o in e&&(n[o]=e[o]);return n}function _3(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:M3(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function M3(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const o in e.components)t[o]=typeof n=="object"?n[o]:n;return t}function nu(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function P3(e){return e.reduce((t,n)=>Je(t,n.meta),{})}function ou(e,t){const n={};for(const o in e)n[o]=o in t?t[o]:e[o];return n}function Cd(e,t){return t.children.some(n=>n===e||Cd(e,n))}const Sd=/#/g,E3=/&/g,I3=/\//g,L3=/=/g,z3=/\?/g,Td=/\+/g,R3=/%5B/g,j3=/%5D/g,Ad=/%5E/g,V3=/%60/g,_d=/%7B/g,O3=/%7C/g,Md=/%7D/g,B3=/%20/g;function xi(e){return encodeURI(""+e).replace(O3,"|").replace(R3,"[").replace(j3,"]")}function D3(e){return xi(e).replace(_d,"{").replace(Md,"}").replace(Ad,"^")}function Ca(e){return xi(e).replace(Td,"%2B").replace(B3,"+").replace(Sd,"%23").replace(E3,"%26").replace(V3,"`").replace(_d,"{").replace(Md,"}").replace(Ad,"^")}function H3(e){return Ca(e).replace(L3,"%3D")}function $3(e){return xi(e).replace(Sd,"%23").replace(z3,"%3F")}function N3(e){return e==null?"":$3(e).replace(I3,"%2F")}function er(e){try{return decodeURIComponent(""+e)}catch{}return""+e}function F3(e){const t={};if(e===""||e==="?")return t;const o=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;sr&&Ca(r)):[o&&Ca(o)]).forEach(r=>{r!==void 0&&(t+=(t.length?"&":"")+n,r!=null&&(t+="="+r))})}return t}function U3(e){const t={};for(const n in e){const o=e[n];o!==void 0&&(t[n]=Vt(o)?o.map(s=>s==null?null:""+s):o==null?o:""+o)}return t}const W3=Symbol(""),ru=Symbol(""),Cr=Symbol(""),Ci=Symbol(""),Sa=Symbol("");function So(){let e=[];function t(o){return e.push(o),()=>{const s=e.indexOf(o);s>-1&&e.splice(s,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function fn(e,t,n,o,s){const r=o&&(o.enterCallbacks[s]=o.enterCallbacks[s]||[]);return()=>new Promise((a,l)=>{const i=p=>{p===!1?l(mo(4,{from:n,to:t})):p instanceof Error?l(p):g3(p)?l(mo(2,{from:t,to:p})):(r&&o.enterCallbacks[s]===r&&typeof p=="function"&&r.push(p),a())},u=e.call(o&&o.instances[s],t,n,i);let c=Promise.resolve(u);e.length<3&&(c=c.then(i)),c.catch(p=>l(p))})}function Gr(e,t,n,o){const s=[];for(const r of e)for(const a in r.components){let l=r.components[a];if(!(t!=="beforeRouteEnter"&&!r.instances[a]))if(q3(l)){const u=(l.__vccOpts||l)[t];u&&s.push(fn(u,n,o,r,a))}else{let i=l();s.push(()=>i.then(u=>{if(!u)return Promise.reject(new Error(`Couldn't resolve component "${a}" at "${r.path}"`));const c=Z5(u)?u.default:u;r.components[a]=c;const f=(c.__vccOpts||c)[t];return f&&fn(f,n,o,r,a)()}))}}return s}function q3(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function au(e){const t=qe(Cr),n=qe(Ci),o=C(()=>t.resolve(me(e.to))),s=C(()=>{const{matched:i}=o.value,{length:u}=i,c=i[u-1],p=n.matched;if(!c||!p.length)return-1;const f=p.findIndex(ho.bind(null,c));if(f>-1)return f;const m=iu(i[u-2]);return u>1&&iu(c)===m&&p[p.length-1].path!==m?p.findIndex(ho.bind(null,i[u-2])):f}),r=C(()=>s.value>-1&&K3(n.params,o.value.params)),a=C(()=>s.value>-1&&s.value===n.matched.length-1&&bd(n.params,o.value.params));function l(i={}){return Q3(i)?t[me(e.replace)?"replace":"push"](me(e.to)).catch(jo):Promise.resolve()}return{route:o,href:C(()=>o.value.href),isActive:r,isExactActive:a,navigate:l}}const G3=Ce({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:au,setup(e,{slots:t}){const n=ar(au(e)),{options:o}=qe(Cr),s=C(()=>({[lu(e.activeClass,o.linkActiveClass,"router-link-active")]:n.isActive,[lu(e.exactActiveClass,o.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&t.default(n);return e.custom?r:Tt("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:s.value},r)}}}),J3=G3;function Q3(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function K3(e,t){for(const n in t){const o=t[n],s=e[n];if(typeof o=="string"){if(o!==s)return!1}else if(!Vt(s)||s.length!==o.length||o.some((r,a)=>r!==s[a]))return!1}return!0}function iu(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const lu=(e,t,n)=>e??t??n,Y3=Ce({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const o=qe(Sa),s=C(()=>e.route||o.value),r=qe(ru,0),a=C(()=>{let u=me(r);const{matched:c}=s.value;let p;for(;(p=c[u])&&!p.components;)u++;return u}),l=C(()=>s.value.matched[a.value]);en(ru,C(()=>a.value+1)),en(W3,l),en(Sa,s);const i=Y();return _t(()=>[i.value,l.value,e.name],([u,c,p],[f,m,v])=>{c&&(c.instances[p]=u,m&&m!==c&&u&&u===f&&(c.leaveGuards.size||(c.leaveGuards=m.leaveGuards),c.updateGuards.size||(c.updateGuards=m.updateGuards))),u&&c&&(!m||!ho(c,m)||!f)&&(c.enterCallbacks[p]||[]).forEach(w=>w(u))},{flush:"post"}),()=>{const u=s.value,c=e.name,p=l.value,f=p&&p.components[c];if(!f)return uu(n.default,{Component:f,route:u});const m=p.props[c],v=m?m===!0?u.params:typeof m=="function"?m(u):m:null,S=Tt(f,Je({},v,t,{onVnodeUnmounted:z=>{z.component.isUnmounted&&(p.instances[c]=null)},ref:i}));return uu(n.default,{Component:S,route:u})||S}}});function uu(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Z3=Y3;function X3(e){const t=A3(e.routes,e),n=e.parseQuery||F3,o=e.stringifyQuery||su,s=e.history,r=So(),a=So(),l=So(),i=jp(ln);let u=ln;eo&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=Wr.bind(null,E=>""+E),p=Wr.bind(null,N3),f=Wr.bind(null,er);function m(E,q){let O,I;return kd(E)?(O=t.getRecordMatcher(E),I=q):I=E,t.addRoute(I,O)}function v(E){const q=t.getRecordMatcher(E);q&&t.removeRoute(q)}function w(){return t.getRoutes().map(E=>E.record)}function S(E){return!!t.getRecordMatcher(E)}function z(E,q){if(q=Je({},q||i.value),typeof E=="string"){const b=qr(n,E,q.path),T=t.resolve({path:b.path},q),k=s.createHref(b.fullPath);return Je(b,T,{params:f(T.params),hash:er(b.hash),redirectedFrom:void 0,href:k})}let O;if("path"in E)O=Je({},E,{path:qr(n,E.path,q.path).path});else{const b=Je({},E.params);for(const T in b)b[T]==null&&delete b[T];O=Je({},E,{params:p(b)}),q.params=p(q.params)}const I=t.resolve(O,q),ae=E.hash||"";I.params=c(f(I.params));const Se=t3(o,Je({},E,{hash:D3(ae),path:I.path})),g=s.createHref(Se);return Je({fullPath:Se,hash:ae,query:o===su?U3(E.query):E.query||{}},I,{redirectedFrom:void 0,href:g})}function $(E){return typeof E=="string"?qr(n,E,i.value.path):Je({},E)}function A(E,q){if(u!==E)return mo(8,{from:q,to:E})}function N(E){return P(E)}function B(E){return N(Je($(E),{replace:!0}))}function D(E){const q=E.matched[E.matched.length-1];if(q&&q.redirect){const{redirect:O}=q;let I=typeof O=="function"?O(E):O;return typeof I=="string"&&(I=I.includes("?")||I.includes("#")?I=$(I):{path:I},I.params={}),Je({query:E.query,hash:E.hash,params:"path"in I?{}:E.params},I)}}function P(E,q){const O=u=z(E),I=i.value,ae=E.state,Se=E.force,g=E.replace===!0,b=D(O);if(b)return P(Je($(b),{state:typeof b=="object"?Je({},ae,b.state):ae,force:Se,replace:g}),q||O);const T=O;T.redirectedFrom=q;let k;return!Se&&n3(o,I,O)&&(k=mo(16,{to:T,from:I}),H(I,I,!0,!1)),(k?Promise.resolve(k):ge(T,I)).catch(x=>Yt(x)?Yt(x,2)?x:_(x):U(x,T,I)).then(x=>{if(x){if(Yt(x,2))return P(Je({replace:g},$(x.to),{state:typeof x.to=="object"?Je({},ae,x.to.state):ae,force:Se}),q||T)}else x=se(T,I,!0,g,ae);return re(T,I,x),x})}function ne(E,q){const O=A(E,q);return O?Promise.reject(O):Promise.resolve()}function Z(E){const q=be.values().next().value;return q&&typeof q.runWithContext=="function"?q.runWithContext(E):E()}function ge(E,q){let O;const[I,ae,Se]=e4(E,q);O=Gr(I.reverse(),"beforeRouteLeave",E,q);for(const b of I)b.leaveGuards.forEach(T=>{O.push(fn(T,E,q))});const g=ne.bind(null,E,q);return O.push(g),ue(O).then(()=>{O=[];for(const b of r.list())O.push(fn(b,E,q));return O.push(g),ue(O)}).then(()=>{O=Gr(ae,"beforeRouteUpdate",E,q);for(const b of ae)b.updateGuards.forEach(T=>{O.push(fn(T,E,q))});return O.push(g),ue(O)}).then(()=>{O=[];for(const b of Se)if(b.beforeEnter)if(Vt(b.beforeEnter))for(const T of b.beforeEnter)O.push(fn(T,E,q));else O.push(fn(b.beforeEnter,E,q));return O.push(g),ue(O)}).then(()=>(E.matched.forEach(b=>b.enterCallbacks={}),O=Gr(Se,"beforeRouteEnter",E,q),O.push(g),ue(O))).then(()=>{O=[];for(const b of a.list())O.push(fn(b,E,q));return O.push(g),ue(O)}).catch(b=>Yt(b,8)?b:Promise.reject(b))}function re(E,q,O){l.list().forEach(I=>Z(()=>I(E,q,O)))}function se(E,q,O,I,ae){const Se=A(E,q);if(Se)return Se;const g=q===ln,b=eo?history.state:{};O&&(I||g?s.replace(E.fullPath,Je({scroll:g&&b&&b.scroll},ae)):s.push(E.fullPath,ae)),i.value=E,H(E,q,O,g),_()}let ve;function pe(){ve||(ve=s.listen((E,q,O)=>{if(!R.listening)return;const I=z(E),ae=D(I);if(ae){P(Je(ae,{replace:!0}),I).catch(jo);return}u=I;const Se=i.value;eo&&c3(Kl(Se.fullPath,O.delta),xr()),ge(I,Se).catch(g=>Yt(g,12)?g:Yt(g,2)?(P(g.to,I).then(b=>{Yt(b,20)&&!O.delta&&O.type===Jo.pop&&s.go(-1,!1)}).catch(jo),Promise.reject()):(O.delta&&s.go(-O.delta,!1),U(g,I,Se))).then(g=>{g=g||se(I,Se,!1),g&&(O.delta&&!Yt(g,8)?s.go(-O.delta,!1):O.type===Jo.pop&&Yt(g,20)&&s.go(-1,!1)),re(I,Se,g)}).catch(jo)}))}let J=So(),ie=So(),M;function U(E,q,O){_(E);const I=ie.list();return I.length?I.forEach(ae=>ae(E,q,O)):console.error(E),Promise.reject(E)}function X(){return M&&i.value!==ln?Promise.resolve():new Promise((E,q)=>{J.add([E,q])})}function _(E){return M||(M=!E,pe(),J.list().forEach(([q,O])=>E?O(E):q()),J.reset()),E}function H(E,q,O,I){const{scrollBehavior:ae}=e;if(!eo||!ae)return Promise.resolve();const Se=!O&&d3(Kl(E.fullPath,0))||(I||!O)&&history.state&&history.state.scroll||null;return jt().then(()=>ae(E,q,Se)).then(g=>g&&u3(g)).catch(g=>U(g,E,q))}const de=E=>s.go(E);let W;const be=new Set,R={currentRoute:i,listening:!0,addRoute:m,removeRoute:v,hasRoute:S,getRoutes:w,resolve:z,options:e,push:N,replace:B,go:de,back:()=>de(-1),forward:()=>de(1),beforeEach:r.add,beforeResolve:a.add,afterEach:l.add,onError:ie.add,isReady:X,install(E){const q=this;E.component("RouterLink",J3),E.component("RouterView",Z3),E.config.globalProperties.$router=q,Object.defineProperty(E.config.globalProperties,"$route",{enumerable:!0,get:()=>me(i)}),eo&&!W&&i.value===ln&&(W=!0,N(s.location).catch(ae=>{}));const O={};for(const ae in ln)Object.defineProperty(O,ae,{get:()=>i.value[ae],enumerable:!0});E.provide(Cr,q),E.provide(Ci,$u(O)),E.provide(Sa,i);const I=E.unmount;be.add(E),E.unmount=function(){be.delete(E),be.size<1&&(u=ln,ve&&ve(),ve=null,i.value=ln,W=!1,M=!1),I()}}};function ue(E){return E.reduce((q,O)=>q.then(()=>Z(O)),Promise.resolve())}return R}function e4(e,t){const n=[],o=[],s=[],r=Math.max(t.matched.length,e.matched.length);for(let a=0;aho(u,l))?o.push(l):n.push(l));const i=e.matched[a];i&&(t.matched.find(u=>ho(u,i))||s.push(i))}return[n,o,s]}function h6(){return qe(Cr)}function m6(){return qe(Ci)}function t4(e){const{extendRoutes:t}=e;return X3(Object.assign(e,{routes:typeof t=="function"?t(Gl):Gl}))}const n4=e=>{const t={};Object.entries(Object.assign({"/src/layouts/default.vue":()=>Ve(()=>import("./default-Bpx-Aajc.js"),__vite__mapDeps([22,10,9])),"/src/layouts/empty.vue":()=>Ve(()=>import("./empty-BlQdiYK7.js"),__vite__mapDeps([23,9]))})).forEach(([s,r])=>{let a=s.replace("/src/layouts/","").replace(".vue","");t[a]=r});function o(s,r=!0){return s.map(a=>{var l,i,u,c,p,f;if(((l=a.children)==null?void 0:l.length)>0&&(a.children=o(a.children,!1)),r){if(!a.component&&((i=a.children)==null?void 0:i.find(v=>{var w;return(v.path===""||v.path==="/")&&((w=v.meta)==null?void 0:w.isLayout)})))return a;if(((u=a.meta)==null?void 0:u.layout)!==!1)return{path:a.path,component:t[((c=a.meta)==null?void 0:c.layout)||"default"],children:a.path==="/"?[a]:[{...a,path:""}],meta:{isLayout:!0}}}return(p=a.meta)!=null&&p.layout?{path:a.path,component:t[(f=a.meta)==null?void 0:f.layout],children:[{...a,path:""}],meta:{isLayout:!0}}:a})}return o(e)},o4={blog:{config:{localBaseUrl:"http://localhost:5173",publicBaseUrl:"https://press-vue.servicestack.net",siteTwitter:"@Vue",blogTitle:"From the blog",blogDescription:"Writing on software design and aerospace industry.",blogEmail:"email@example.org (Vue)",blogImageUrl:"https://servicestack.net/img/logo.png"},authors:[{name:"Lucy Bates",email:"lucy@email.org",bio:"Works in software design, company building, and the aerospace industry.",profileUrl:"/img/profiles/user1.svg",twitterUrl:"https://twitter.com/lucy",threadsUrl:"https://threads.net/@lucy",gitHubUrl:"https://github.com/lucy"},{name:"Gayle Smith",email:"gayle@email.org",bio:"Gayle is an author, consultant, and founder focusing on improving tech.",profileUrl:"/img/profiles/user2.svg",twitterUrl:"https://twitter.com/gayle",mastodonUrl:"https://mastodon.social/@gayle"},{name:"Brandon Foley",email:"brandon@email.org",bio:"I am a programmer at heart. I like to tinker with code and build generic coding structures.",profileUrl:"/img/profiles/user3.svg",gitHubUrl:"https://github.com/brandon"}],posts:[{slug:"vite-press-plugin",path:"src/_posts/2024-03-01_vite-press-plugin.md",fileName:"vite-press-plugin.md",content:`The Vite Press Plugin is an alternative to [VitePress](https://vitepress.dev) for adding Markdown features + */const eo=typeof window<"u";function Z5(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const Je=Object.assign;function Wr(e,t){const n={};for(const o in t){const s=t[o];n[o]=Vt(s)?s.map(e):e(s)}return n}const jo=()=>{},Vt=Array.isArray,X5=/\/$/,e3=e=>e.replace(X5,"");function qr(e,t,n="/"){let o,s={},r="",a="";const l=t.indexOf("#");let i=t.indexOf("?");return l=0&&(i=-1),i>-1&&(o=t.slice(0,i),r=t.slice(i+1,l>-1?l:t.length),s=e(r)),l>-1&&(o=o||t.slice(0,l),a=t.slice(l,t.length)),o=s3(o??t,n),{fullPath:o+(r&&"?")+r+a,path:o,query:s,hash:a}}function t3(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Jl(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function n3(e,t,n){const o=t.matched.length-1,s=n.matched.length-1;return o>-1&&o===s&&ho(t.matched[o],n.matched[s])&&bd(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function ho(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function bd(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!o3(e[n],t[n]))return!1;return!0}function o3(e,t){return Vt(e)?Ql(e,t):Vt(t)?Ql(t,e):e===t}function Ql(e,t){return Vt(t)?e.length===t.length&&e.every((n,o)=>n===t[o]):e.length===1&&e[0]===t}function s3(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),o=e.split("/"),s=o[o.length-1];(s===".."||s===".")&&o.push("");let r=n.length-1,a,l;for(a=0;a1&&r--;else break;return n.slice(0,r).join("/")+"/"+o.slice(a-(a===o.length?1:0)).join("/")}var Jo;(function(e){e.pop="pop",e.push="push"})(Jo||(Jo={}));var Vo;(function(e){e.back="back",e.forward="forward",e.unknown=""})(Vo||(Vo={}));function r3(e){if(!e)if(eo){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),e3(e)}const a3=/^[^#]+#/;function i3(e,t){return e.replace(a3,"#")+t}function l3(e,t){const n=document.documentElement.getBoundingClientRect(),o=e.getBoundingClientRect();return{behavior:t.behavior,left:o.left-n.left-(t.left||0),top:o.top-n.top-(t.top||0)}}const xr=()=>({left:window.pageXOffset,top:window.pageYOffset});function u3(e){let t;if("el"in e){const n=e.el,o=typeof n=="string"&&n.startsWith("#"),s=typeof n=="string"?o?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!s)return;t=l3(s,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.pageXOffset,t.top!=null?t.top:window.pageYOffset)}function Kl(e,t){return(history.state?history.state.position-t:-1)+e}const xa=new Map;function c3(e,t){xa.set(e,t)}function d3(e){const t=xa.get(e);return xa.delete(e),t}let p3=()=>location.protocol+"//"+location.host;function wd(e,t){const{pathname:n,search:o,hash:s}=t,r=e.indexOf("#");if(r>-1){let l=s.includes(e.slice(r))?e.slice(r).length:1,i=s.slice(l);return i[0]!=="/"&&(i="/"+i),Jl(i,"")}return Jl(n,e)+o+s}function f3(e,t,n,o){let s=[],r=[],a=null;const l=({state:f})=>{const m=wd(e,location),v=n.value,w=t.value;let S=0;if(f){if(n.value=m,t.value=f,a&&a===v){a=null;return}S=w?f.position-w.position:0}else o(m);s.forEach(z=>{z(n.value,v,{delta:S,type:Jo.pop,direction:S?S>0?Vo.forward:Vo.back:Vo.unknown})})};function i(){a=n.value}function u(f){s.push(f);const m=()=>{const v=s.indexOf(f);v>-1&&s.splice(v,1)};return r.push(m),m}function c(){const{history:f}=window;f.state&&f.replaceState(Je({},f.state,{scroll:xr()}),"")}function p(){for(const f of r)f();r=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",c)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",c,{passive:!0}),{pauseListeners:i,listen:u,destroy:p}}function Yl(e,t,n,o=!1,s=!1){return{back:e,current:t,forward:n,replaced:o,position:window.history.length,scroll:s?xr():null}}function h3(e){const{history:t,location:n}=window,o={value:wd(e,n)},s={value:t.state};s.value||r(o.value,{back:null,current:o.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(i,u,c){const p=e.indexOf("#"),f=p>-1?(n.host&&document.querySelector("base")?e:e.slice(p))+i:p3()+e+i;try{t[c?"replaceState":"pushState"](u,"",f),s.value=u}catch(m){console.error(m),n[c?"replace":"assign"](f)}}function a(i,u){const c=Je({},t.state,Yl(s.value.back,i,s.value.forward,!0),u,{position:s.value.position});r(i,c,!0),o.value=i}function l(i,u){const c=Je({},s.value,t.state,{forward:i,scroll:xr()});r(c.current,c,!0);const p=Je({},Yl(o.value,i,null),{position:c.position+1},u);r(i,p,!1),o.value=i}return{location:o,state:s,push:l,replace:a}}function m3(e){e=r3(e);const t=h3(e),n=f3(e,t.state,t.location,t.replace);function o(r,a=!0){a||n.pauseListeners(),history.go(r)}const s=Je({location:"",base:e,go:o,createHref:i3.bind(null,e)},t,n);return Object.defineProperty(s,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(s,"state",{enumerable:!0,get:()=>t.state.value}),s}function g3(e){return typeof e=="string"||e&&typeof e=="object"}function kd(e){return typeof e=="string"||typeof e=="symbol"}const ln={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},xd=Symbol("");var Zl;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Zl||(Zl={}));function mo(e,t){return Je(new Error,{type:e,[xd]:!0},t)}function Yt(e,t){return e instanceof Error&&xd in e&&(t==null||!!(e.type&t))}const Xl="[^/]+?",v3={sensitive:!1,strict:!1,start:!0,end:!0},y3=/[.+*?^${}()[\]/\\]/g;function b3(e,t){const n=Je({},v3,t),o=[];let s=n.start?"^":"";const r=[];for(const u of e){const c=u.length?[]:[90];n.strict&&!u.length&&(s+="/");for(let p=0;pt.length?t.length===1&&t[0]===80?1:-1:0}function k3(e,t){let n=0;const o=e.score,s=t.score;for(;n0&&t[t.length-1]<0}const x3={type:0,value:""},C3=/[a-zA-Z0-9_]/;function S3(e){if(!e)return[[]];if(e==="/")return[[x3]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${u}": ${m}`)}let n=0,o=n;const s=[];let r;function a(){r&&s.push(r),r=[]}let l=0,i,u="",c="";function p(){u&&(n===0?r.push({type:0,value:u}):n===1||n===2||n===3?(r.length>1&&(i==="*"||i==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),r.push({type:1,value:u,regexp:c,repeatable:i==="*"||i==="+",optional:i==="*"||i==="?"})):t("Invalid state to consume buffer"),u="")}function f(){u+=i}for(;l{a($)}:jo}function a(c){if(kd(c)){const p=o.get(c);p&&(o.delete(c),n.splice(n.indexOf(p),1),p.children.forEach(a),p.alias.forEach(a))}else{const p=n.indexOf(c);p>-1&&(n.splice(p,1),c.record.name&&o.delete(c.record.name),c.children.forEach(a),c.alias.forEach(a))}}function l(){return n}function i(c){let p=0;for(;p=0&&(c.record.path!==n[p].record.path||!Cd(c,n[p]));)p++;n.splice(p,0,c),c.record.name&&!nu(c)&&o.set(c.record.name,c)}function u(c,p){let f,m={},v,w;if("name"in c&&c.name){if(f=o.get(c.name),!f)throw mo(1,{location:c});w=f.record.name,m=Je(tu(p.params,f.keys.filter($=>!$.optional).map($=>$.name)),c.params&&tu(c.params,f.keys.map($=>$.name))),v=f.stringify(m)}else if("path"in c)v=c.path,f=n.find($=>$.re.test(v)),f&&(m=f.parse(v),w=f.record.name);else{if(f=p.name?o.get(p.name):n.find($=>$.re.test(p.path)),!f)throw mo(1,{location:c,currentLocation:p});w=f.record.name,m=Je({},p.params,c.params),v=f.stringify(m)}const S=[];let z=f;for(;z;)S.unshift(z.record),z=z.parent;return{name:w,path:v,params:m,matched:S,meta:P3(S)}}return e.forEach(c=>r(c)),{addRoute:r,resolve:u,removeRoute:a,getRoutes:l,getRecordMatcher:s}}function tu(e,t){const n={};for(const o of t)o in e&&(n[o]=e[o]);return n}function _3(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:M3(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function M3(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const o in e.components)t[o]=typeof n=="object"?n[o]:n;return t}function nu(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function P3(e){return e.reduce((t,n)=>Je(t,n.meta),{})}function ou(e,t){const n={};for(const o in e)n[o]=o in t?t[o]:e[o];return n}function Cd(e,t){return t.children.some(n=>n===e||Cd(e,n))}const Sd=/#/g,E3=/&/g,I3=/\//g,L3=/=/g,z3=/\?/g,Td=/\+/g,R3=/%5B/g,j3=/%5D/g,Ad=/%5E/g,V3=/%60/g,_d=/%7B/g,O3=/%7C/g,Md=/%7D/g,B3=/%20/g;function xi(e){return encodeURI(""+e).replace(O3,"|").replace(R3,"[").replace(j3,"]")}function D3(e){return xi(e).replace(_d,"{").replace(Md,"}").replace(Ad,"^")}function Ca(e){return xi(e).replace(Td,"%2B").replace(B3,"+").replace(Sd,"%23").replace(E3,"%26").replace(V3,"`").replace(_d,"{").replace(Md,"}").replace(Ad,"^")}function H3(e){return Ca(e).replace(L3,"%3D")}function $3(e){return xi(e).replace(Sd,"%23").replace(z3,"%3F")}function N3(e){return e==null?"":$3(e).replace(I3,"%2F")}function er(e){try{return decodeURIComponent(""+e)}catch{}return""+e}function F3(e){const t={};if(e===""||e==="?")return t;const o=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;sr&&Ca(r)):[o&&Ca(o)]).forEach(r=>{r!==void 0&&(t+=(t.length?"&":"")+n,r!=null&&(t+="="+r))})}return t}function U3(e){const t={};for(const n in e){const o=e[n];o!==void 0&&(t[n]=Vt(o)?o.map(s=>s==null?null:""+s):o==null?o:""+o)}return t}const W3=Symbol(""),ru=Symbol(""),Cr=Symbol(""),Ci=Symbol(""),Sa=Symbol("");function So(){let e=[];function t(o){return e.push(o),()=>{const s=e.indexOf(o);s>-1&&e.splice(s,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function fn(e,t,n,o,s){const r=o&&(o.enterCallbacks[s]=o.enterCallbacks[s]||[]);return()=>new Promise((a,l)=>{const i=p=>{p===!1?l(mo(4,{from:n,to:t})):p instanceof Error?l(p):g3(p)?l(mo(2,{from:t,to:p})):(r&&o.enterCallbacks[s]===r&&typeof p=="function"&&r.push(p),a())},u=e.call(o&&o.instances[s],t,n,i);let c=Promise.resolve(u);e.length<3&&(c=c.then(i)),c.catch(p=>l(p))})}function Gr(e,t,n,o){const s=[];for(const r of e)for(const a in r.components){let l=r.components[a];if(!(t!=="beforeRouteEnter"&&!r.instances[a]))if(q3(l)){const u=(l.__vccOpts||l)[t];u&&s.push(fn(u,n,o,r,a))}else{let i=l();s.push(()=>i.then(u=>{if(!u)return Promise.reject(new Error(`Couldn't resolve component "${a}" at "${r.path}"`));const c=Z5(u)?u.default:u;r.components[a]=c;const f=(c.__vccOpts||c)[t];return f&&fn(f,n,o,r,a)()}))}}return s}function q3(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function au(e){const t=qe(Cr),n=qe(Ci),o=C(()=>t.resolve(me(e.to))),s=C(()=>{const{matched:i}=o.value,{length:u}=i,c=i[u-1],p=n.matched;if(!c||!p.length)return-1;const f=p.findIndex(ho.bind(null,c));if(f>-1)return f;const m=iu(i[u-2]);return u>1&&iu(c)===m&&p[p.length-1].path!==m?p.findIndex(ho.bind(null,i[u-2])):f}),r=C(()=>s.value>-1&&K3(n.params,o.value.params)),a=C(()=>s.value>-1&&s.value===n.matched.length-1&&bd(n.params,o.value.params));function l(i={}){return Q3(i)?t[me(e.replace)?"replace":"push"](me(e.to)).catch(jo):Promise.resolve()}return{route:o,href:C(()=>o.value.href),isActive:r,isExactActive:a,navigate:l}}const G3=Ce({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:au,setup(e,{slots:t}){const n=ar(au(e)),{options:o}=qe(Cr),s=C(()=>({[lu(e.activeClass,o.linkActiveClass,"router-link-active")]:n.isActive,[lu(e.exactActiveClass,o.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&t.default(n);return e.custom?r:Tt("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:s.value},r)}}}),J3=G3;function Q3(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function K3(e,t){for(const n in t){const o=t[n],s=e[n];if(typeof o=="string"){if(o!==s)return!1}else if(!Vt(s)||s.length!==o.length||o.some((r,a)=>r!==s[a]))return!1}return!0}function iu(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const lu=(e,t,n)=>e??t??n,Y3=Ce({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const o=qe(Sa),s=C(()=>e.route||o.value),r=qe(ru,0),a=C(()=>{let u=me(r);const{matched:c}=s.value;let p;for(;(p=c[u])&&!p.components;)u++;return u}),l=C(()=>s.value.matched[a.value]);en(ru,C(()=>a.value+1)),en(W3,l),en(Sa,s);const i=Y();return _t(()=>[i.value,l.value,e.name],([u,c,p],[f,m,v])=>{c&&(c.instances[p]=u,m&&m!==c&&u&&u===f&&(c.leaveGuards.size||(c.leaveGuards=m.leaveGuards),c.updateGuards.size||(c.updateGuards=m.updateGuards))),u&&c&&(!m||!ho(c,m)||!f)&&(c.enterCallbacks[p]||[]).forEach(w=>w(u))},{flush:"post"}),()=>{const u=s.value,c=e.name,p=l.value,f=p&&p.components[c];if(!f)return uu(n.default,{Component:f,route:u});const m=p.props[c],v=m?m===!0?u.params:typeof m=="function"?m(u):m:null,S=Tt(f,Je({},v,t,{onVnodeUnmounted:z=>{z.component.isUnmounted&&(p.instances[c]=null)},ref:i}));return uu(n.default,{Component:S,route:u})||S}}});function uu(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Z3=Y3;function X3(e){const t=A3(e.routes,e),n=e.parseQuery||F3,o=e.stringifyQuery||su,s=e.history,r=So(),a=So(),l=So(),i=jp(ln);let u=ln;eo&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=Wr.bind(null,E=>""+E),p=Wr.bind(null,N3),f=Wr.bind(null,er);function m(E,q){let O,I;return kd(E)?(O=t.getRecordMatcher(E),I=q):I=E,t.addRoute(I,O)}function v(E){const q=t.getRecordMatcher(E);q&&t.removeRoute(q)}function w(){return t.getRoutes().map(E=>E.record)}function S(E){return!!t.getRecordMatcher(E)}function z(E,q){if(q=Je({},q||i.value),typeof E=="string"){const b=qr(n,E,q.path),T=t.resolve({path:b.path},q),k=s.createHref(b.fullPath);return Je(b,T,{params:f(T.params),hash:er(b.hash),redirectedFrom:void 0,href:k})}let O;if("path"in E)O=Je({},E,{path:qr(n,E.path,q.path).path});else{const b=Je({},E.params);for(const T in b)b[T]==null&&delete b[T];O=Je({},E,{params:p(b)}),q.params=p(q.params)}const I=t.resolve(O,q),ae=E.hash||"";I.params=c(f(I.params));const Se=t3(o,Je({},E,{hash:D3(ae),path:I.path})),g=s.createHref(Se);return Je({fullPath:Se,hash:ae,query:o===su?U3(E.query):E.query||{}},I,{redirectedFrom:void 0,href:g})}function $(E){return typeof E=="string"?qr(n,E,i.value.path):Je({},E)}function A(E,q){if(u!==E)return mo(8,{from:q,to:E})}function N(E){return P(E)}function B(E){return N(Je($(E),{replace:!0}))}function D(E){const q=E.matched[E.matched.length-1];if(q&&q.redirect){const{redirect:O}=q;let I=typeof O=="function"?O(E):O;return typeof I=="string"&&(I=I.includes("?")||I.includes("#")?I=$(I):{path:I},I.params={}),Je({query:E.query,hash:E.hash,params:"path"in I?{}:E.params},I)}}function P(E,q){const O=u=z(E),I=i.value,ae=E.state,Se=E.force,g=E.replace===!0,b=D(O);if(b)return P(Je($(b),{state:typeof b=="object"?Je({},ae,b.state):ae,force:Se,replace:g}),q||O);const T=O;T.redirectedFrom=q;let k;return!Se&&n3(o,I,O)&&(k=mo(16,{to:T,from:I}),H(I,I,!0,!1)),(k?Promise.resolve(k):ge(T,I)).catch(x=>Yt(x)?Yt(x,2)?x:_(x):U(x,T,I)).then(x=>{if(x){if(Yt(x,2))return P(Je({replace:g},$(x.to),{state:typeof x.to=="object"?Je({},ae,x.to.state):ae,force:Se}),q||T)}else x=se(T,I,!0,g,ae);return re(T,I,x),x})}function ne(E,q){const O=A(E,q);return O?Promise.reject(O):Promise.resolve()}function Z(E){const q=be.values().next().value;return q&&typeof q.runWithContext=="function"?q.runWithContext(E):E()}function ge(E,q){let O;const[I,ae,Se]=e4(E,q);O=Gr(I.reverse(),"beforeRouteLeave",E,q);for(const b of I)b.leaveGuards.forEach(T=>{O.push(fn(T,E,q))});const g=ne.bind(null,E,q);return O.push(g),ue(O).then(()=>{O=[];for(const b of r.list())O.push(fn(b,E,q));return O.push(g),ue(O)}).then(()=>{O=Gr(ae,"beforeRouteUpdate",E,q);for(const b of ae)b.updateGuards.forEach(T=>{O.push(fn(T,E,q))});return O.push(g),ue(O)}).then(()=>{O=[];for(const b of Se)if(b.beforeEnter)if(Vt(b.beforeEnter))for(const T of b.beforeEnter)O.push(fn(T,E,q));else O.push(fn(b.beforeEnter,E,q));return O.push(g),ue(O)}).then(()=>(E.matched.forEach(b=>b.enterCallbacks={}),O=Gr(Se,"beforeRouteEnter",E,q),O.push(g),ue(O))).then(()=>{O=[];for(const b of a.list())O.push(fn(b,E,q));return O.push(g),ue(O)}).catch(b=>Yt(b,8)?b:Promise.reject(b))}function re(E,q,O){l.list().forEach(I=>Z(()=>I(E,q,O)))}function se(E,q,O,I,ae){const Se=A(E,q);if(Se)return Se;const g=q===ln,b=eo?history.state:{};O&&(I||g?s.replace(E.fullPath,Je({scroll:g&&b&&b.scroll},ae)):s.push(E.fullPath,ae)),i.value=E,H(E,q,O,g),_()}let ve;function pe(){ve||(ve=s.listen((E,q,O)=>{if(!R.listening)return;const I=z(E),ae=D(I);if(ae){P(Je(ae,{replace:!0}),I).catch(jo);return}u=I;const Se=i.value;eo&&c3(Kl(Se.fullPath,O.delta),xr()),ge(I,Se).catch(g=>Yt(g,12)?g:Yt(g,2)?(P(g.to,I).then(b=>{Yt(b,20)&&!O.delta&&O.type===Jo.pop&&s.go(-1,!1)}).catch(jo),Promise.reject()):(O.delta&&s.go(-O.delta,!1),U(g,I,Se))).then(g=>{g=g||se(I,Se,!1),g&&(O.delta&&!Yt(g,8)?s.go(-O.delta,!1):O.type===Jo.pop&&Yt(g,20)&&s.go(-1,!1)),re(I,Se,g)}).catch(jo)}))}let J=So(),ie=So(),M;function U(E,q,O){_(E);const I=ie.list();return I.length?I.forEach(ae=>ae(E,q,O)):console.error(E),Promise.reject(E)}function X(){return M&&i.value!==ln?Promise.resolve():new Promise((E,q)=>{J.add([E,q])})}function _(E){return M||(M=!E,pe(),J.list().forEach(([q,O])=>E?O(E):q()),J.reset()),E}function H(E,q,O,I){const{scrollBehavior:ae}=e;if(!eo||!ae)return Promise.resolve();const Se=!O&&d3(Kl(E.fullPath,0))||(I||!O)&&history.state&&history.state.scroll||null;return jt().then(()=>ae(E,q,Se)).then(g=>g&&u3(g)).catch(g=>U(g,E,q))}const de=E=>s.go(E);let W;const be=new Set,R={currentRoute:i,listening:!0,addRoute:m,removeRoute:v,hasRoute:S,getRoutes:w,resolve:z,options:e,push:N,replace:B,go:de,back:()=>de(-1),forward:()=>de(1),beforeEach:r.add,beforeResolve:a.add,afterEach:l.add,onError:ie.add,isReady:X,install(E){const q=this;E.component("RouterLink",J3),E.component("RouterView",Z3),E.config.globalProperties.$router=q,Object.defineProperty(E.config.globalProperties,"$route",{enumerable:!0,get:()=>me(i)}),eo&&!W&&i.value===ln&&(W=!0,N(s.location).catch(ae=>{}));const O={};for(const ae in ln)Object.defineProperty(O,ae,{get:()=>i.value[ae],enumerable:!0});E.provide(Cr,q),E.provide(Ci,$u(O)),E.provide(Sa,i);const I=E.unmount;be.add(E),E.unmount=function(){be.delete(E),be.size<1&&(u=ln,ve&&ve(),ve=null,i.value=ln,W=!1,M=!1),I()}}};function ue(E){return E.reduce((q,O)=>q.then(()=>Z(O)),Promise.resolve())}return R}function e4(e,t){const n=[],o=[],s=[],r=Math.max(t.matched.length,e.matched.length);for(let a=0;aho(u,l))?o.push(l):n.push(l));const i=e.matched[a];i&&(t.matched.find(u=>ho(u,i))||s.push(i))}return[n,o,s]}function h6(){return qe(Cr)}function m6(){return qe(Ci)}function t4(e){const{extendRoutes:t}=e;return X3(Object.assign(e,{routes:typeof t=="function"?t(Gl):Gl}))}const n4=e=>{const t={};Object.entries(Object.assign({"/src/layouts/default.vue":()=>Ve(()=>import("./default-Caiy_OVN.js"),__vite__mapDeps([22,10,9])),"/src/layouts/empty.vue":()=>Ve(()=>import("./empty-u1n3FCjQ.js"),__vite__mapDeps([23,9]))})).forEach(([s,r])=>{let a=s.replace("/src/layouts/","").replace(".vue","");t[a]=r});function o(s,r=!0){return s.map(a=>{var l,i,u,c,p,f;if(((l=a.children)==null?void 0:l.length)>0&&(a.children=o(a.children,!1)),r){if(!a.component&&((i=a.children)==null?void 0:i.find(v=>{var w;return(v.path===""||v.path==="/")&&((w=v.meta)==null?void 0:w.isLayout)})))return a;if(((u=a.meta)==null?void 0:u.layout)!==!1)return{path:a.path,component:t[((c=a.meta)==null?void 0:c.layout)||"default"],children:a.path==="/"?[a]:[{...a,path:""}],meta:{isLayout:!0}}}return(p=a.meta)!=null&&p.layout?{path:a.path,component:t[(f=a.meta)==null?void 0:f.layout],children:[{...a,path:""}],meta:{isLayout:!0}}:a})}return o(e)},o4={blog:{config:{localBaseUrl:"http://localhost:5173",publicBaseUrl:"https://press-vue.servicestack.net",siteTwitter:"@Vue",blogTitle:"From the blog",blogDescription:"Writing on software design and aerospace industry.",blogEmail:"email@example.org (Vue)",blogImageUrl:"https://servicestack.net/img/logo.png"},authors:[{name:"Lucy Bates",email:"lucy@email.org",bio:"Works in software design, company building, and the aerospace industry.",profileUrl:"/img/profiles/user1.svg",twitterUrl:"https://twitter.com/lucy",threadsUrl:"https://threads.net/@lucy",gitHubUrl:"https://github.com/lucy"},{name:"Gayle Smith",email:"gayle@email.org",bio:"Gayle is an author, consultant, and founder focusing on improving tech.",profileUrl:"/img/profiles/user2.svg",twitterUrl:"https://twitter.com/gayle",mastodonUrl:"https://mastodon.social/@gayle"},{name:"Brandon Foley",email:"brandon@email.org",bio:"I am a programmer at heart. I like to tinker with code and build generic coding structures.",profileUrl:"/img/profiles/user3.svg",gitHubUrl:"https://github.com/brandon"}],posts:[{slug:"vite-press-plugin",path:"src/_posts/2024-03-01_vite-press-plugin.md",fileName:"vite-press-plugin.md",content:`The Vite Press Plugin is an alternative to [VitePress](https://vitepress.dev) for adding Markdown features to existing Vite Vue or React projects. It's a non-intrusive plugin for Vue and React Vite apps that want to add markdown powered content features without needing to adopt an opinionated framework for their entire App. @@ -3700,7 +3700,7 @@ making it one of the fastest and most efficient animation tools available today. Built with performance in mind, Animaginary delivers stunning animations that are both smooth and seamless, even on lower-end devices. The library is designed to provide developers with a powerful toolset that makes it easy to create -complex animations that would otherwise be time-consuming and challenging to build.`,date:"2023-03-08",tags:[],wordCount:86,lineCount:7,minutesToRead:0,title:"Animaginary",url:"/blog",image:"/img/whatsnew/animaginary.svg",group:"Animaginary"}]},components:{blog:{"vite-press-plugin":()=>Ve(()=>import("./2024-03-01_vite-press-plugin-BV6PDf7d.js"),__vite__mapDeps([24,7])),"markdown-components-in-vue":()=>Ve(()=>import("./2024-02-28_markdown-components-in-vue-BMrj5Q1x.js"),__vite__mapDeps([25,7,4,26,27,28])),"net8-best-blazor":()=>Ve(()=>import("./2023-11-22_net8-best-blazor-wjwjFuPp.js"),__vite__mapDeps([29,7,27,30])),"net8-blazor-template":()=>Ve(()=>import("./2023-11-20_net8-blazor-template-BS9qPuaN.js"),__vite__mapDeps([31,7,30])),"razor-ssg-new-blog-features":()=>Ve(()=>import("./2023-08-23_razor-ssg-new-blog-features-DA5S93ND.js"),__vite__mapDeps([32,7,4,28])),"razor-ssg":()=>Ve(()=>import("./2023-03-30_razor-ssg-Ci0fv4r7.js"),__vite__mapDeps([33,7,4])),javascript:()=>Ve(()=>import("./2023-02-01_javascript-BozINeQT.js"),__vite__mapDeps([34,7,26,27])),start:()=>Ve(()=>import("./2023-01-21_start-BLjTU3tE.js"),__vite__mapDeps([35,7])),rider:()=>Ve(()=>import("./2023-01-11_rider-BIj5SqpT.js"),__vite__mapDeps([36,7])),vs:()=>Ve(()=>import("./2023-01-10_vs-CnHF8_tj.js"),__vite__mapDeps([37,7])),deploy:()=>Ve(()=>import("./2023-01-01_deploy-DS48nsUk.js"),__vite__mapDeps([38,7])),typography:()=>Ve(()=>import("./2022-12-31_typography-CQ2u4p7c.js"),__vite__mapDeps([39,7])),"hetzner-cloud":()=>Ve(()=>import("./2022-09-06_hetzner-cloud-CMGV4KKw.js"),__vite__mapDeps([40,7,41]))},videos:{vue:{autoquerygrid:()=>Ve(()=>import("./autoquerygrid-B8jP3C5m.js"),__vite__mapDeps([42,7])),components:()=>Ve(()=>import("./components-D8n2u9I9.js"),__vite__mapDeps([43,7])),admin:()=>Ve(()=>import("./admin-ddEAmk2a.js"),__vite__mapDeps([44,7])),modern:()=>Ve(()=>import("./modern-CCyvQdVa.js"),__vite__mapDeps([45,7]))}},whatsNew:{"2023-03-28_Planetaria":{feature1:()=>Ve(()=>import("./feature1-BJlXHRzt.js"),__vite__mapDeps([46,7]))},"2023-03-18_OpenShuttle":{feature1:()=>Ve(()=>import("./feature1-B0cK-EMF.js"),__vite__mapDeps([47,7]))},"2023-03-08_Animaginary":{feature1:()=>Ve(()=>import("./feature1-B9tl-y8M.js"),__vite__mapDeps([48,7]))}},includes:{"component-links.md":()=>Ve(()=>import("./component-links-B0AHB4nY.js"),__vite__mapDeps([49,7])),"features.md":()=>Ve(()=>import("./features-DgyWH2Q5.js"),__vite__mapDeps([50,7]))}}},Oo=/^[a-z0-9]+(-[a-z0-9]+)*$/,Sr=(e,t,n,o="")=>{const s=e.split(":");if(e.slice(0,1)==="@"){if(s.length<2||s.length>3)return null;o=s.shift().slice(1)}if(s.length>3||!s.length)return null;if(s.length>1){const l=s.pop(),i=s.pop(),u={provider:s.length>0?s[0]:o,prefix:i,name:l};return t&&!Bs(u)?null:u}const r=s[0],a=r.split("-");if(a.length>1){const l={provider:o,prefix:a.shift(),name:a.join("-")};return t&&!Bs(l)?null:l}if(n&&o===""){const l={provider:o,prefix:"",name:r};return t&&!Bs(l,n)?null:l}return null},Bs=(e,t)=>e?!!((e.provider===""||e.provider.match(Oo))&&(t&&e.prefix===""||e.prefix.match(Oo))&&e.name.match(Oo)):!1,Pd=Object.freeze({left:0,top:0,width:16,height:16}),tr=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),Tr=Object.freeze({...Pd,...tr}),Ta=Object.freeze({...Tr,body:"",hidden:!1});function s4(e,t){const n={};!e.hFlip!=!t.hFlip&&(n.hFlip=!0),!e.vFlip!=!t.vFlip&&(n.vFlip=!0);const o=((e.rotate||0)+(t.rotate||0))%4;return o&&(n.rotate=o),n}function cu(e,t){const n=s4(e,t);for(const o in Ta)o in tr?o in e&&!(o in n)&&(n[o]=tr[o]):o in t?n[o]=t[o]:o in e&&(n[o]=e[o]);return n}function r4(e,t){const n=e.icons,o=e.aliases||Object.create(null),s=Object.create(null);function r(a){if(n[a])return s[a]=[];if(!(a in s)){s[a]=null;const l=o[a]&&o[a].parent,i=l&&r(l);i&&(s[a]=[l].concat(i))}return s[a]}return(t||Object.keys(n).concat(Object.keys(o))).forEach(r),s}function a4(e,t,n){const o=e.icons,s=e.aliases||Object.create(null);let r={};function a(l){r=cu(o[l]||s[l],r)}return a(t),n.forEach(a),cu(e,r)}function Ed(e,t){const n=[];if(typeof e!="object"||typeof e.icons!="object")return n;e.not_found instanceof Array&&e.not_found.forEach(s=>{t(s,null),n.push(s)});const o=r4(e);for(const s in o){const r=o[s];r&&(t(s,a4(e,s,r)),n.push(s))}return n}const i4={provider:"",aliases:{},not_found:{},...Pd};function Jr(e,t){for(const n in t)if(n in e&&typeof e[n]!=typeof t[n])return!1;return!0}function Id(e){if(typeof e!="object"||e===null)return null;const t=e;if(typeof t.prefix!="string"||!e.icons||typeof e.icons!="object"||!Jr(e,i4))return null;const n=t.icons;for(const s in n){const r=n[s];if(!s.match(Oo)||typeof r.body!="string"||!Jr(r,Ta))return null}const o=t.aliases||Object.create(null);for(const s in o){const r=o[s],a=r.parent;if(!s.match(Oo)||typeof a!="string"||!n[a]&&!o[a]||!Jr(r,Ta))return null}return t}const du=Object.create(null);function l4(e,t){return{provider:e,prefix:t,icons:Object.create(null),missing:new Set}}function Hn(e,t){const n=du[e]||(du[e]=Object.create(null));return n[t]||(n[t]=l4(e,t))}function Si(e,t){return Id(t)?Ed(t,(n,o)=>{o?e.icons[n]=o:e.missing.add(n)}):[]}function u4(e,t,n){try{if(typeof n.body=="string")return e.icons[t]={...n},!0}catch{}return!1}let Qo=!1;function Ld(e){return typeof e=="boolean"&&(Qo=e),Qo}function c4(e){const t=typeof e=="string"?Sr(e,!0,Qo):e;if(t){const n=Hn(t.provider,t.prefix),o=t.name;return n.icons[o]||(n.missing.has(o)?null:void 0)}}function d4(e,t){const n=Sr(e,!0,Qo);if(!n)return!1;const o=Hn(n.provider,n.prefix);return u4(o,n.name,t)}function p4(e,t){if(typeof e!="object")return!1;if(typeof t!="string"&&(t=e.provider||""),Qo&&!t&&!e.prefix){let s=!1;return Id(e)&&(e.prefix="",Ed(e,(r,a)=>{a&&d4(r,a)&&(s=!0)})),s}const n=e.prefix;if(!Bs({provider:t,prefix:n,name:"a"}))return!1;const o=Hn(t,n);return!!Si(o,e)}const zd=Object.freeze({width:null,height:null}),Rd=Object.freeze({...zd,...tr}),f4=/(-?[0-9.]*[0-9]+[0-9.]*)/g,h4=/^-?[0-9.]*[0-9]+[0-9.]*$/g;function pu(e,t,n){if(t===1)return e;if(n=n||100,typeof e=="number")return Math.ceil(e*t*n)/n;if(typeof e!="string")return e;const o=e.split(f4);if(o===null||!o.length)return e;const s=[];let r=o.shift(),a=h4.test(r);for(;;){if(a){const l=parseFloat(r);isNaN(l)?s.push(r):s.push(Math.ceil(l*t*n)/n)}else s.push(r);if(r=o.shift(),r===void 0)return s.join("");a=!a}}const m4=e=>e==="unset"||e==="undefined"||e==="none";function g4(e,t){const n={...Tr,...e},o={...Rd,...t},s={left:n.left,top:n.top,width:n.width,height:n.height};let r=n.body;[n,o].forEach(v=>{const w=[],S=v.hFlip,z=v.vFlip;let $=v.rotate;S?z?$+=2:(w.push("translate("+(s.width+s.left).toString()+" "+(0-s.top).toString()+")"),w.push("scale(-1 1)"),s.top=s.left=0):z&&(w.push("translate("+(0-s.left).toString()+" "+(s.height+s.top).toString()+")"),w.push("scale(1 -1)"),s.top=s.left=0);let A;switch($<0&&($-=Math.floor($/4)*4),$=$%4,$){case 1:A=s.height/2+s.top,w.unshift("rotate(90 "+A.toString()+" "+A.toString()+")");break;case 2:w.unshift("rotate(180 "+(s.width/2+s.left).toString()+" "+(s.height/2+s.top).toString()+")");break;case 3:A=s.width/2+s.left,w.unshift("rotate(-90 "+A.toString()+" "+A.toString()+")");break}$%2===1&&(s.left!==s.top&&(A=s.left,s.left=s.top,s.top=A),s.width!==s.height&&(A=s.width,s.width=s.height,s.height=A)),w.length&&(r=''+r+"")});const a=o.width,l=o.height,i=s.width,u=s.height;let c,p;a===null?(p=l===null?"1em":l==="auto"?u:l,c=pu(p,i/u)):(c=a==="auto"?i:a,p=l===null?pu(c,u/i):l==="auto"?u:l);const f={},m=(v,w)=>{m4(w)||(f[v]=w.toString())};return m("width",c),m("height",p),f.viewBox=s.left.toString()+" "+s.top.toString()+" "+i.toString()+" "+u.toString(),{attributes:f,body:r}}const v4=/\sid="(\S+)"/g,y4="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16);let b4=0;function w4(e,t=y4){const n=[];let o;for(;o=v4.exec(e);)n.push(o[1]);if(!n.length)return e;const s="suffix"+(Math.random()*16777216|Date.now()).toString(16);return n.forEach(r=>{const a=typeof t=="function"?t(r):t+(b4++).toString(),l=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");e=e.replace(new RegExp('([#;"])('+l+')([")]|\\.[a-z])',"g"),"$1"+a+s+"$3")}),e=e.replace(new RegExp(s,"g"),""),e}const Aa=Object.create(null);function k4(e,t){Aa[e]=t}function _a(e){return Aa[e]||Aa[""]}function Ti(e){let t;if(typeof e.resources=="string")t=[e.resources];else if(t=e.resources,!(t instanceof Array)||!t.length)return null;return{resources:t,path:e.path||"/",maxURL:e.maxURL||500,rotate:e.rotate||750,timeout:e.timeout||5e3,random:e.random===!0,index:e.index||0,dataAfterTimeout:e.dataAfterTimeout!==!1}}const Ai=Object.create(null),To=["https://api.simplesvg.com","https://api.unisvg.com"],Ds=[];for(;To.length>0;)To.length===1||Math.random()>.5?Ds.push(To.shift()):Ds.push(To.pop());Ai[""]=Ti({resources:["https://api.iconify.design"].concat(Ds)});function x4(e,t){const n=Ti(t);return n===null?!1:(Ai[e]=n,!0)}function _i(e){return Ai[e]}const C4=()=>{let e;try{if(e=fetch,typeof e=="function")return e}catch{}};let fu=C4();function S4(e,t){const n=_i(e);if(!n)return 0;let o;if(!n.maxURL)o=0;else{let s=0;n.resources.forEach(a=>{s=Math.max(s,a.length)});const r=t+".json?icons=";o=n.maxURL-s-n.path.length-r.length}return o}function T4(e){return e===404}const A4=(e,t,n)=>{const o=[],s=S4(e,t),r="icons";let a={type:r,provider:e,prefix:t,icons:[]},l=0;return n.forEach((i,u)=>{l+=i.length+1,l>=s&&u>0&&(o.push(a),a={type:r,provider:e,prefix:t,icons:[]},l=i.length),a.icons.push(i)}),o.push(a),o};function _4(e){if(typeof e=="string"){const t=_i(e);if(t)return t.path}return"/"}const M4=(e,t,n)=>{if(!fu){n("abort",424);return}let o=_4(t.provider);switch(t.type){case"icons":{const r=t.prefix,l=t.icons.join(","),i=new URLSearchParams({icons:l});o+=r+".json?"+i.toString();break}case"custom":{const r=t.uri;o+=r.slice(0,1)==="/"?r.slice(1):r;break}default:n("abort",400);return}let s=503;fu(e+o).then(r=>{const a=r.status;if(a!==200){setTimeout(()=>{n(T4(a)?"abort":"next",a)});return}return s=501,r.json()}).then(r=>{if(typeof r!="object"||r===null){setTimeout(()=>{r===404?n("abort",r):n("next",s)});return}setTimeout(()=>{n("success",r)})}).catch(()=>{n("next",s)})},P4={prepare:A4,send:M4};function E4(e){const t={loaded:[],missing:[],pending:[]},n=Object.create(null);e.sort((s,r)=>s.provider!==r.provider?s.provider.localeCompare(r.provider):s.prefix!==r.prefix?s.prefix.localeCompare(r.prefix):s.name.localeCompare(r.name));let o={provider:"",prefix:"",name:""};return e.forEach(s=>{if(o.name===s.name&&o.prefix===s.prefix&&o.provider===s.provider)return;o=s;const r=s.provider,a=s.prefix,l=s.name,i=n[r]||(n[r]=Object.create(null)),u=i[a]||(i[a]=Hn(r,a));let c;l in u.icons?c=t.loaded:a===""||u.missing.has(l)?c=t.missing:c=t.pending;const p={provider:r,prefix:a,name:l};c.push(p)}),t}function jd(e,t){e.forEach(n=>{const o=n.loaderCallbacks;o&&(n.loaderCallbacks=o.filter(s=>s.id!==t))})}function I4(e){e.pendingCallbacksFlag||(e.pendingCallbacksFlag=!0,setTimeout(()=>{e.pendingCallbacksFlag=!1;const t=e.loaderCallbacks?e.loaderCallbacks.slice(0):[];if(!t.length)return;let n=!1;const o=e.provider,s=e.prefix;t.forEach(r=>{const a=r.icons,l=a.pending.length;a.pending=a.pending.filter(i=>{if(i.prefix!==s)return!0;const u=i.name;if(e.icons[u])a.loaded.push({provider:o,prefix:s,name:u});else if(e.missing.has(u))a.missing.push({provider:o,prefix:s,name:u});else return n=!0,!0;return!1}),a.pending.length!==l&&(n||jd([e],r.id),r.callback(a.loaded.slice(0),a.missing.slice(0),a.pending.slice(0),r.abort))})}))}let L4=0;function z4(e,t,n){const o=L4++,s=jd.bind(null,n,o);if(!t.pending.length)return s;const r={id:o,icons:t,callback:e,abort:s};return n.forEach(a=>{(a.loaderCallbacks||(a.loaderCallbacks=[])).push(r)}),s}function R4(e,t=!0,n=!1){const o=[];return e.forEach(s=>{const r=typeof s=="string"?Sr(s,t,n):s;r&&o.push(r)}),o}var j4={resources:[],index:0,timeout:2e3,rotate:750,random:!1,dataAfterTimeout:!1};function V4(e,t,n,o){const s=e.resources.length,r=e.random?Math.floor(Math.random()*s):e.index;let a;if(e.random){let D=e.resources.slice(0);for(a=[];D.length>1;){const P=Math.floor(Math.random()*D.length);a.push(D[P]),D=D.slice(0,P).concat(D.slice(P+1))}a=a.concat(D)}else a=e.resources.slice(r).concat(e.resources.slice(0,r));const l=Date.now();let i="pending",u=0,c,p=null,f=[],m=[];typeof o=="function"&&m.push(o);function v(){p&&(clearTimeout(p),p=null)}function w(){i==="pending"&&(i="aborted"),v(),f.forEach(D=>{D.status==="pending"&&(D.status="aborted")}),f=[]}function S(D,P){P&&(m=[]),typeof D=="function"&&m.push(D)}function z(){return{startTime:l,payload:t,status:i,queriesSent:u,queriesPending:f.length,subscribe:S,abort:w}}function $(){i="failed",m.forEach(D=>{D(void 0,c)})}function A(){f.forEach(D=>{D.status==="pending"&&(D.status="aborted")}),f=[]}function N(D,P,ne){const Z=P!=="success";switch(f=f.filter(ge=>ge!==D),i){case"pending":break;case"failed":if(Z||!e.dataAfterTimeout)return;break;default:return}if(P==="abort"){c=ne,$();return}if(Z){c=ne,f.length||(a.length?B():$());return}if(v(),A(),!e.random){const ge=e.resources.indexOf(D.resource);ge!==-1&&ge!==e.index&&(e.index=ge)}i="completed",m.forEach(ge=>{ge(ne)})}function B(){if(i!=="pending")return;v();const D=a.shift();if(D===void 0){if(f.length){p=setTimeout(()=>{v(),i==="pending"&&(A(),$())},e.timeout);return}$();return}const P={status:"pending",resource:D,callback:(ne,Z)=>{N(P,ne,Z)}};f.push(P),u++,p=setTimeout(B,e.rotate),n(D,t,P.callback)}return setTimeout(B),z}function Vd(e){const t={...j4,...e};let n=[];function o(){n=n.filter(l=>l().status==="pending")}function s(l,i,u){const c=V4(t,l,i,(p,f)=>{o(),u&&u(p,f)});return n.push(c),c}function r(l){return n.find(i=>l(i))||null}return{query:s,find:r,setIndex:l=>{t.index=l},getIndex:()=>t.index,cleanup:o}}function hu(){}const Qr=Object.create(null);function O4(e){if(!Qr[e]){const t=_i(e);if(!t)return;const n=Vd(t),o={config:t,redundancy:n};Qr[e]=o}return Qr[e]}function B4(e,t,n){let o,s;if(typeof e=="string"){const r=_a(e);if(!r)return n(void 0,424),hu;s=r.send;const a=O4(e);a&&(o=a.redundancy)}else{const r=Ti(e);if(r){o=Vd(r);const a=e.resources?e.resources[0]:"",l=_a(a);l&&(s=l.send)}}return!o||!s?(n(void 0,424),hu):o.query(t,s,n)().abort}const mu="iconify2",Ko="iconify",Od=Ko+"-count",gu=Ko+"-version",Bd=36e5,D4=168;function Ma(e,t){try{return e.getItem(t)}catch{}}function Mi(e,t,n){try{return e.setItem(t,n),!0}catch{}}function vu(e,t){try{e.removeItem(t)}catch{}}function Pa(e,t){return Mi(e,Od,t.toString())}function Ea(e){return parseInt(Ma(e,Od))||0}const Ar={local:!0,session:!0},Dd={local:new Set,session:new Set};let Pi=!1;function H4(e){Pi=e}let Ss=typeof window>"u"?{}:window;function Hd(e){const t=e+"Storage";try{if(Ss&&Ss[t]&&typeof Ss[t].length=="number")return Ss[t]}catch{}Ar[e]=!1}function $d(e,t){const n=Hd(e);if(!n)return;const o=Ma(n,gu);if(o!==mu){if(o){const l=Ea(n);for(let i=0;i{const i=Ko+l.toString(),u=Ma(n,i);if(typeof u=="string"){try{const c=JSON.parse(u);if(typeof c=="object"&&typeof c.cached=="number"&&c.cached>s&&typeof c.provider=="string"&&typeof c.data=="object"&&typeof c.data.prefix=="string"&&t(c,l))return!0}catch{}vu(n,i)}};let a=Ea(n);for(let l=a-1;l>=0;l--)r(l)||(l===a-1?(a--,Pa(n,a)):Dd[e].add(l))}function Nd(){if(!Pi){H4(!0);for(const e in Ar)$d(e,t=>{const n=t.data,o=t.provider,s=n.prefix,r=Hn(o,s);if(!Si(r,n).length)return!1;const a=n.lastModified||-1;return r.lastModifiedCached=r.lastModifiedCached?Math.min(r.lastModifiedCached,a):a,!0})}}function $4(e,t){const n=e.lastModifiedCached;if(n&&n>=t)return n===t;if(e.lastModifiedCached=t,n)for(const o in Ar)$d(o,s=>{const r=s.data;return s.provider!==e.provider||r.prefix!==e.prefix||r.lastModified===t});return!0}function N4(e,t){Pi||Nd();function n(o){let s;if(!Ar[o]||!(s=Hd(o)))return;const r=Dd[o];let a;if(r.size)r.delete(a=Array.from(r).shift());else if(a=Ea(s),!Pa(s,a+1))return;const l={cached:Math.floor(Date.now()/Bd),provider:e.provider,data:t};return Mi(s,Ko+a.toString(),JSON.stringify(l))}t.lastModified&&!$4(e,t.lastModified)||Object.keys(t.icons).length&&(t.not_found&&(t=Object.assign({},t),delete t.not_found),n("local")||n("session"))}function yu(){}function F4(e){e.iconsLoaderFlag||(e.iconsLoaderFlag=!0,setTimeout(()=>{e.iconsLoaderFlag=!1,I4(e)}))}function U4(e,t){e.iconsToLoad?e.iconsToLoad=e.iconsToLoad.concat(t).sort():e.iconsToLoad=t,e.iconsQueueFlag||(e.iconsQueueFlag=!0,setTimeout(()=>{e.iconsQueueFlag=!1;const{provider:n,prefix:o}=e,s=e.iconsToLoad;delete e.iconsToLoad;let r;if(!s||!(r=_a(n)))return;r.prepare(n,o,s).forEach(l=>{B4(n,l,i=>{if(typeof i!="object")l.icons.forEach(u=>{e.missing.add(u)});else try{const u=Si(e,i);if(!u.length)return;const c=e.pendingIcons;c&&u.forEach(p=>{c.delete(p)}),N4(e,i)}catch(u){console.error(u)}F4(e)})})}))}const W4=(e,t)=>{const n=R4(e,!0,Ld()),o=E4(n);if(!o.pending.length){let i=!0;return t&&setTimeout(()=>{i&&t(o.loaded,o.missing,o.pending,yu)}),()=>{i=!1}}const s=Object.create(null),r=[];let a,l;return o.pending.forEach(i=>{const{provider:u,prefix:c}=i;if(c===l&&u===a)return;a=u,l=c,r.push(Hn(u,c));const p=s[u]||(s[u]=Object.create(null));p[c]||(p[c]=[])}),o.pending.forEach(i=>{const{provider:u,prefix:c,name:p}=i,f=Hn(u,c),m=f.pendingIcons||(f.pendingIcons=new Set);m.has(p)||(m.add(p),s[u][c].push(p))}),r.forEach(i=>{const{provider:u,prefix:c}=i;s[u][c].length&&U4(i,s[u][c])}),t?z4(t,o,r):yu};function q4(e,t){const n={...e};for(const o in t){const s=t[o],r=typeof s;o in zd?(s===null||s&&(r==="string"||r==="number"))&&(n[o]=s):r===typeof n[o]&&(n[o]=o==="rotate"?s%4:s)}return n}const G4=/[\s,]+/;function J4(e,t){t.split(G4).forEach(n=>{switch(n.trim()){case"horizontal":e.hFlip=!0;break;case"vertical":e.vFlip=!0;break}})}function Q4(e,t=0){const n=e.replace(/^-?[0-9.]*/,"");function o(s){for(;s<0;)s+=4;return s%4}if(n===""){const s=parseInt(e);return isNaN(s)?0:o(s)}else if(n!==e){let s=0;switch(n){case"%":s=25;break;case"deg":s=90}if(s){let r=parseFloat(e.slice(0,e.length-n.length));return isNaN(r)?0:(r=r/s,r%1===0?o(r):0)}}return t}function K4(e,t){let n=e.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(const o in t)n+=" "+o+'="'+t[o]+'"';return'"+e+""}function Y4(e){return e.replace(/"/g,"'").replace(/%/g,"%25").replace(/#/g,"%23").replace(//g,"%3E").replace(/\s+/g," ")}function Z4(e){return"data:image/svg+xml,"+Y4(e)}function X4(e){return'url("'+Z4(e)+'")'}const bu={...Rd,inline:!1},e6={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":!0,role:"img"},t6={display:"inline-block"},Ia={backgroundColor:"currentColor"},Fd={backgroundColor:"transparent"},wu={Image:"var(--svg)",Repeat:"no-repeat",Size:"100% 100%"},ku={webkitMask:Ia,mask:Ia,background:Fd};for(const e in ku){const t=ku[e];for(const n in wu)t[e+n]=wu[n]}const Hs={};["horizontal","vertical"].forEach(e=>{const t=e.slice(0,1)+"Flip";Hs[e+"-flip"]=t,Hs[e.slice(0,1)+"-flip"]=t,Hs[e+"Flip"]=t});function xu(e){return e+(e.match(/^[-0-9.]+$/)?"px":"")}const Cu=(e,t)=>{const n=q4(bu,t),o={...e6},s=t.mode||"svg",r={},a=t.style,l=typeof a=="object"&&!(a instanceof Array)?a:{};for(let w in t){const S=t[w];if(S!==void 0)switch(w){case"icon":case"style":case"onLoad":case"mode":break;case"inline":case"hFlip":case"vFlip":n[w]=S===!0||S==="true"||S===1;break;case"flip":typeof S=="string"&&J4(n,S);break;case"color":r.color=S;break;case"rotate":typeof S=="string"?n[w]=Q4(S):typeof S=="number"&&(n[w]=S);break;case"ariaHidden":case"aria-hidden":S!==!0&&S!=="true"&&delete o["aria-hidden"];break;default:{const z=Hs[w];z?(S===!0||S==="true"||S===1)&&(n[z]=!0):bu[w]===void 0&&(o[w]=S)}}}const i=g4(e,n),u=i.attributes;if(n.inline&&(r.verticalAlign="-0.125em"),s==="svg"){o.style={...r,...l},Object.assign(o,u);let w=0,S=t.id;return typeof S=="string"&&(S=S.replace(/-/g,"_")),o.innerHTML=w4(i.body,S?()=>S+"ID"+w++:"iconifyVue"),Tt("svg",o)}const{body:c,width:p,height:f}=e,m=s==="mask"||(s==="bg"?!1:c.indexOf("currentColor")!==-1),v=K4(c,{...u,width:p+"",height:f+""});return o.style={...r,"--svg":X4(v),width:xu(u.width),height:xu(u.height),...t6,...m?Ia:Fd,...l},Tt("span",o)};Ld(!0);k4("",P4);if(typeof document<"u"&&typeof window<"u"){Nd();const e=window;if(e.IconifyPreload!==void 0){const t=e.IconifyPreload,n="Invalid IconifyPreload syntax.";typeof t=="object"&&t!==null&&(t instanceof Array?t:[t]).forEach(o=>{try{(typeof o!="object"||o===null||o instanceof Array||typeof o.icons!="object"||typeof o.prefix!="string"||!p4(o))&&console.error(n)}catch{console.error(n)}})}if(e.IconifyProviders!==void 0){const t=e.IconifyProviders;if(typeof t=="object"&&t!==null)for(let n in t){const o="IconifyProviders["+n+"] is invalid.";try{const s=t[n];if(typeof s!="object"||!s||s.resources===void 0)continue;x4(n,s)||console.error(o)}catch{console.error(o)}}}}const n6={...Tr,body:""},o6=Ce({inheritAttrs:!1,data(){return{iconMounted:!1,counter:0}},mounted(){this._name="",this._loadingIcon=null,this.iconMounted=!0},unmounted(){this.abortLoading()},methods:{abortLoading(){this._loadingIcon&&(this._loadingIcon.abort(),this._loadingIcon=null)},getIcon(e,t){if(typeof e=="object"&&e!==null&&typeof e.body=="string")return this._name="",this.abortLoading(),{data:e};let n;if(typeof e!="string"||(n=Sr(e,!1,!0))===null)return this.abortLoading(),null;const o=c4(n);if(!o)return(!this._loadingIcon||this._loadingIcon.name!==e)&&(this.abortLoading(),this._name="",o!==null&&(this._loadingIcon={name:e,abort:W4([n],()=>{this.counter++})})),null;this.abortLoading(),this._name!==e&&(this._name=e,t&&t(e));const s=["iconify"];return n.prefix!==""&&s.push("iconify--"+n.prefix),n.provider!==""&&s.push("iconify--"+n.provider),{data:o,classes:s}}},render(){this.counter;const e=this.$attrs,t=this.iconMounted?this.getIcon(e.icon,e.onLoad):null;if(!t)return Cu(n6,e);let n=e;return t.classes&&(n={...e,class:(typeof e.class=="string"?e.class+" ":"")+t.classes.join(" ")}),Cu({...Tr,...t.data},n)}});/*! +complex animations that would otherwise be time-consuming and challenging to build.`,date:"2023-03-08",tags:[],wordCount:86,lineCount:7,minutesToRead:0,title:"Animaginary",url:"/blog",image:"/img/whatsnew/animaginary.svg",group:"Animaginary"}]},components:{blog:{"vite-press-plugin":()=>Ve(()=>import("./2024-03-01_vite-press-plugin-DJwsPj6t.js"),__vite__mapDeps([24,7])),"markdown-components-in-vue":()=>Ve(()=>import("./2024-02-28_markdown-components-in-vue-OgPNuM_j.js"),__vite__mapDeps([25,7,4,26,27,28])),"net8-best-blazor":()=>Ve(()=>import("./2023-11-22_net8-best-blazor-B8AK7TtK.js"),__vite__mapDeps([29,7,27,30])),"net8-blazor-template":()=>Ve(()=>import("./2023-11-20_net8-blazor-template-csCQIEk-.js"),__vite__mapDeps([31,7,30])),"razor-ssg-new-blog-features":()=>Ve(()=>import("./2023-08-23_razor-ssg-new-blog-features-DJ1Rr8VN.js"),__vite__mapDeps([32,7,4,28])),"razor-ssg":()=>Ve(()=>import("./2023-03-30_razor-ssg-h6EyxEND.js"),__vite__mapDeps([33,7,4])),javascript:()=>Ve(()=>import("./2023-02-01_javascript-DsU9PqrK.js"),__vite__mapDeps([34,7,26,27])),start:()=>Ve(()=>import("./2023-01-21_start-Dvy20kPM.js"),__vite__mapDeps([35,7])),rider:()=>Ve(()=>import("./2023-01-11_rider-C1RjBW7K.js"),__vite__mapDeps([36,7])),vs:()=>Ve(()=>import("./2023-01-10_vs-Dpo3fFRu.js"),__vite__mapDeps([37,7])),deploy:()=>Ve(()=>import("./2023-01-01_deploy-Bh3tgLQ9.js"),__vite__mapDeps([38,7])),typography:()=>Ve(()=>import("./2022-12-31_typography-C35AONwX.js"),__vite__mapDeps([39,7])),"hetzner-cloud":()=>Ve(()=>import("./2022-09-06_hetzner-cloud-B9u-MxgU.js"),__vite__mapDeps([40,7,41]))},videos:{vue:{autoquerygrid:()=>Ve(()=>import("./autoquerygrid-CYIg7oz6.js"),__vite__mapDeps([42,7])),components:()=>Ve(()=>import("./components-Q0dmsTg-.js"),__vite__mapDeps([43,7])),admin:()=>Ve(()=>import("./admin-DfK6L5xt.js"),__vite__mapDeps([44,7])),modern:()=>Ve(()=>import("./modern-DHYi0nI9.js"),__vite__mapDeps([45,7]))}},whatsNew:{"2023-03-28_Planetaria":{feature1:()=>Ve(()=>import("./feature1-CYSjmA7I.js"),__vite__mapDeps([46,7]))},"2023-03-18_OpenShuttle":{feature1:()=>Ve(()=>import("./feature1-CvHTx5Sl.js"),__vite__mapDeps([47,7]))},"2023-03-08_Animaginary":{feature1:()=>Ve(()=>import("./feature1-FhqPQYoT.js"),__vite__mapDeps([48,7]))}},includes:{"component-links.md":()=>Ve(()=>import("./component-links-B6Jg27wb.js"),__vite__mapDeps([49,7])),"features.md":()=>Ve(()=>import("./features-nHCxd1P1.js"),__vite__mapDeps([50,7]))}}},Oo=/^[a-z0-9]+(-[a-z0-9]+)*$/,Sr=(e,t,n,o="")=>{const s=e.split(":");if(e.slice(0,1)==="@"){if(s.length<2||s.length>3)return null;o=s.shift().slice(1)}if(s.length>3||!s.length)return null;if(s.length>1){const l=s.pop(),i=s.pop(),u={provider:s.length>0?s[0]:o,prefix:i,name:l};return t&&!Bs(u)?null:u}const r=s[0],a=r.split("-");if(a.length>1){const l={provider:o,prefix:a.shift(),name:a.join("-")};return t&&!Bs(l)?null:l}if(n&&o===""){const l={provider:o,prefix:"",name:r};return t&&!Bs(l,n)?null:l}return null},Bs=(e,t)=>e?!!((e.provider===""||e.provider.match(Oo))&&(t&&e.prefix===""||e.prefix.match(Oo))&&e.name.match(Oo)):!1,Pd=Object.freeze({left:0,top:0,width:16,height:16}),tr=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),Tr=Object.freeze({...Pd,...tr}),Ta=Object.freeze({...Tr,body:"",hidden:!1});function s4(e,t){const n={};!e.hFlip!=!t.hFlip&&(n.hFlip=!0),!e.vFlip!=!t.vFlip&&(n.vFlip=!0);const o=((e.rotate||0)+(t.rotate||0))%4;return o&&(n.rotate=o),n}function cu(e,t){const n=s4(e,t);for(const o in Ta)o in tr?o in e&&!(o in n)&&(n[o]=tr[o]):o in t?n[o]=t[o]:o in e&&(n[o]=e[o]);return n}function r4(e,t){const n=e.icons,o=e.aliases||Object.create(null),s=Object.create(null);function r(a){if(n[a])return s[a]=[];if(!(a in s)){s[a]=null;const l=o[a]&&o[a].parent,i=l&&r(l);i&&(s[a]=[l].concat(i))}return s[a]}return(t||Object.keys(n).concat(Object.keys(o))).forEach(r),s}function a4(e,t,n){const o=e.icons,s=e.aliases||Object.create(null);let r={};function a(l){r=cu(o[l]||s[l],r)}return a(t),n.forEach(a),cu(e,r)}function Ed(e,t){const n=[];if(typeof e!="object"||typeof e.icons!="object")return n;e.not_found instanceof Array&&e.not_found.forEach(s=>{t(s,null),n.push(s)});const o=r4(e);for(const s in o){const r=o[s];r&&(t(s,a4(e,s,r)),n.push(s))}return n}const i4={provider:"",aliases:{},not_found:{},...Pd};function Jr(e,t){for(const n in t)if(n in e&&typeof e[n]!=typeof t[n])return!1;return!0}function Id(e){if(typeof e!="object"||e===null)return null;const t=e;if(typeof t.prefix!="string"||!e.icons||typeof e.icons!="object"||!Jr(e,i4))return null;const n=t.icons;for(const s in n){const r=n[s];if(!s.match(Oo)||typeof r.body!="string"||!Jr(r,Ta))return null}const o=t.aliases||Object.create(null);for(const s in o){const r=o[s],a=r.parent;if(!s.match(Oo)||typeof a!="string"||!n[a]&&!o[a]||!Jr(r,Ta))return null}return t}const du=Object.create(null);function l4(e,t){return{provider:e,prefix:t,icons:Object.create(null),missing:new Set}}function Hn(e,t){const n=du[e]||(du[e]=Object.create(null));return n[t]||(n[t]=l4(e,t))}function Si(e,t){return Id(t)?Ed(t,(n,o)=>{o?e.icons[n]=o:e.missing.add(n)}):[]}function u4(e,t,n){try{if(typeof n.body=="string")return e.icons[t]={...n},!0}catch{}return!1}let Qo=!1;function Ld(e){return typeof e=="boolean"&&(Qo=e),Qo}function c4(e){const t=typeof e=="string"?Sr(e,!0,Qo):e;if(t){const n=Hn(t.provider,t.prefix),o=t.name;return n.icons[o]||(n.missing.has(o)?null:void 0)}}function d4(e,t){const n=Sr(e,!0,Qo);if(!n)return!1;const o=Hn(n.provider,n.prefix);return u4(o,n.name,t)}function p4(e,t){if(typeof e!="object")return!1;if(typeof t!="string"&&(t=e.provider||""),Qo&&!t&&!e.prefix){let s=!1;return Id(e)&&(e.prefix="",Ed(e,(r,a)=>{a&&d4(r,a)&&(s=!0)})),s}const n=e.prefix;if(!Bs({provider:t,prefix:n,name:"a"}))return!1;const o=Hn(t,n);return!!Si(o,e)}const zd=Object.freeze({width:null,height:null}),Rd=Object.freeze({...zd,...tr}),f4=/(-?[0-9.]*[0-9]+[0-9.]*)/g,h4=/^-?[0-9.]*[0-9]+[0-9.]*$/g;function pu(e,t,n){if(t===1)return e;if(n=n||100,typeof e=="number")return Math.ceil(e*t*n)/n;if(typeof e!="string")return e;const o=e.split(f4);if(o===null||!o.length)return e;const s=[];let r=o.shift(),a=h4.test(r);for(;;){if(a){const l=parseFloat(r);isNaN(l)?s.push(r):s.push(Math.ceil(l*t*n)/n)}else s.push(r);if(r=o.shift(),r===void 0)return s.join("");a=!a}}const m4=e=>e==="unset"||e==="undefined"||e==="none";function g4(e,t){const n={...Tr,...e},o={...Rd,...t},s={left:n.left,top:n.top,width:n.width,height:n.height};let r=n.body;[n,o].forEach(v=>{const w=[],S=v.hFlip,z=v.vFlip;let $=v.rotate;S?z?$+=2:(w.push("translate("+(s.width+s.left).toString()+" "+(0-s.top).toString()+")"),w.push("scale(-1 1)"),s.top=s.left=0):z&&(w.push("translate("+(0-s.left).toString()+" "+(s.height+s.top).toString()+")"),w.push("scale(1 -1)"),s.top=s.left=0);let A;switch($<0&&($-=Math.floor($/4)*4),$=$%4,$){case 1:A=s.height/2+s.top,w.unshift("rotate(90 "+A.toString()+" "+A.toString()+")");break;case 2:w.unshift("rotate(180 "+(s.width/2+s.left).toString()+" "+(s.height/2+s.top).toString()+")");break;case 3:A=s.width/2+s.left,w.unshift("rotate(-90 "+A.toString()+" "+A.toString()+")");break}$%2===1&&(s.left!==s.top&&(A=s.left,s.left=s.top,s.top=A),s.width!==s.height&&(A=s.width,s.width=s.height,s.height=A)),w.length&&(r=''+r+"")});const a=o.width,l=o.height,i=s.width,u=s.height;let c,p;a===null?(p=l===null?"1em":l==="auto"?u:l,c=pu(p,i/u)):(c=a==="auto"?i:a,p=l===null?pu(c,u/i):l==="auto"?u:l);const f={},m=(v,w)=>{m4(w)||(f[v]=w.toString())};return m("width",c),m("height",p),f.viewBox=s.left.toString()+" "+s.top.toString()+" "+i.toString()+" "+u.toString(),{attributes:f,body:r}}const v4=/\sid="(\S+)"/g,y4="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16);let b4=0;function w4(e,t=y4){const n=[];let o;for(;o=v4.exec(e);)n.push(o[1]);if(!n.length)return e;const s="suffix"+(Math.random()*16777216|Date.now()).toString(16);return n.forEach(r=>{const a=typeof t=="function"?t(r):t+(b4++).toString(),l=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");e=e.replace(new RegExp('([#;"])('+l+')([")]|\\.[a-z])',"g"),"$1"+a+s+"$3")}),e=e.replace(new RegExp(s,"g"),""),e}const Aa=Object.create(null);function k4(e,t){Aa[e]=t}function _a(e){return Aa[e]||Aa[""]}function Ti(e){let t;if(typeof e.resources=="string")t=[e.resources];else if(t=e.resources,!(t instanceof Array)||!t.length)return null;return{resources:t,path:e.path||"/",maxURL:e.maxURL||500,rotate:e.rotate||750,timeout:e.timeout||5e3,random:e.random===!0,index:e.index||0,dataAfterTimeout:e.dataAfterTimeout!==!1}}const Ai=Object.create(null),To=["https://api.simplesvg.com","https://api.unisvg.com"],Ds=[];for(;To.length>0;)To.length===1||Math.random()>.5?Ds.push(To.shift()):Ds.push(To.pop());Ai[""]=Ti({resources:["https://api.iconify.design"].concat(Ds)});function x4(e,t){const n=Ti(t);return n===null?!1:(Ai[e]=n,!0)}function _i(e){return Ai[e]}const C4=()=>{let e;try{if(e=fetch,typeof e=="function")return e}catch{}};let fu=C4();function S4(e,t){const n=_i(e);if(!n)return 0;let o;if(!n.maxURL)o=0;else{let s=0;n.resources.forEach(a=>{s=Math.max(s,a.length)});const r=t+".json?icons=";o=n.maxURL-s-n.path.length-r.length}return o}function T4(e){return e===404}const A4=(e,t,n)=>{const o=[],s=S4(e,t),r="icons";let a={type:r,provider:e,prefix:t,icons:[]},l=0;return n.forEach((i,u)=>{l+=i.length+1,l>=s&&u>0&&(o.push(a),a={type:r,provider:e,prefix:t,icons:[]},l=i.length),a.icons.push(i)}),o.push(a),o};function _4(e){if(typeof e=="string"){const t=_i(e);if(t)return t.path}return"/"}const M4=(e,t,n)=>{if(!fu){n("abort",424);return}let o=_4(t.provider);switch(t.type){case"icons":{const r=t.prefix,l=t.icons.join(","),i=new URLSearchParams({icons:l});o+=r+".json?"+i.toString();break}case"custom":{const r=t.uri;o+=r.slice(0,1)==="/"?r.slice(1):r;break}default:n("abort",400);return}let s=503;fu(e+o).then(r=>{const a=r.status;if(a!==200){setTimeout(()=>{n(T4(a)?"abort":"next",a)});return}return s=501,r.json()}).then(r=>{if(typeof r!="object"||r===null){setTimeout(()=>{r===404?n("abort",r):n("next",s)});return}setTimeout(()=>{n("success",r)})}).catch(()=>{n("next",s)})},P4={prepare:A4,send:M4};function E4(e){const t={loaded:[],missing:[],pending:[]},n=Object.create(null);e.sort((s,r)=>s.provider!==r.provider?s.provider.localeCompare(r.provider):s.prefix!==r.prefix?s.prefix.localeCompare(r.prefix):s.name.localeCompare(r.name));let o={provider:"",prefix:"",name:""};return e.forEach(s=>{if(o.name===s.name&&o.prefix===s.prefix&&o.provider===s.provider)return;o=s;const r=s.provider,a=s.prefix,l=s.name,i=n[r]||(n[r]=Object.create(null)),u=i[a]||(i[a]=Hn(r,a));let c;l in u.icons?c=t.loaded:a===""||u.missing.has(l)?c=t.missing:c=t.pending;const p={provider:r,prefix:a,name:l};c.push(p)}),t}function jd(e,t){e.forEach(n=>{const o=n.loaderCallbacks;o&&(n.loaderCallbacks=o.filter(s=>s.id!==t))})}function I4(e){e.pendingCallbacksFlag||(e.pendingCallbacksFlag=!0,setTimeout(()=>{e.pendingCallbacksFlag=!1;const t=e.loaderCallbacks?e.loaderCallbacks.slice(0):[];if(!t.length)return;let n=!1;const o=e.provider,s=e.prefix;t.forEach(r=>{const a=r.icons,l=a.pending.length;a.pending=a.pending.filter(i=>{if(i.prefix!==s)return!0;const u=i.name;if(e.icons[u])a.loaded.push({provider:o,prefix:s,name:u});else if(e.missing.has(u))a.missing.push({provider:o,prefix:s,name:u});else return n=!0,!0;return!1}),a.pending.length!==l&&(n||jd([e],r.id),r.callback(a.loaded.slice(0),a.missing.slice(0),a.pending.slice(0),r.abort))})}))}let L4=0;function z4(e,t,n){const o=L4++,s=jd.bind(null,n,o);if(!t.pending.length)return s;const r={id:o,icons:t,callback:e,abort:s};return n.forEach(a=>{(a.loaderCallbacks||(a.loaderCallbacks=[])).push(r)}),s}function R4(e,t=!0,n=!1){const o=[];return e.forEach(s=>{const r=typeof s=="string"?Sr(s,t,n):s;r&&o.push(r)}),o}var j4={resources:[],index:0,timeout:2e3,rotate:750,random:!1,dataAfterTimeout:!1};function V4(e,t,n,o){const s=e.resources.length,r=e.random?Math.floor(Math.random()*s):e.index;let a;if(e.random){let D=e.resources.slice(0);for(a=[];D.length>1;){const P=Math.floor(Math.random()*D.length);a.push(D[P]),D=D.slice(0,P).concat(D.slice(P+1))}a=a.concat(D)}else a=e.resources.slice(r).concat(e.resources.slice(0,r));const l=Date.now();let i="pending",u=0,c,p=null,f=[],m=[];typeof o=="function"&&m.push(o);function v(){p&&(clearTimeout(p),p=null)}function w(){i==="pending"&&(i="aborted"),v(),f.forEach(D=>{D.status==="pending"&&(D.status="aborted")}),f=[]}function S(D,P){P&&(m=[]),typeof D=="function"&&m.push(D)}function z(){return{startTime:l,payload:t,status:i,queriesSent:u,queriesPending:f.length,subscribe:S,abort:w}}function $(){i="failed",m.forEach(D=>{D(void 0,c)})}function A(){f.forEach(D=>{D.status==="pending"&&(D.status="aborted")}),f=[]}function N(D,P,ne){const Z=P!=="success";switch(f=f.filter(ge=>ge!==D),i){case"pending":break;case"failed":if(Z||!e.dataAfterTimeout)return;break;default:return}if(P==="abort"){c=ne,$();return}if(Z){c=ne,f.length||(a.length?B():$());return}if(v(),A(),!e.random){const ge=e.resources.indexOf(D.resource);ge!==-1&&ge!==e.index&&(e.index=ge)}i="completed",m.forEach(ge=>{ge(ne)})}function B(){if(i!=="pending")return;v();const D=a.shift();if(D===void 0){if(f.length){p=setTimeout(()=>{v(),i==="pending"&&(A(),$())},e.timeout);return}$();return}const P={status:"pending",resource:D,callback:(ne,Z)=>{N(P,ne,Z)}};f.push(P),u++,p=setTimeout(B,e.rotate),n(D,t,P.callback)}return setTimeout(B),z}function Vd(e){const t={...j4,...e};let n=[];function o(){n=n.filter(l=>l().status==="pending")}function s(l,i,u){const c=V4(t,l,i,(p,f)=>{o(),u&&u(p,f)});return n.push(c),c}function r(l){return n.find(i=>l(i))||null}return{query:s,find:r,setIndex:l=>{t.index=l},getIndex:()=>t.index,cleanup:o}}function hu(){}const Qr=Object.create(null);function O4(e){if(!Qr[e]){const t=_i(e);if(!t)return;const n=Vd(t),o={config:t,redundancy:n};Qr[e]=o}return Qr[e]}function B4(e,t,n){let o,s;if(typeof e=="string"){const r=_a(e);if(!r)return n(void 0,424),hu;s=r.send;const a=O4(e);a&&(o=a.redundancy)}else{const r=Ti(e);if(r){o=Vd(r);const a=e.resources?e.resources[0]:"",l=_a(a);l&&(s=l.send)}}return!o||!s?(n(void 0,424),hu):o.query(t,s,n)().abort}const mu="iconify2",Ko="iconify",Od=Ko+"-count",gu=Ko+"-version",Bd=36e5,D4=168;function Ma(e,t){try{return e.getItem(t)}catch{}}function Mi(e,t,n){try{return e.setItem(t,n),!0}catch{}}function vu(e,t){try{e.removeItem(t)}catch{}}function Pa(e,t){return Mi(e,Od,t.toString())}function Ea(e){return parseInt(Ma(e,Od))||0}const Ar={local:!0,session:!0},Dd={local:new Set,session:new Set};let Pi=!1;function H4(e){Pi=e}let Ss=typeof window>"u"?{}:window;function Hd(e){const t=e+"Storage";try{if(Ss&&Ss[t]&&typeof Ss[t].length=="number")return Ss[t]}catch{}Ar[e]=!1}function $d(e,t){const n=Hd(e);if(!n)return;const o=Ma(n,gu);if(o!==mu){if(o){const l=Ea(n);for(let i=0;i{const i=Ko+l.toString(),u=Ma(n,i);if(typeof u=="string"){try{const c=JSON.parse(u);if(typeof c=="object"&&typeof c.cached=="number"&&c.cached>s&&typeof c.provider=="string"&&typeof c.data=="object"&&typeof c.data.prefix=="string"&&t(c,l))return!0}catch{}vu(n,i)}};let a=Ea(n);for(let l=a-1;l>=0;l--)r(l)||(l===a-1?(a--,Pa(n,a)):Dd[e].add(l))}function Nd(){if(!Pi){H4(!0);for(const e in Ar)$d(e,t=>{const n=t.data,o=t.provider,s=n.prefix,r=Hn(o,s);if(!Si(r,n).length)return!1;const a=n.lastModified||-1;return r.lastModifiedCached=r.lastModifiedCached?Math.min(r.lastModifiedCached,a):a,!0})}}function $4(e,t){const n=e.lastModifiedCached;if(n&&n>=t)return n===t;if(e.lastModifiedCached=t,n)for(const o in Ar)$d(o,s=>{const r=s.data;return s.provider!==e.provider||r.prefix!==e.prefix||r.lastModified===t});return!0}function N4(e,t){Pi||Nd();function n(o){let s;if(!Ar[o]||!(s=Hd(o)))return;const r=Dd[o];let a;if(r.size)r.delete(a=Array.from(r).shift());else if(a=Ea(s),!Pa(s,a+1))return;const l={cached:Math.floor(Date.now()/Bd),provider:e.provider,data:t};return Mi(s,Ko+a.toString(),JSON.stringify(l))}t.lastModified&&!$4(e,t.lastModified)||Object.keys(t.icons).length&&(t.not_found&&(t=Object.assign({},t),delete t.not_found),n("local")||n("session"))}function yu(){}function F4(e){e.iconsLoaderFlag||(e.iconsLoaderFlag=!0,setTimeout(()=>{e.iconsLoaderFlag=!1,I4(e)}))}function U4(e,t){e.iconsToLoad?e.iconsToLoad=e.iconsToLoad.concat(t).sort():e.iconsToLoad=t,e.iconsQueueFlag||(e.iconsQueueFlag=!0,setTimeout(()=>{e.iconsQueueFlag=!1;const{provider:n,prefix:o}=e,s=e.iconsToLoad;delete e.iconsToLoad;let r;if(!s||!(r=_a(n)))return;r.prepare(n,o,s).forEach(l=>{B4(n,l,i=>{if(typeof i!="object")l.icons.forEach(u=>{e.missing.add(u)});else try{const u=Si(e,i);if(!u.length)return;const c=e.pendingIcons;c&&u.forEach(p=>{c.delete(p)}),N4(e,i)}catch(u){console.error(u)}F4(e)})})}))}const W4=(e,t)=>{const n=R4(e,!0,Ld()),o=E4(n);if(!o.pending.length){let i=!0;return t&&setTimeout(()=>{i&&t(o.loaded,o.missing,o.pending,yu)}),()=>{i=!1}}const s=Object.create(null),r=[];let a,l;return o.pending.forEach(i=>{const{provider:u,prefix:c}=i;if(c===l&&u===a)return;a=u,l=c,r.push(Hn(u,c));const p=s[u]||(s[u]=Object.create(null));p[c]||(p[c]=[])}),o.pending.forEach(i=>{const{provider:u,prefix:c,name:p}=i,f=Hn(u,c),m=f.pendingIcons||(f.pendingIcons=new Set);m.has(p)||(m.add(p),s[u][c].push(p))}),r.forEach(i=>{const{provider:u,prefix:c}=i;s[u][c].length&&U4(i,s[u][c])}),t?z4(t,o,r):yu};function q4(e,t){const n={...e};for(const o in t){const s=t[o],r=typeof s;o in zd?(s===null||s&&(r==="string"||r==="number"))&&(n[o]=s):r===typeof n[o]&&(n[o]=o==="rotate"?s%4:s)}return n}const G4=/[\s,]+/;function J4(e,t){t.split(G4).forEach(n=>{switch(n.trim()){case"horizontal":e.hFlip=!0;break;case"vertical":e.vFlip=!0;break}})}function Q4(e,t=0){const n=e.replace(/^-?[0-9.]*/,"");function o(s){for(;s<0;)s+=4;return s%4}if(n===""){const s=parseInt(e);return isNaN(s)?0:o(s)}else if(n!==e){let s=0;switch(n){case"%":s=25;break;case"deg":s=90}if(s){let r=parseFloat(e.slice(0,e.length-n.length));return isNaN(r)?0:(r=r/s,r%1===0?o(r):0)}}return t}function K4(e,t){let n=e.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(const o in t)n+=" "+o+'="'+t[o]+'"';return'"+e+""}function Y4(e){return e.replace(/"/g,"'").replace(/%/g,"%25").replace(/#/g,"%23").replace(//g,"%3E").replace(/\s+/g," ")}function Z4(e){return"data:image/svg+xml,"+Y4(e)}function X4(e){return'url("'+Z4(e)+'")'}const bu={...Rd,inline:!1},e6={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":!0,role:"img"},t6={display:"inline-block"},Ia={backgroundColor:"currentColor"},Fd={backgroundColor:"transparent"},wu={Image:"var(--svg)",Repeat:"no-repeat",Size:"100% 100%"},ku={webkitMask:Ia,mask:Ia,background:Fd};for(const e in ku){const t=ku[e];for(const n in wu)t[e+n]=wu[n]}const Hs={};["horizontal","vertical"].forEach(e=>{const t=e.slice(0,1)+"Flip";Hs[e+"-flip"]=t,Hs[e.slice(0,1)+"-flip"]=t,Hs[e+"Flip"]=t});function xu(e){return e+(e.match(/^[-0-9.]+$/)?"px":"")}const Cu=(e,t)=>{const n=q4(bu,t),o={...e6},s=t.mode||"svg",r={},a=t.style,l=typeof a=="object"&&!(a instanceof Array)?a:{};for(let w in t){const S=t[w];if(S!==void 0)switch(w){case"icon":case"style":case"onLoad":case"mode":break;case"inline":case"hFlip":case"vFlip":n[w]=S===!0||S==="true"||S===1;break;case"flip":typeof S=="string"&&J4(n,S);break;case"color":r.color=S;break;case"rotate":typeof S=="string"?n[w]=Q4(S):typeof S=="number"&&(n[w]=S);break;case"ariaHidden":case"aria-hidden":S!==!0&&S!=="true"&&delete o["aria-hidden"];break;default:{const z=Hs[w];z?(S===!0||S==="true"||S===1)&&(n[z]=!0):bu[w]===void 0&&(o[w]=S)}}}const i=g4(e,n),u=i.attributes;if(n.inline&&(r.verticalAlign="-0.125em"),s==="svg"){o.style={...r,...l},Object.assign(o,u);let w=0,S=t.id;return typeof S=="string"&&(S=S.replace(/-/g,"_")),o.innerHTML=w4(i.body,S?()=>S+"ID"+w++:"iconifyVue"),Tt("svg",o)}const{body:c,width:p,height:f}=e,m=s==="mask"||(s==="bg"?!1:c.indexOf("currentColor")!==-1),v=K4(c,{...u,width:p+"",height:f+""});return o.style={...r,"--svg":X4(v),width:xu(u.width),height:xu(u.height),...t6,...m?Ia:Fd,...l},Tt("span",o)};Ld(!0);k4("",P4);if(typeof document<"u"&&typeof window<"u"){Nd();const e=window;if(e.IconifyPreload!==void 0){const t=e.IconifyPreload,n="Invalid IconifyPreload syntax.";typeof t=="object"&&t!==null&&(t instanceof Array?t:[t]).forEach(o=>{try{(typeof o!="object"||o===null||o instanceof Array||typeof o.icons!="object"||typeof o.prefix!="string"||!p4(o))&&console.error(n)}catch{console.error(n)}})}if(e.IconifyProviders!==void 0){const t=e.IconifyProviders;if(typeof t=="object"&&t!==null)for(let n in t){const o="IconifyProviders["+n+"] is invalid.";try{const s=t[n];if(typeof s!="object"||!s||s.resources===void 0)continue;x4(n,s)||console.error(o)}catch{console.error(o)}}}}const n6={...Tr,body:""},o6=Ce({inheritAttrs:!1,data(){return{iconMounted:!1,counter:0}},mounted(){this._name="",this._loadingIcon=null,this.iconMounted=!0},unmounted(){this.abortLoading()},methods:{abortLoading(){this._loadingIcon&&(this._loadingIcon.abort(),this._loadingIcon=null)},getIcon(e,t){if(typeof e=="object"&&e!==null&&typeof e.body=="string")return this._name="",this.abortLoading(),{data:e};let n;if(typeof e!="string"||(n=Sr(e,!1,!0))===null)return this.abortLoading(),null;const o=c4(n);if(!o)return(!this._loadingIcon||this._loadingIcon.name!==e)&&(this.abortLoading(),this._name="",o!==null&&(this._loadingIcon={name:e,abort:W4([n],()=>{this.counter++})})),null;this.abortLoading(),this._name!==e&&(this._name=e,t&&t(e));const s=["iconify"];return n.prefix!==""&&s.push("iconify--"+n.prefix),n.provider!==""&&s.push("iconify--"+n.provider),{data:o,classes:s}}},render(){this.counter;const e=this.$attrs,t=this.iconMounted?this.getIcon(e.icon,e.onLoad):null;if(!t)return Cu(n6,e);let n=e;return t.classes&&(n={...e,class:(typeof e.class=="string"?e.class+" ":"")+t.classes.join(" ")}),Cu({...Tr,...t.data},n)}});/*! * Original code by Ibrahim Cesar * MIT Licensed, Copyright 2022 Ibrahim Cesar, see https://github.com/ibrahimcesar/react-lite-youtube-embed/blob/main/LICENSE for details * @@ -3709,7 +3709,7 @@ complex animations that would otherwise be time-consuming and challenging to bui */function Kr(e,t){var n;if(e===null)throw new Error("iframe element not instantiated.");(n=e.contentWindow)==null||n.postMessage(`{"event":"command","func":"${t}","args":""}`,"*")}function Ts(e){return Mo("link",{attrs:{rel:"preconnect",href:e}})}const s6=e=>e?Object.entries(e).reduce((t,[n,o])=>(n=n.charAt(0).toUpperCase()+n.slice(1),n=`on${n}`,{...t,[n]:o}),{}):null,Mo=(e,t={},n)=>{const{props:o,domProps:s,on:r,attrs:a,...l}=t,i=s6(r),u={...l,...o,...s,...i,...a};return Tt(e,u,n)},r6=Ce({props:{announce:{type:String,required:!1,default:"Watch"},id:{type:String,required:!0},title:{type:String,required:!1},activatedClass:{type:String,required:!1,default:"lyt-activated"},adNetwork:{type:Boolean,required:!1,default:!0},iframeClass:{type:String,required:!1,default:""},cookie:{type:Boolean,required:!1,default:!1},params:{type:String,required:!1,default:""},playerClass:{type:String,required:!1,default:"lty-playbtn"},playlist:{type:Boolean,required:!1,default:!1},playlistCoverId:{type:String,required:!1,default:""},poster:{type:String,required:!1,default:"maxresdefault"},wrapperClass:{type:String,required:!1,default:"yt-lite"},muted:{type:Boolean,required:!1,default:!1},thumbnail:{type:String,required:!1},webp:{type:Boolean,required:!1,default:!1},rel:{type:String,required:!1,default:"preload"},aspectHeight:{type:Number,required:!1,default:9},aspectWidth:{type:Number,required:!1,default:16}},emits:["iframeAdded"],setup(e,{emit:t,expose:n}){const o=Y(!1),s=Y(!1),r=Y(null),a=C(()=>encodeURIComponent(e.id)),l=C(()=>`&${e.params}`||""),i=C(()=>e.muted?"&mute=1":""),u=C(()=>e.webp?"webp":"jpg"),c=C(()=>e.webp?"vi_webp":"vi"),p=C(()=>typeof e.playlistCoverId=="string"?encodeURIComponent(e.playlistCoverId):null),f=C(()=>e.thumbnail||(e.playlist?`https://i.ytimg.com/${c.value}/${p.value}/${e.poster}.${u.value}`:`https://i.ytimg.com/${c.value}/${a.value}/${e.poster}.${u.value}`)),m=C(()=>e.cookie?"https://www.youtube.com":"https://www.youtube-nocookie.com"),v=C(()=>e.playlist?`${m.value}/embed/videoseries?autoplay=1&enablejsapi=1&list=${a.value}${i.value}${l.value}`:`${m.value}/embed/${a.value}?autoplay=1&enablejsapi=1&state=1${i.value}${l.value}`);function w(){s.value||(s.value=!0,t("iframeAdded"))}function S(){o.value||(o.value=!0)}n({getPlayerInstance(){return r.value},stopVideo(){Kr(r.value,"stopVideo")},pauseVideo(){Kr(r.value,"pauseVideo")},playVideo(){Kr(r.value,"playVideo")},warmConnections:S,addIframe:w});const z=()=>[Mo("link",{attrs:{rel:e.rel,href:f.value,as:"image"}}),o.value?Ts(m.value):null,o.value?Ts("https://www.google.com"):null,e.adNetwork?Ts("https://static.doubleclick.net"):null,e.adNetwork?Ts("https://googleads.g.doubleclick.net"):null,Mo("article",{on:{pointerover:S,click:w},class:`${e.wrapperClass} ${s.value?e.activatedClass:""}`,attrs:{"data-title":e.title},style:{backgroundImage:`url(${f.value})`,"--aspect-ratio":`${e.aspectHeight/e.aspectWidth*100}%`}},[Mo("button",{class:e.playerClass,attrs:{type:"button","aria-label":`${e.announce} ${e.title}`}}),s.value?Mo("iframe",{ref:r,class:e.iframeClass,attrs:{title:e.title,width:560,height:315,frameborder:0,allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0,src:v.value}}):null])];return()=>z()}}),a6={key:1},i6=Ce({__name:"Include",props:{src:{}},setup(e){const t=e,s=(qe("press").components.includes||{})[t.src],r=s?tf(s):null;return(a,l)=>me(r)?(h(),we(qa(me(r)),{key:0,name:a.src,frontmatter:{nowrap:!0}},null,8,["name"])):(h(),y("div",a6,"Include not found: "+te(a.src),1))}}),l6=mh(lm),u6=sm(),Ud=t4({history:m3(),scrollBehavior(e,t,n){if(n)return n;if(e.hash)return{el:e.hash,behavior:"smooth"};setTimeout(()=>{window.scrollTo(0,0)},1)},extendRoutes(e){return e.forEach(t=>{t.path.startsWith("/admin")&&(t.children??[]).forEach(n=>{n.meta??(n.meta={}),n.meta.layout="admin"})}),n4(e)}});Ud.beforeEach((e,t,n)=>{e.path.startsWith("/http")?location.href=e.path.substring(1):n()});l6.use(u6).use(Ud).use(Y5).provide("press",o4).component("LiteYouTube",r6).component("Iconify",o6).component("Include",i6).mount("#app");export{m6 as A,On as B,It as C,qa as D,tf as E,Re as F,ts as G,Ro as H,d6 as I,pa as J,p6 as K,i6 as _,d as a,Ae as b,y as c,Ce as d,Be as e,fr as f,Qe as g,we as h,am as i,Y as j,C as k,jn as l,F as m,L as n,h as o,f6 as p,Ct as q,ye as r,Tt as s,te as t,me as u,ua as v,He as w,qe as x,he as y,h6 as z}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { - __vite__mapDeps.viteFileDeps = ["assets/index-BG5anPub.js","assets/SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js","assets/VideoGroup.vue_vue_type_script_setup_true_lang-yt9KRqcL.js","assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js","assets/GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js","assets/utils-D7bH4Tlo.js","assets/about-C5lL5M9L.js","assets/MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js","assets/blog-DsWHVwkJ.js","assets/_plugin-vue_export-helper-DlAUqK2U.js","assets/logo-DspwJfOt.js","assets/counter-BqsUn9iq.js","assets/index-DB65REeY.js","assets/BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js","assets/_slug_-D0R-lY2g.js","assets/_name_-D0WdA550.js","assets/_tag_-A7_HVUVC.js","assets/_year_-bjfw_pb5.js","assets/privacy-CgZlqKfp.js","assets/videos-B48T2Bqr.js","assets/whatsnew-DLwuVrUY.js","assets/whatsnew-edl9V2YA.css","assets/default-Bpx-Aajc.js","assets/empty-BlQdiYK7.js","assets/2024-03-01_vite-press-plugin-BV6PDf7d.js","assets/2024-02-28_markdown-components-in-vue-BMrj5Q1x.js","assets/HelloApi.vue_vue_type_script_setup_true_lang-BNRlbX2m.js","assets/Counter.vue_vue_type_script_setup_true_lang-DCgW5edk.js","assets/ChartJs-I6khMjFE.js","assets/2023-11-22_net8-best-blazor-wjwjFuPp.js","assets/Templates.vue_vue_type_script_setup_true_lang-DajVBfQg.js","assets/2023-11-20_net8-blazor-template-BS9qPuaN.js","assets/2023-08-23_razor-ssg-new-blog-features-DA5S93ND.js","assets/2023-03-30_razor-ssg-Ci0fv4r7.js","assets/2023-02-01_javascript-BozINeQT.js","assets/2023-01-21_start-BLjTU3tE.js","assets/2023-01-11_rider-BIj5SqpT.js","assets/2023-01-10_vs-CnHF8_tj.js","assets/2023-01-01_deploy-DS48nsUk.js","assets/2022-12-31_typography-CQ2u4p7c.js","assets/2022-09-06_hetzner-cloud-CMGV4KKw.js","assets/2022-09-06_hetzner-cloud-DQ1ZL1Ux.css","assets/autoquerygrid-B8jP3C5m.js","assets/components-D8n2u9I9.js","assets/admin-ddEAmk2a.js","assets/modern-CCyvQdVa.js","assets/feature1-BJlXHRzt.js","assets/feature1-B0cK-EMF.js","assets/feature1-B9tl-y8M.js","assets/component-links-B0AHB4nY.js","assets/features-DgyWH2Q5.js"] + __vite__mapDeps.viteFileDeps = ["assets/index-Da1NoZ0N.js","assets/SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js","assets/VideoGroup.vue_vue_type_script_setup_true_lang-Cko02hll.js","assets/MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js","assets/GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js","assets/utils-BDrlE94o.js","assets/about-CSevwr_F.js","assets/MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js","assets/blog-NLNSyVmF.js","assets/_plugin-vue_export-helper-DlAUqK2U.js","assets/logo-BG60RFri.js","assets/counter-DSxYdCIG.js","assets/index-Db6kjhtf.js","assets/BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js","assets/_slug_-BaiPQcvV.js","assets/_name_-D5H8wJy-.js","assets/_tag_-Bl8Dgnay.js","assets/_year_-C2Zxurez.js","assets/privacy-BP3kbvHT.js","assets/videos-DZLBdRXH.js","assets/whatsnew-CZ_1B3HR.js","assets/whatsnew-edl9V2YA.css","assets/default-Caiy_OVN.js","assets/empty-u1n3FCjQ.js","assets/2024-03-01_vite-press-plugin-DJwsPj6t.js","assets/2024-02-28_markdown-components-in-vue-OgPNuM_j.js","assets/HelloApi.vue_vue_type_script_setup_true_lang-DrkDEcx3.js","assets/Counter.vue_vue_type_script_setup_true_lang-CEPiro_Z.js","assets/ChartJs-ljXEK9mH.js","assets/2023-11-22_net8-best-blazor-B8AK7TtK.js","assets/Templates.vue_vue_type_script_setup_true_lang-8Ivl7FzK.js","assets/2023-11-20_net8-blazor-template-csCQIEk-.js","assets/2023-08-23_razor-ssg-new-blog-features-DJ1Rr8VN.js","assets/2023-03-30_razor-ssg-h6EyxEND.js","assets/2023-02-01_javascript-DsU9PqrK.js","assets/2023-01-21_start-Dvy20kPM.js","assets/2023-01-11_rider-C1RjBW7K.js","assets/2023-01-10_vs-Dpo3fFRu.js","assets/2023-01-01_deploy-Bh3tgLQ9.js","assets/2022-12-31_typography-C35AONwX.js","assets/2022-09-06_hetzner-cloud-B9u-MxgU.js","assets/2022-09-06_hetzner-cloud-DQ1ZL1Ux.css","assets/autoquerygrid-CYIg7oz6.js","assets/components-Q0dmsTg-.js","assets/admin-DfK6L5xt.js","assets/modern-DHYi0nI9.js","assets/feature1-CYSjmA7I.js","assets/feature1-CvHTx5Sl.js","assets/feature1-FhqPQYoT.js","assets/component-links-B6Jg27wb.js","assets/features-nHCxd1P1.js"] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) } diff --git a/assets/index-BG5anPub.js b/assets/index-Da1NoZ0N.js similarity index 90% rename from assets/index-BG5anPub.js rename to assets/index-Da1NoZ0N.js index 3d115cb..e1f6c30 100644 --- a/assets/index-BG5anPub.js +++ b/assets/index-Da1NoZ0N.js @@ -1 +1 @@ -import{_ as w}from"./SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js";import{_ as V}from"./VideoGroup.vue_vue_type_script_setup_true_lang-yt9KRqcL.js";import{d as C,x as L,r as g,o as r,c as d,a as t,b as a,u as e,w as m,e as S,t as l,h as $,m as j,F as A,f as N,_ as P}from"./index-B-kKBcPB.js";import{_ as B}from"./GettingStarted.vue_vue_type_script_setup_true_lang-iIZL_Jie.js";import{d as G,a as I,g as F}from"./utils-D7bH4Tlo.js";import"./MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js";const U=N('

    Welcome to Press Vue

    Welcome to your new Vue SPA App

    ',1),R={class:"py-8 flex"},T={class:"mt-8 mx-auto"},W=t("h2",{class:"mt-2 text-3xl font-extrabold tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl text-center"}," Getting Started ",-1),D={class:"container mx-auto px-5 mt-24 mb-24"},E={key:0},M={class:"mb-8 md:mb-16"},O={class:"sm:mx-0"},X=["src","alt"],q={class:"md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28"},z={class:"mb-4 text-4xl lg:text-6xl leading-tight"},H={class:"mb-4 md:mb-0 text-lg"},J=["datetime"],K={class:"text-lg leading-relaxed mb-4"},Q=["src"],Y={key:1,class:"flex items-center text-xl font-bold"},Z=["src"],tt={class:"flex justify-center my-20 py-20 bg-slate-100 dark:bg-slate-800"},et={class:"text-center"},st=t("h1",{class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"}," Features ",-1),ot=t("div",{class:"text-center text-xl"}," Opinionated Vue template for a productive out-of-the-box development UX ",-1),at={class:"prose dark:prose-invert lg:prose-xl mx-auto"},nt={class:"flex justify-center my-20 py-20 bg-slate-100 dark:bg-slate-800"},lt={class:"text-center"},rt=t("h1",{class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"}," Videos ",-1),it={class:"my-8 flex justify-center gap-x-4"},gt=C({__name:"index",setup(ct){const i=L("press");function x(o){return o&&i.blog.authors.some(n=>n.name.toLowerCase()==o.toLowerCase())?`/posts/author/${F(o)}`:null}function u(o){return`/posts/${o.slug}`}function f(o){return o?i.blog.authors.filter(n=>n.name.toLowerCase()==o.toLowerCase())[0]:null}function _(o){var n;return((n=f(o))==null?void 0:n.profileUrl)??"/img/profiles/user1.svg"}const s=i.blog.posts[0],h=s.author;return(o,n)=>{const b=B,c=g("RouterLink"),p=g("Iconify"),v=P,y=V,k=w;return r(),d(A,null,[U,t("section",R,[t("div",T,[W,t("div",null,[a(b,{template:"press-vue"})])])]),t("div",D,[e(s)?(r(),d("section",E,[t("div",M,[t("div",O,[a(c,{"aria-label":e(s).title,to:u(e(s))},{default:m(()=>[t("img",{src:e(s).image,alt:`Cover Image for ${e(s).title}`,class:"shadow-sm hover:shadow-2xl transition-shadow duration-200"},null,8,X)]),_:1},8,["aria-label","to"])])]),t("div",q,[t("div",null,[t("h3",z,[a(c,{class:"hover:underline",to:u(e(s))},{default:m(()=>[S(l(e(s).title),1)]),_:1},8,["to"])]),t("div",H,[t("time",{datetime:e(G)(e(s).date)},l(e(I)(e(s).date)),9,J)])]),t("div",null,[t("p",K,l(e(s).summary),1),x(e(s).author)?(r(),$(c,{key:0,class:"flex items-center text-xl font-bold",to:x(e(s).author)},{default:m(()=>[t("img",{src:_(e(s).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,Q),t("span",null,l(e(h)),1)]),_:1},8,["to"])):(r(),d("span",Y,[t("img",{src:_(e(s).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,Z),t("span",null,l(e(h)),1)]))])])])):j("",!0)]),t("div",tt,[t("div",et,[a(p,{icon:"mdi:feature-highlight",class:"text-green-600 w-36 h-36 inline-block"}),st])]),ot,t("div",at,[a(v,{src:"features.md"})]),t("div",nt,[t("div",lt,[a(p,{icon:"material-symbols:hangout-video",class:"text-green-600 w-36 h-36 inline-block"}),rt])]),a(y,{title:"Vue Components",summary:"Learn about productive features in our growing Vue Component Library",group:"vue",learnMore:"https://docs.servicestack.net/vue/"}),t("div",it,[a(k,{path:"index.vue"})])],64)}}});export{gt as default}; +import{_ as w}from"./SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js";import{_ as V}from"./VideoGroup.vue_vue_type_script_setup_true_lang-Cko02hll.js";import{d as C,x as L,r as g,o as r,c as d,a as t,b as a,u as e,w as m,e as S,t as l,h as $,m as j,F as A,f as N,_ as P}from"./index-CoFPLbfm.js";import{_ as B}from"./GettingStarted.vue_vue_type_script_setup_true_lang-BcGdWgS3.js";import{d as G,a as I,g as F}from"./utils-BDrlE94o.js";import"./MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js";const U=N('

    Welcome to Press Vue

    Welcome to your new Vue SPA App

    ',1),R={class:"py-8 flex"},T={class:"mt-8 mx-auto"},W=t("h2",{class:"mt-2 text-3xl font-extrabold tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl text-center"}," Getting Started ",-1),D={class:"container mx-auto px-5 mt-24 mb-24"},E={key:0},M={class:"mb-8 md:mb-16"},O={class:"sm:mx-0"},X=["src","alt"],q={class:"md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28"},z={class:"mb-4 text-4xl lg:text-6xl leading-tight"},H={class:"mb-4 md:mb-0 text-lg"},J=["datetime"],K={class:"text-lg leading-relaxed mb-4"},Q=["src"],Y={key:1,class:"flex items-center text-xl font-bold"},Z=["src"],tt={class:"flex justify-center my-20 py-20 bg-slate-100 dark:bg-slate-800"},et={class:"text-center"},st=t("h1",{class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"}," Features ",-1),ot=t("div",{class:"text-center text-xl"}," Opinionated Vue template for a productive out-of-the-box development UX ",-1),at={class:"prose dark:prose-invert lg:prose-xl mx-auto"},nt={class:"flex justify-center my-20 py-20 bg-slate-100 dark:bg-slate-800"},lt={class:"text-center"},rt=t("h1",{class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"}," Videos ",-1),it={class:"my-8 flex justify-center gap-x-4"},gt=C({__name:"index",setup(ct){const i=L("press");function x(o){return o&&i.blog.authors.some(n=>n.name.toLowerCase()==o.toLowerCase())?`/posts/author/${F(o)}`:null}function u(o){return`/posts/${o.slug}`}function f(o){return o?i.blog.authors.filter(n=>n.name.toLowerCase()==o.toLowerCase())[0]:null}function _(o){var n;return((n=f(o))==null?void 0:n.profileUrl)??"/img/profiles/user1.svg"}const s=i.blog.posts[0],h=s.author;return(o,n)=>{const b=B,c=g("RouterLink"),p=g("Iconify"),v=P,y=V,k=w;return r(),d(A,null,[U,t("section",R,[t("div",T,[W,t("div",null,[a(b,{template:"press-vue"})])])]),t("div",D,[e(s)?(r(),d("section",E,[t("div",M,[t("div",O,[a(c,{"aria-label":e(s).title,to:u(e(s))},{default:m(()=>[t("img",{src:e(s).image,alt:`Cover Image for ${e(s).title}`,class:"shadow-sm hover:shadow-2xl transition-shadow duration-200"},null,8,X)]),_:1},8,["aria-label","to"])])]),t("div",q,[t("div",null,[t("h3",z,[a(c,{class:"hover:underline",to:u(e(s))},{default:m(()=>[S(l(e(s).title),1)]),_:1},8,["to"])]),t("div",H,[t("time",{datetime:e(G)(e(s).date)},l(e(I)(e(s).date)),9,J)])]),t("div",null,[t("p",K,l(e(s).summary),1),x(e(s).author)?(r(),$(c,{key:0,class:"flex items-center text-xl font-bold",to:x(e(s).author)},{default:m(()=>[t("img",{src:_(e(s).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,Q),t("span",null,l(e(h)),1)]),_:1},8,["to"])):(r(),d("span",Y,[t("img",{src:_(e(s).author),class:"w-12 h-12 rounded-full mr-4",alt:"Author"},null,8,Z),t("span",null,l(e(h)),1)]))])])])):j("",!0)]),t("div",tt,[t("div",et,[a(p,{icon:"mdi:feature-highlight",class:"text-green-600 w-36 h-36 inline-block"}),st])]),ot,t("div",at,[a(v,{src:"features.md"})]),t("div",nt,[t("div",lt,[a(p,{icon:"material-symbols:hangout-video",class:"text-green-600 w-36 h-36 inline-block"}),rt])]),a(y,{title:"Vue Components",summary:"Learn about productive features in our growing Vue Component Library",group:"vue",learnMore:"https://docs.servicestack.net/vue/"}),t("div",it,[a(k,{path:"index.vue"})])],64)}}});export{gt as default}; diff --git a/assets/index-DB65REeY.js b/assets/index-Db6kjhtf.js similarity index 88% rename from assets/index-DB65REeY.js rename to assets/index-Db6kjhtf.js index 724cadb..880e5c4 100644 --- a/assets/index-DB65REeY.js +++ b/assets/index-Db6kjhtf.js @@ -1 +1 @@ -import{_ as F}from"./SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js";import{_ as L,a as S}from"./BlogTitle.vue_vue_type_script_setup_true_lang-Dtinjf4F.js";import{g as Y}from"./utils-D7bH4Tlo.js";import{d as $,x as j,r as C,o as i,c as m,a as e,b as o,u as a,F as g,g as h,w as p,e as u,t as x,h as N}from"./index-B-kKBcPB.js";const P={class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},T=e("div",{class:"absolute inset-0"},[e("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),V={class:"relative mx-auto max-w-7xl"},E={class:"relative my-4 mx-auto max-w-7xl"},R={class:"flex flex-wrap justify-center"},M={class:"relative mb-8 mx-auto max-w-7xl"},q={class:"flex flex-wrap justify-center"},z={class:"text-sm font-semibold"},A={class:"relative mx-auto max-w-7xl"},G={class:"mt-8 text-center"},H={class:"my-8 flex justify-center gap-x-4"},U=$({__name:"index",setup(I){const f=j("press"),b=f.blog.config.blogDescription,n=f.blog.posts,v=[...new Set(n.map(t=>new Date(t.date).getFullYear()))],r=[...new Set(n.flatMap(t=>t.tags))],c={};r.forEach(t=>c[t]=n.filter(l=>l.tags.includes(t)).length),r.sort((t,l)=>c[l]-c[t]);function w(t){return`/posts/tagged/${Y(t)}`}function k(t){return`/posts/year/${t}`}const d=new Date().getFullYear();return(t,l)=>{const y=L,_=C("RouterLink"),B=S,D=F;return i(),m(g,null,[e("div",P,[T,e("div",V,[o(y,{heading:a(b)},null,8,["heading"])]),e("div",E,[e("div",R,[(i(),m(g,null,h(r,s=>o(_,{to:w(s),class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-slate-400/10 dark:bg-slate-400/30 rounded-full py-1 px-3 flex items-center space-x-2 hover:bg-slate-400/20 dark:hover:bg-slate-400/40 dark:highlight-white/5"},{default:p(()=>[u(x(s),1)]),_:2},1032,["to"])),64))])]),e("div",M,[e("div",q,[e("b",z,x(a(d)),1),(i(!0),m(g,null,h(v.filter(s=>s!=a(d)),s=>(i(),N(_,{class:"ml-3 text-sm text-indigo-700 dark:text-indigo-300 font-semibold hover:underline",to:k(s)},{default:p(()=>[u(x(s),1)]),_:2},1032,["to"]))),256))])]),e("div",A,[o(B,{posts:a(n).filter(s=>new Date(s.date).getFullYear()==a(d))},null,8,["posts"]),e("div",G,[o(_,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:p(()=>[u("view all posts")]),_:1})])])]),e("div",H,[o(D,{path:"posts/index.vue"})])],64)}}});export{U as default}; +import{_ as F}from"./SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js";import{_ as L,a as S}from"./BlogTitle.vue_vue_type_script_setup_true_lang-DMQXQGLg.js";import{g as Y}from"./utils-BDrlE94o.js";import{d as $,x as j,r as C,o as i,c as m,a as e,b as o,u as a,F as g,g as h,w as p,e as u,t as x,h as N}from"./index-CoFPLbfm.js";const P={class:"relative bg-gray-50 dark:bg-gray-900 px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},T=e("div",{class:"absolute inset-0"},[e("div",{class:"h-1/3 bg-white dark:bg-black sm:h-2/3"})],-1),V={class:"relative mx-auto max-w-7xl"},E={class:"relative my-4 mx-auto max-w-7xl"},R={class:"flex flex-wrap justify-center"},M={class:"relative mb-8 mx-auto max-w-7xl"},q={class:"flex flex-wrap justify-center"},z={class:"text-sm font-semibold"},A={class:"relative mx-auto max-w-7xl"},G={class:"mt-8 text-center"},H={class:"my-8 flex justify-center gap-x-4"},U=$({__name:"index",setup(I){const f=j("press"),b=f.blog.config.blogDescription,n=f.blog.posts,v=[...new Set(n.map(t=>new Date(t.date).getFullYear()))],r=[...new Set(n.flatMap(t=>t.tags))],c={};r.forEach(t=>c[t]=n.filter(l=>l.tags.includes(t)).length),r.sort((t,l)=>c[l]-c[t]);function w(t){return`/posts/tagged/${Y(t)}`}function k(t){return`/posts/year/${t}`}const d=new Date().getFullYear();return(t,l)=>{const y=L,_=C("RouterLink"),B=S,D=F;return i(),m(g,null,[e("div",P,[T,e("div",V,[o(y,{heading:a(b)},null,8,["heading"])]),e("div",E,[e("div",R,[(i(),m(g,null,h(r,s=>o(_,{to:w(s),class:"mr-2 mb-2 text-xs leading-5 font-semibold bg-slate-400/10 dark:bg-slate-400/30 rounded-full py-1 px-3 flex items-center space-x-2 hover:bg-slate-400/20 dark:hover:bg-slate-400/40 dark:highlight-white/5"},{default:p(()=>[u(x(s),1)]),_:2},1032,["to"])),64))])]),e("div",M,[e("div",q,[e("b",z,x(a(d)),1),(i(!0),m(g,null,h(v.filter(s=>s!=a(d)),s=>(i(),N(_,{class:"ml-3 text-sm text-indigo-700 dark:text-indigo-300 font-semibold hover:underline",to:k(s)},{default:p(()=>[u(x(s),1)]),_:2},1032,["to"]))),256))])]),e("div",A,[o(B,{posts:a(n).filter(s=>new Date(s.date).getFullYear()==a(d))},null,8,["posts"]),e("div",G,[o(_,{class:"text-sm font-semibold hover:underline",to:"/posts"},{default:p(()=>[u("view all posts")]),_:1})])])]),e("div",H,[o(D,{path:"posts/index.vue"})])],64)}}});export{U as default}; diff --git a/assets/logo-DspwJfOt.js b/assets/logo-BG60RFri.js similarity index 85% rename from assets/logo-DspwJfOt.js rename to assets/logo-BG60RFri.js index 4d11f71..8d58499 100644 --- a/assets/logo-DspwJfOt.js +++ b/assets/logo-BG60RFri.js @@ -1 +1 @@ -import{o,c as t,a as e}from"./index-B-kKBcPB.js";const s={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 261.76 226.69"},n=e("path",{fill:"#41b883",d:"m161.096.001-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z"},null,-1),c=e("path",{fill:"#34495e",d:"m161.096.001-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z"},null,-1),l=[n,c];function r(a,_){return o(),t("svg",s,[...l])}const i={render:r};export{i as L}; +import{o,c as t,a as e}from"./index-CoFPLbfm.js";const s={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 261.76 226.69"},n=e("path",{fill:"#41b883",d:"m161.096.001-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z"},null,-1),c=e("path",{fill:"#34495e",d:"m161.096.001-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z"},null,-1),l=[n,c];function r(a,_){return o(),t("svg",s,[...l])}const i={render:r};export{i as L}; diff --git a/assets/modern-CCyvQdVa.js b/assets/modern-DHYi0nI9.js similarity index 91% rename from assets/modern-CCyvQdVa.js rename to assets/modern-DHYi0nI9.js index 0bf6fce..96e0dce 100644 --- a/assets/modern-CCyvQdVa.js +++ b/assets/modern-DHYi0nI9.js @@ -1 +1 @@ -import{_ as n}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o as s,h as i,w as l,a as e}from"./index-B-kKBcPB.js";const d=e("div",{class:"markdown-body"},[e("p",null,"ServiceStack templates provide a wide range of options when it comes to using Razor Pages in your .NET application"),e("p",null,"These templates come with Tailwind, JS Modules, and Vue components already built-in, making it easy to build hybrid apps containing both Server-Side Rendering (SSR) and static resources")],-1),w="Modern Razor Pages & MVC .NET Tailwind templates",M="https://youtu.be/SyppvQB7IPs",_=["vue","razor"],h="08-02-2023",P=4,y=[{property:"og:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"},{name:"twitter:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"}],z={__name:"modern",setup(p,{expose:a}){const t={title:"Modern Razor Pages & MVC .NET Tailwind templates",url:"https://youtu.be/SyppvQB7IPs",tags:["vue","razor"],date:"08-02-2023",order:4,meta:[{property:"og:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"},{name:"twitter:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"}]};return a({frontmatter:t}),r({title:"Modern Razor Pages & MVC .NET Tailwind templates",meta:[{property:"og:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"},{name:"twitter:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"}]}),(m,u)=>{const o=n;return s(),i(o,{frontmatter:t},{default:l(()=>[d]),_:1})}}};export{h as date,z as default,y as meta,P as order,_ as tags,w as title,M as url}; +import{_ as n}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o as s,h as i,w as l,a as e}from"./index-CoFPLbfm.js";const d=e("div",{class:"markdown-body"},[e("p",null,"ServiceStack templates provide a wide range of options when it comes to using Razor Pages in your .NET application"),e("p",null,"These templates come with Tailwind, JS Modules, and Vue components already built-in, making it easy to build hybrid apps containing both Server-Side Rendering (SSR) and static resources")],-1),w="Modern Razor Pages & MVC .NET Tailwind templates",M="https://youtu.be/SyppvQB7IPs",_=["vue","razor"],h="08-02-2023",P=4,y=[{property:"og:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"},{name:"twitter:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"}],z={__name:"modern",setup(p,{expose:a}){const t={title:"Modern Razor Pages & MVC .NET Tailwind templates",url:"https://youtu.be/SyppvQB7IPs",tags:["vue","razor"],date:"08-02-2023",order:4,meta:[{property:"og:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"},{name:"twitter:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"}]};return a({frontmatter:t}),r({title:"Modern Razor Pages & MVC .NET Tailwind templates",meta:[{property:"og:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"},{name:"twitter:title",content:"Modern Razor Pages & MVC .NET Tailwind templates"}]}),(m,u)=>{const o=n;return s(),i(o,{frontmatter:t},{default:l(()=>[d]),_:1})}}};export{h as date,z as default,y as meta,P as order,_ as tags,w as title,M as url}; diff --git a/assets/privacy-CgZlqKfp.js b/assets/privacy-BP3kbvHT.js similarity index 97% rename from assets/privacy-CgZlqKfp.js rename to assets/privacy-BP3kbvHT.js index 7dc23d2..d00200e 100644 --- a/assets/privacy-CgZlqKfp.js +++ b/assets/privacy-BP3kbvHT.js @@ -1 +1 @@ -import{_ as t}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-DHnIaXUE.js";import{i as r,o as s,h as l,w as u,a as e,e as i}from"./index-B-kKBcPB.js";const c=e("div",{class:"markdown-body"},[e("p",null,"[Your business name] is committed to providing quality services to you and this policy outlines our ongoing obligations to you in respect of how we manage your Personal Information."),e("p",null,"We have adopted the Australian Privacy Principles (APPs) contained in the Privacy Act 1988 (Cth) (the Privacy Act). The NPPs govern the way in which we collect, use, disclose, store, secure and dispose of your Personal Information."),e("p",null,[i("A copy of the Australian Privacy Principles may be obtained from the website of The Office of the Australian Information Commissioner at "),e("a",{href:"https://www.oaic.gov.au/"},"https://www.oaic.gov.au/"),i(".")]),e("p",null,"What is Personal Information and why do we collect it? Personal Information is information or an opinion that identifies an individual. Examples of Personal Information we collect includes names, addresses, email addresses, phone and facsimile numbers."),e("p",null,"This Personal Information is obtained in many ways including [interviews, correspondence, by telephone and facsimile, by email, via our website www.yourbusinessname.com.au, from your website, from media and publications, from other publicly available sources, from cookies- delete all that aren’t applicable] and from third parties. We don’t guarantee website links or policy of authorised third parties."),e("p",null,"We collect your Personal Information for the primary purpose of providing our services to you, providing information to our clients and marketing. We may also use your Personal Information for secondary purposes closely related to the primary purpose, in circumstances where you would reasonably expect such use or disclosure. You may unsubscribe from our mailing/marketing lists at any time by contacting us in writing."),e("p",null,"When we collect Personal Information we will, where appropriate and where possible, explain to you why we are collecting the information and how we plan to use it."),e("p",null,"Sensitive Information Sensitive information is defined in the Privacy Act to include information or opinion about such things as an individual’s racial or ethnic origin, political opinions, membership of a political association, religious or philosophical beliefs, membership of a trade union or other professional body, criminal record or health information."),e("p",null,"Sensitive information will be used by us only:"),e("ul",null,[e("li",null,[e("p",null,"For the primary purpose for which it was obtained")]),e("li",null,[e("p",null,"For a secondary purpose that is directly related to the primary purpose")]),e("li",null,[e("p",null,"With your consent; or where required or authorised by law.")])]),e("p",null,"Third Parties Where reasonable and practicable to do so, we will collect your Personal Information only from you. However, in some circumstances we may be provided with information by third parties. In such a case we will take reasonable steps to ensure that you are made aware of the information provided to us by the third party."),e("p",null,"Disclosure of Personal Information Your Personal Information may be disclosed in a number of circumstances including the following:"),e("ul",null,[e("li",null,[e("p",null,"Third parties where you consent to the use or disclosure; and")]),e("li",null,[e("p",null,"Where required or authorised by law.")])]),e("p",null,"Security of Personal Information Your Personal Information is stored in a manner that reasonably protects it from misuse and loss and from unauthorized access, modification or disclosure."),e("p",null,"When your Personal Information is no longer needed for the purpose for which it was obtained, we will take reasonable steps to destroy or permanently de-identify your Personal Information. However, most of the Personal Information is or will be stored in client files which will be kept by us for a minimum of 7 years."),e("p",null,"Access to your Personal Information You may access the Personal Information we hold about you and to update and/or correct it, subject to certain exceptions. If you wish to access your Personal Information, please contact us in writing."),e("p",null,"[Your business name] will not charge any fee for your access request, but may charge an administrative fee for providing a copy of your Personal Information."),e("p",null,"In order to protect your Personal Information we may require identification from you before releasing the requested information."),e("p",null,"Maintaining the Quality of your Personal Information It is an important to us that your Personal Information is up to date. We will take reasonable steps to make sure that your Personal Information is accurate, complete and up-to-date. If you find that the information we have is not up to date or is inaccurate, please advise us as soon as practicable so we can update our records and ensure we can continue to provide quality services to you."),e("p",null,"Policy Updates This Policy may change from time to time and is available on our website."),e("p",null,"Privacy Policy Complaints and Enquiries If you have any queries or complaints about our Privacy Policy please contact us at:"),e("p",null,"[Your business address]"),e("p",null,"[Your business email address]"),e("p",null,"[Your business phone number]")],-1),w="Privacy Policy",P=[{property:"og:title",content:"Privacy Policy"},{name:"twitter:title",content:"Privacy Policy"}],b={__name:"privacy",setup(p,{expose:n}){const o={title:"Privacy Policy",meta:[{property:"og:title",content:"Privacy Policy"},{name:"twitter:title",content:"Privacy Policy"}]};return n({frontmatter:o}),r({title:"Privacy Policy",meta:[{property:"og:title",content:"Privacy Policy"},{name:"twitter:title",content:"Privacy Policy"}]}),(d,y)=>{const a=t;return s(),l(a,{frontmatter:o},{default:u(()=>[c]),_:1})}}};export{b as default,P as meta,w as title}; +import{_ as t}from"./MarkdownPage.vue_vue_type_script_setup_true_lang-BiYTyr_j.js";import{i as r,o as s,h as l,w as u,a as e,e as i}from"./index-CoFPLbfm.js";const c=e("div",{class:"markdown-body"},[e("p",null,"[Your business name] is committed to providing quality services to you and this policy outlines our ongoing obligations to you in respect of how we manage your Personal Information."),e("p",null,"We have adopted the Australian Privacy Principles (APPs) contained in the Privacy Act 1988 (Cth) (the Privacy Act). The NPPs govern the way in which we collect, use, disclose, store, secure and dispose of your Personal Information."),e("p",null,[i("A copy of the Australian Privacy Principles may be obtained from the website of The Office of the Australian Information Commissioner at "),e("a",{href:"https://www.oaic.gov.au/"},"https://www.oaic.gov.au/"),i(".")]),e("p",null,"What is Personal Information and why do we collect it? Personal Information is information or an opinion that identifies an individual. Examples of Personal Information we collect includes names, addresses, email addresses, phone and facsimile numbers."),e("p",null,"This Personal Information is obtained in many ways including [interviews, correspondence, by telephone and facsimile, by email, via our website www.yourbusinessname.com.au, from your website, from media and publications, from other publicly available sources, from cookies- delete all that aren’t applicable] and from third parties. We don’t guarantee website links or policy of authorised third parties."),e("p",null,"We collect your Personal Information for the primary purpose of providing our services to you, providing information to our clients and marketing. We may also use your Personal Information for secondary purposes closely related to the primary purpose, in circumstances where you would reasonably expect such use or disclosure. You may unsubscribe from our mailing/marketing lists at any time by contacting us in writing."),e("p",null,"When we collect Personal Information we will, where appropriate and where possible, explain to you why we are collecting the information and how we plan to use it."),e("p",null,"Sensitive Information Sensitive information is defined in the Privacy Act to include information or opinion about such things as an individual’s racial or ethnic origin, political opinions, membership of a political association, religious or philosophical beliefs, membership of a trade union or other professional body, criminal record or health information."),e("p",null,"Sensitive information will be used by us only:"),e("ul",null,[e("li",null,[e("p",null,"For the primary purpose for which it was obtained")]),e("li",null,[e("p",null,"For a secondary purpose that is directly related to the primary purpose")]),e("li",null,[e("p",null,"With your consent; or where required or authorised by law.")])]),e("p",null,"Third Parties Where reasonable and practicable to do so, we will collect your Personal Information only from you. However, in some circumstances we may be provided with information by third parties. In such a case we will take reasonable steps to ensure that you are made aware of the information provided to us by the third party."),e("p",null,"Disclosure of Personal Information Your Personal Information may be disclosed in a number of circumstances including the following:"),e("ul",null,[e("li",null,[e("p",null,"Third parties where you consent to the use or disclosure; and")]),e("li",null,[e("p",null,"Where required or authorised by law.")])]),e("p",null,"Security of Personal Information Your Personal Information is stored in a manner that reasonably protects it from misuse and loss and from unauthorized access, modification or disclosure."),e("p",null,"When your Personal Information is no longer needed for the purpose for which it was obtained, we will take reasonable steps to destroy or permanently de-identify your Personal Information. However, most of the Personal Information is or will be stored in client files which will be kept by us for a minimum of 7 years."),e("p",null,"Access to your Personal Information You may access the Personal Information we hold about you and to update and/or correct it, subject to certain exceptions. If you wish to access your Personal Information, please contact us in writing."),e("p",null,"[Your business name] will not charge any fee for your access request, but may charge an administrative fee for providing a copy of your Personal Information."),e("p",null,"In order to protect your Personal Information we may require identification from you before releasing the requested information."),e("p",null,"Maintaining the Quality of your Personal Information It is an important to us that your Personal Information is up to date. We will take reasonable steps to make sure that your Personal Information is accurate, complete and up-to-date. If you find that the information we have is not up to date or is inaccurate, please advise us as soon as practicable so we can update our records and ensure we can continue to provide quality services to you."),e("p",null,"Policy Updates This Policy may change from time to time and is available on our website."),e("p",null,"Privacy Policy Complaints and Enquiries If you have any queries or complaints about our Privacy Policy please contact us at:"),e("p",null,"[Your business address]"),e("p",null,"[Your business email address]"),e("p",null,"[Your business phone number]")],-1),w="Privacy Policy",P=[{property:"og:title",content:"Privacy Policy"},{name:"twitter:title",content:"Privacy Policy"}],b={__name:"privacy",setup(p,{expose:n}){const o={title:"Privacy Policy",meta:[{property:"og:title",content:"Privacy Policy"},{name:"twitter:title",content:"Privacy Policy"}]};return n({frontmatter:o}),r({title:"Privacy Policy",meta:[{property:"og:title",content:"Privacy Policy"},{name:"twitter:title",content:"Privacy Policy"}]}),(d,y)=>{const a=t;return s(),l(a,{frontmatter:o},{default:u(()=>[c]),_:1})}}};export{b as default,P as meta,w as title}; diff --git a/assets/utils-D7bH4Tlo.js b/assets/utils-BDrlE94o.js similarity index 84% rename from assets/utils-D7bH4Tlo.js rename to assets/utils-BDrlE94o.js index d820f23..f2c92d2 100644 --- a/assets/utils-D7bH4Tlo.js +++ b/assets/utils-BDrlE94o.js @@ -1 +1 @@ -import"./index-B-kKBcPB.js";function a(e){return e.normalize("NFKD").toLowerCase().trim().replace(/\s+/g,"-").replace(/[^\w\-]+/g,"").replace(/\_/g,"-").replace(/\-\-+/g,"-").replace(/\-$/g,"")}function n(e){return new Date(e).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}function c(e){try{return new Date(e).toISOString()}catch{return"2000-01-01T00:00:00.000Z"}}export{n as a,c as d,a as g}; +import"./index-CoFPLbfm.js";function a(e){return e.normalize("NFKD").toLowerCase().trim().replace(/\s+/g,"-").replace(/[^\w\-]+/g,"").replace(/\_/g,"-").replace(/\-\-+/g,"-").replace(/\-$/g,"")}function n(e){return new Date(e).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}function c(e){try{return new Date(e).toISOString()}catch{return"2000-01-01T00:00:00.000Z"}}export{n as a,c as d,a as g}; diff --git a/assets/videos-B48T2Bqr.js b/assets/videos-DZLBdRXH.js similarity index 75% rename from assets/videos-B48T2Bqr.js rename to assets/videos-DZLBdRXH.js index 570faf1..ae16ede 100644 --- a/assets/videos-B48T2Bqr.js +++ b/assets/videos-DZLBdRXH.js @@ -1 +1 @@ -import{_ as n}from"./SrcPage.vue_vue_type_script_setup_true_lang-BHEen7wR.js";import{d as a,i,r,o as c,c as l,a as e,b as t,F as m}from"./index-B-kKBcPB.js";import{_ as d}from"./VideoGroup.vue_vue_type_script_setup_true_lang-yt9KRqcL.js";import"./MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js";const _={class:"flex justify-center my-10"},p={class:"text-center"},u=e("h1",{class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"}," Videos ",-1),f={class:"my-8 flex justify-center gap-x-4"},k=a({__name:"videos",setup(x){return i({title:"Video Library"}),(g,h)=>{const o=r("Iconify"),s=n;return c(),l(m,null,[e("div",_,[e("div",p,[t(o,{icon:"material-symbols:hangout-video",class:"text-green-600 w-36 h-36 inline-block"}),u])]),t(d,{title:"Vue Components",summary:"Learn about productive features in our growing Vue Component Library",group:"vue",learnMore:"https://docs.servicestack.net/vue/"}),e("div",f,[t(s,{path:"videos.vue"})])],64)}}});export{k as default}; +import{_ as n}from"./SrcPage.vue_vue_type_script_setup_true_lang-BUJJyXxz.js";import{d as a,i,r,o as c,c as l,a as e,b as t,F as m}from"./index-CoFPLbfm.js";import{_ as d}from"./VideoGroup.vue_vue_type_script_setup_true_lang-Cko02hll.js";import"./MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js";const _={class:"flex justify-center my-10"},p={class:"text-center"},u=e("h1",{class:"text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"}," Videos ",-1),f={class:"my-8 flex justify-center gap-x-4"},k=a({__name:"videos",setup(x){return i({title:"Video Library"}),(g,h)=>{const o=r("Iconify"),s=n;return c(),l(m,null,[e("div",_,[e("div",p,[t(o,{icon:"material-symbols:hangout-video",class:"text-green-600 w-36 h-36 inline-block"}),u])]),t(d,{title:"Vue Components",summary:"Learn about productive features in our growing Vue Component Library",group:"vue",learnMore:"https://docs.servicestack.net/vue/"}),e("div",f,[t(s,{path:"videos.vue"})])],64)}}});export{k as default}; diff --git a/assets/whatsnew-DLwuVrUY.js b/assets/whatsnew-CZ_1B3HR.js similarity index 94% rename from assets/whatsnew-DLwuVrUY.js rename to assets/whatsnew-CZ_1B3HR.js index c9ac8b1..9d19ef1 100644 --- a/assets/whatsnew-DLwuVrUY.js +++ b/assets/whatsnew-CZ_1B3HR.js @@ -1 +1 @@ -import{_ as v}from"./MarkdownComponent.vue_vue_type_script_setup_true_lang-BmVN3Che.js";import{d as b,x as y,r as k,o,c as a,a as t,F as i,g as _,t as d,b as l,w as m,e as x,u as L,G as I,H as S,I as D,K as N}from"./index-B-kKBcPB.js";import{_ as C}from"./_plugin-vue_export-helper-DlAUqK2U.js";const V=n=>(D("data-v-51c6d3df"),n=n(),N(),n),B=V(()=>t("div",{class:"container mx-auto px-5"},[t("section",{class:"flex-col md:flex-row flex justify-center mt-16 mb-16 md:mb-12"},[t("h1",{class:"mx-auto max-w-4xl font-display text-5xl font-medium tracking-tight text-slate-900 dark:text-slate-50 sm:text-7xl"}," Latest features & highlights ")])],-1)),j={class:"relative px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},F={class:"relative mx-auto max-w-7xl"},P={class:"text-center mb-4 text-6xl md:text-7xl font-bold tracking-tighter leading-tight"},R={class:"text-center text-lg font-normal text-gray-500 dark:text-gray-400 mb-8"},z={class:"flex flex-wrap my-24"},E={class:"w-full sm:w-1/2 animated px-4"},G=["src"],H={class:"w-full sm:w-1/2 text-left wow fadeInLeft animated px-4"},K={class:"m-0 mb-4"},M={class:"prose dark:prose-invert max-w-none"},T={class:"text-center sm:text-left my-10"},U=b({__name:"whatsnew",setup(n){const u=y("press").whatsNew;function p(e){return new Date(e).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}function h(e){return I(e,"_")}function f(e){return S(e,"_")}return(e,q)=>{const r=k("RouterLink"),g=v;return o(),a(i,null,[B,t("div",j,[(o(!0),a(i,null,_(L(u),(w,c)=>(o(),a("div",F,[t("h2",P,d(f(c)),1),t("div",R,d(p(h(c))),1),(o(!0),a(i,null,_(w,s=>(o(),a("div",z,[t("div",E,[l(r,{to:s.url},{default:m(()=>[t("img",{src:s.image,alt:"",loading:"lazy"},null,8,G)]),_:2},1032,["to"])]),t("div",H,[t("h3",K,[l(r,{class:"text-2xl font-normal text-blue-500 hover:text-blue-600",to:s.url},{default:m(()=>[x(d(s.title),1)]),_:2},1032,["to"])]),t("div",M,[l(g,{type:"whatsNew",doc:s,group:c},null,8,["doc","group"])]),t("div",T,[l(r,{to:s.url,class:"text-white text-sm font-semibold py-2.5 px-3.5 rounded outline-none focus:outline-none mr-1 mb-1 bg-slate-700 active:bg-slate-600 shadow hover:shadow-lg ease-linear transition-all duration-150"},{default:m(()=>[x(" Learn more ")]),_:2},1032,["to"])])])]))),256))]))),256))])],64)}}}),Q=C(U,[["__scopeId","data-v-51c6d3df"]]);export{Q as default}; +import{_ as v}from"./MarkdownComponent.vue_vue_type_script_setup_true_lang-CsTUuBVZ.js";import{d as b,x as y,r as k,o,c as a,a as t,F as i,g as _,t as d,b as l,w as m,e as x,u as L,G as I,H as S,I as D,K as N}from"./index-CoFPLbfm.js";import{_ as C}from"./_plugin-vue_export-helper-DlAUqK2U.js";const V=n=>(D("data-v-51c6d3df"),n=n(),N(),n),B=V(()=>t("div",{class:"container mx-auto px-5"},[t("section",{class:"flex-col md:flex-row flex justify-center mt-16 mb-16 md:mb-12"},[t("h1",{class:"mx-auto max-w-4xl font-display text-5xl font-medium tracking-tight text-slate-900 dark:text-slate-50 sm:text-7xl"}," Latest features & highlights ")])],-1)),j={class:"relative px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28"},F={class:"relative mx-auto max-w-7xl"},P={class:"text-center mb-4 text-6xl md:text-7xl font-bold tracking-tighter leading-tight"},R={class:"text-center text-lg font-normal text-gray-500 dark:text-gray-400 mb-8"},z={class:"flex flex-wrap my-24"},E={class:"w-full sm:w-1/2 animated px-4"},G=["src"],H={class:"w-full sm:w-1/2 text-left wow fadeInLeft animated px-4"},K={class:"m-0 mb-4"},M={class:"prose dark:prose-invert max-w-none"},T={class:"text-center sm:text-left my-10"},U=b({__name:"whatsnew",setup(n){const u=y("press").whatsNew;function p(e){return new Date(e).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}function h(e){return I(e,"_")}function f(e){return S(e,"_")}return(e,q)=>{const r=k("RouterLink"),g=v;return o(),a(i,null,[B,t("div",j,[(o(!0),a(i,null,_(L(u),(w,c)=>(o(),a("div",F,[t("h2",P,d(f(c)),1),t("div",R,d(p(h(c))),1),(o(!0),a(i,null,_(w,s=>(o(),a("div",z,[t("div",E,[l(r,{to:s.url},{default:m(()=>[t("img",{src:s.image,alt:"",loading:"lazy"},null,8,G)]),_:2},1032,["to"])]),t("div",H,[t("h3",K,[l(r,{class:"text-2xl font-normal text-blue-500 hover:text-blue-600",to:s.url},{default:m(()=>[x(d(s.title),1)]),_:2},1032,["to"])]),t("div",M,[l(g,{type:"whatsNew",doc:s,group:c},null,8,["doc","group"])]),t("div",T,[l(r,{to:s.url,class:"text-white text-sm font-semibold py-2.5 px-3.5 rounded outline-none focus:outline-none mr-1 mb-1 bg-slate-700 active:bg-slate-600 shadow hover:shadow-lg ease-linear transition-all duration-150"},{default:m(()=>[x(" Learn more ")]),_:2},1032,["to"])])])]))),256))]))),256))])],64)}}}),Q=C(U,[["__scopeId","data-v-51c6d3df"]]);export{Q as default}; diff --git a/index.html b/index.html index 8be181c..90900ef 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ Vite + Vue + TS - +