diff --git a/.gitignore b/.gitignore index 8edcbd04..4cefb1cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,113 @@ .hugo_build.lock .vscode + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/hugo,node diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index cbbc36bc..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "themes/hugo-video"] - path = themes/hugo-video - url = https://github.com/martignoni/hugo-video.git diff --git a/Makefile b/Makefile index f2624f6d..aabd39e1 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,8 @@ endif .RECIPEPREFIX = > build: clean -> hugo +> npm ci +> hugo --minify clean: > rm -rf public/ @@ -19,9 +20,6 @@ clean: server: > hugo server --buildDrafts -## index-pagefind: Not yet implemented -index-pagefind: -> npx pagefind --source "public" ## help: Print this help message help: diff --git a/archetypes/default.md b/archetypes/default.md index 21255a18..82b2c5e7 100644 --- a/archetypes/default.md +++ b/archetypes/default.md @@ -1,35 +1,9 @@ --- -title: "{{ replace .TranslationBaseName "-" " " | title }}" -date: {{ .Date }} -lastmod: {{ .Date }} +title: "{{ humanize .Name | title }}" +date: "{{ .Date }}" draft: true -keywords: [] -description: "" -tags: [] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false +comments: true toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" - --- diff --git a/assets/css/custom.css b/assets/css/custom.css deleted file mode 100644 index 5c8be984..00000000 --- a/assets/css/custom.css +++ /dev/null @@ -1,15 +0,0 @@ -.hanchor { - visibility: hidden; - color: silver; - font-size: 100%; - transition: 0.2s; - padding-left: 8px; - font-weight: 600; -} - -h2:hover a, -h3:hover a, -h4:hover a { - visibility: visible; - text-decoration: none; -} diff --git a/assets/jsconfig.json b/assets/jsconfig.json new file mode 100644 index 00000000..05c9d2e1 --- /dev/null +++ b/assets/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "*": [ + "../node_modules/prismjs/*" + ] + } + } +} \ No newline at end of file diff --git a/config.yaml b/config.yaml index 565f21e0..c7ac718b 100644 --- a/config.yaml +++ b/config.yaml @@ -1,67 +1,54 @@ -baseurl: / -staticDir: static +baseurl: "https://davegallant.ca" languageCode: en-us googleAnalytics: G-V8WJDERTX9 copyright: Dave Gallant -preserveTaxonomyNames: true -pygmentsstyle: nord -pygmentscodefences: true -pygmentscodefencesguesssyntax: true -theme: - - archie - - hugo-video -title: davegallant params: - mode: toggle - useCDN: true - subtitle: "A personal blog" - mathjax: true - katex: true + author: Dave Gallant + subtitle: Software Engineer + favicon: https://davegallant.ca/favicon.ico - favicon: https://davegallant.ca/favicon.ico + logo: + text: davegallant.ca + url: / - kofi: - - customcss: - - css/custom.css - - social: - - name: Email - icon: at-sign - url: 'mailto:me@davegallant.ca' - - name: LinkTree - icon: compass - url: 'https://linktr.ee/davegallant' - - name: GitHub - icon: github - url: 'https://github.com/davegallant' - - name: Mastodon - icon: speaker - url: https://mastodon.social/@davegallant - - name: LinkedIn - icon: linkedin - url: https://www.linkedin.com/in/dave-gallant/ - - comments: - utterances: - enable: true - issueTerm: "pathname" - github: - username: davegallant - repository: davegallant.github.io + comments: + utterances: + enable: true + issueTerm: "pathname" + github: + username: davegallant + repository: davegallant.github.io menu: main: - - name: Posts - url: / - weight: 1 - - name: About - url: /about - weight: 2 - name: RSS url: /index.xml - weight: 3 + weight: 1 permalinks: - post: '/blog/:year/:month/:day/:slug/' + post: "/blog/:year/:month/:day/:slug/" + +module: + imports: + - path: github.com/davegallant/hugo-theme-gruvbox + - path: github.com/schnerring/hugo-mod-json-resume + mounts: + - source: node_modules/simple-icons/icons + target: assets/simple-icons + - source: assets + target: assets + - source: layouts + target: layouts + - source: static + target: static + - source: node_modules/prismjs + target: assets/prismjs + - source: node_modules/prism-themes/themes + target: assets/prism-themes + - source: node_modules/typeface-fira-code/files + target: static/fonts + - source: node_modules/typeface-roboto-slab/files + target: static/fonts + - source: node_modules/@tabler/icons/icons + target: assets/tabler-icons diff --git a/content/about.md b/content/about.md deleted file mode 100644 index ebc034f4..00000000 --- a/content/about.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: About -weight: -210 -disable_comments: true -hide_date: true ---- - -I'm a software tinkerer with a passion for infrastructure, tooling, security, and coffee. - -Feel free to reach out at [me@davegallant.ca](mailto:me@davegallant.ca). diff --git a/content/post/appgate-sdp-on-arch-linux/index.md b/content/post/appgate-sdp-on-arch-linux/index.md index 963ded33..8f676232 100644 --- a/content/post/appgate-sdp-on-arch-linux/index.md +++ b/content/post/appgate-sdp-on-arch-linux/index.md @@ -2,8 +2,7 @@ title: "AppGate SDP on Arch Linux" date: 2020-03-16T22:00:15-04:00 draft: false -keywords: ['linux', 'vpn'] -description: "" +comments: true tags: ['linux', 'vpn', 'python'] author: "Dave Gallant" --- diff --git a/content/post/automatically-rotating-aws-keys/index.md b/content/post/automatically-rotating-aws-keys/index.md index 9b494af6..6dff3a95 100644 --- a/content/post/automatically-rotating-aws-keys/index.md +++ b/content/post/automatically-rotating-aws-keys/index.md @@ -3,37 +3,10 @@ title: "Automatically rotating AWS access keys" date: 2021-09-17T12:48:33-04:00 lastmod: 2021-09-17T12:48:33-04:00 draft: false -keywords: [] -description: "" +comments: true tags: ['aws', 'python', 'security', 'aws-vault'] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" - --- - - Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a [script](https://gist.github.com/davegallant/2c042686a78684a657fe99e20fa7a924#file-aws_access_key_rotator-py) since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. In the longer term, migrating my local workflows to [aws-vault](https://github.com/99designs/aws-vault) seems like a more secure solution. This would mean that credentials (even temporary session credentials) never have to be written in plaintext to disk (i.e. where [AWS suggests](https://docs.aws.amazon.com/sdkref/latest/guide/file-location.html)). Any existing applications, such as terraform, could be have their credentials passed to them from aws-vault, which retrieves them from the OS's secure keystore. There is even a [rotate command](https://github.com/99designs/aws-vault/blob/master/USAGE.md#rotating-credentials) included. diff --git a/content/post/backing-up-gmail-with-synology/index.md b/content/post/backing-up-gmail-with-synology/index.md index 5ba68c64..21eb747c 100644 --- a/content/post/backing-up-gmail-with-synology/index.md +++ b/content/post/backing-up-gmail-with-synology/index.md @@ -2,39 +2,14 @@ title: "Backing up gmail with Synology" date: 2022-03-13T18:49:10-04:00 lastmod: 2022-03-13T18:49:10-04:00 +comments: true draft: false -keywords: [] -description: "" -tags: ['degoogle', 'synology', 'gmail', 'backup', 'ransomware'] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" - +tags: ["degoogle", "synology", "gmail", "backup", "ransomware"] --- - +I've used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines. - I've used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines. + The thought of completely de-googling has crossed my mind on occassion. Convenience, coupled with my admiration for Google engineering, has prevented me from doing so thus far. Though, I may end up doing so at some point in the future. @@ -42,7 +17,7 @@ The thought of completely de-googling has crossed my mind on occassion. Convenie Synology products are reasonably priced for what you get (essentially a cloud-in-a-box) and there is very little maintenance required. I've recently been in interested in syncing and snapshotting my personal data. I've setup [Synology's Cloud Sync](https://www.synology.com/en-ca/dsm/feature/cloud_sync) and keep copies of most of my cloud data. - I've used tools such as [gmvault](http://www.gmvault.org) with success in the past. Setting this up on a cron seems like a viable option. However, I don't really need a lot of the features it offers and do not plan to restore this data to another account. +I've used tools such as [gmvault](http://www.gmvault.org) with success in the past. Setting this up on a cron seems like a viable option. However, I don't really need a lot of the features it offers and do not plan to restore this data to another account. Synology's MailPlus seems to be a good candidate for backing up this data. By enabling POP3 fetching, it's possible to fetch all existing emails, as well as periodically fetch all new emails. If a disaster ever did occur, having these emails would be beneficial, as they are an extension of my memory bank. @@ -62,7 +37,7 @@ After this, mail started coming in. ![image](mail-plus-incoming-mail.png) - After fetching 19 years worth of emails, I tried searching for some emails. It only took a few seconds to search through ~50K emails, which is a relief if I ever did have to search for something important. +After fetching 19 years worth of emails, I tried searching for some emails. It only took a few seconds to search through ~50K emails, which is a relief if I ever did have to search for something important. ## Securing Synology diff --git a/content/post/replacing-docker-with-podman-on-macos/index.md b/content/post/replacing-docker-with-podman-on-macos/index.md index 29bf8537..da36721e 100644 --- a/content/post/replacing-docker-with-podman-on-macos/index.md +++ b/content/post/replacing-docker-with-podman-on-macos/index.md @@ -3,39 +3,14 @@ title: "Replacing docker with podman on macOS (and Linux)" date: 2021-10-11T10:43:35-04:00 lastmod: 2021-10-11T10:43:35-04:00 draft: false -keywords: [] -description: "" -tags: ['docker', 'podman', 'containers'] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" - +comments: true +tags: ["docker", "podman", "containers"] --- - - - There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker: + + {{< tweet 1388586550682861568 >}} Docker has been one of the larger influencers in the container world, helping to standardize the [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/main/spec.md). For many developers, containers have become synonymous with terms like `docker` and `Dockerfile` (a file containing build instructions for a container image). Docker has certainly made it very convenient to build and run containers, but it is not the only solution for doing so. @@ -85,7 +60,7 @@ Copying config sha256:14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8 Writing manifest to image destination Storing signatures 14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab -```` +``` > If you're having an issue pulling images, you may need to remove `~/.docker/config.json` or remove the set of auths in the configuration as mentioned [here](https://stackoverflow.com/a/69121873/1191286). @@ -118,7 +93,7 @@ alias docker=podman ### podman-compose -You may be wondering: what about docker-compose? Well, there *claims* to be a drop-in replacement for it: [podman-compose](https://github.com/containers/podman-compose). +You may be wondering: what about docker-compose? Well, there _claims_ to be a drop-in replacement for it: [podman-compose](https://github.com/containers/podman-compose). ```sh pip3 install --user podman-compose @@ -168,5 +143,4 @@ One caveat to mention is that there isn't an official graphical user interface f > Update: After further usage, bind mounts do not seem to work out of the box when the client and host are on different machines. A rather involved solution using [sshfs](https://en.wikipedia.org/wiki/SSHFS) was shared [here](https://github.com/containers/podman/issues/8016#issuecomment-920015800). - I had been experimenting with Podman on Linux before writing this, but after listening to this [podcast episode](https://kubernetespodcast.com/episode/164-podman/), I was inspired to give Podman a try on macOS. diff --git a/content/post/running-k3s-in-lxc-on-proxmox/index.md b/content/post/running-k3s-in-lxc-on-proxmox/index.md index bba432d6..afa0893b 100644 --- a/content/post/running-k3s-in-lxc-on-proxmox/index.md +++ b/content/post/running-k3s-in-lxc-on-proxmox/index.md @@ -3,29 +3,8 @@ title: "Running K3s in LXC on Proxmox" date: 2021-11-14T10:07:03-05:00 lastmod: 2021-11-14T10:07:03-05:00 draft: false -keywords: [] -description: "" +comments: true tags: ["k3s", "proxmox", "lxc", "self-hosted"] -categories: [] -author: "" - -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" --- It has been a while since I've actively used Kubernetes and wanted to explore the evolution of tools such as [Helm](https://helm.sh) and [Tekton](https://tekton.dev). I decided to deploy [K3s](https://k3s.io), since I've had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it'd be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. LXC containers also provide an efficient way to use a machine's resources. diff --git a/content/post/setting-up-gitea-actions-with-tailscale/index.md b/content/post/setting-up-gitea-actions-with-tailscale/index.md index 7948cfa3..91b72353 100644 --- a/content/post/setting-up-gitea-actions-with-tailscale/index.md +++ b/content/post/setting-up-gitea-actions-with-tailscale/index.md @@ -1,40 +1,17 @@ --- title: "Setting up Gitea Actions with Tailscale" date: 2023-12-10T17:22:11-05:00 +comments: true lastmod: 2023-12-10T17:22:11-05:00 draft: false -keywords: [] description: "" tags: ["gitea", "gitea actions", "github actions", "tailscale", "self-hosted"] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" --- - - In this post I'll go through the process of setting up Gitea Actions and [Tailscale](https://tailscale.com/), unlocking a simple and secure way to automate workflows. + + ## What is Gitea? [Gitea](https://about.gitea.com/) is a lightweight and fast git server that has much of the same look and feel as github. I have been using it in my homelab to mirror repositories hosted on other platforms such as github and gitlab. These mirrors take advantage of the decentralized nature of git by serving as "backups". One of the main reasons I hadn't been using it more often was due to the lack of integrated CI/CD. This is no longer the case. @@ -209,7 +186,7 @@ jobs: And voilà: -{{< video src="gitea-workflow" >}} +{{< video poster="gitea-workflow" >}} You may be wondering how the gitea runner is allowed to connect to the other hosts using ansible? Well, the nodes are in the same tailnet and have [tailscale ssh](https://tailscale.com/tailscale-ssh) enabled. diff --git a/content/post/using-aks-and-socks-to-connect-to-a-private-azure-db/index.md b/content/post/using-aks-and-socks-to-connect-to-a-private-azure-db/index.md index 7b70feac..85e12c1b 100644 --- a/content/post/using-aks-and-socks-to-connect-to-a-private-azure-db/index.md +++ b/content/post/using-aks-and-socks-to-connect-to-a-private-azure-db/index.md @@ -3,8 +3,7 @@ title: "Using AKS and SOCKS to connect to a private Azure DB" date: 2023-05-22T16:31:29-04:00 lastmod: 2023-05-22T16:31:29-04:00 draft: false -keywords: [] -description: "" +comments: true tags: [ "aks", @@ -20,36 +19,12 @@ tags: "socat", "socks", ] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" --- +I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I'd rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I'd like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this. + -## The Problem - -I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I'd rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I'd like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this. ## Go Public? diff --git a/content/post/virtualizing-a-router-with-pfsense/index.md b/content/post/virtualizing-a-router-with-pfsense/index.md index 008944f1..6e790fcf 100644 --- a/content/post/virtualizing-a-router-with-pfsense/index.md +++ b/content/post/virtualizing-a-router-with-pfsense/index.md @@ -3,8 +3,7 @@ title: "Virtualizing my router with pfSense" date: 2022-04-02T18:50:09-04:00 lastmod: 2022-04-02T18:50:09-04:00 draft: false -keywords: [] -description: "" +comments: true tags: [ "pfsense", @@ -15,37 +14,12 @@ tags: "vlan", "self-hosted", ] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" --- - - -## The problem - My aging router has been running [OpenWrt](https://en.wikipedia.org/wiki/OpenWrt) for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a [large index of packages](https://openwrt.org/packages/index/start). Ever since I've connected some standalone wireless access points, I've had less of a need for an off-the-shelf all-in-one wireless router combo. I've also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on! + + ## pfSense I figured this would be a good opportunity to try [pfSense](https://en.wikipedia.org/wiki/PfSense). I've heard nothing but positive things about pfSense and the fact it's been around since 2004, based on FreeBSD, and written in PHP gave me the impression that it would be relatively stable (and I'd expect nothing less because it has an important job to do!). pfSense can be run on many different machines, and there are even some [officially supported appliances](https://www.netgate.com/appliances). Since I already have a machine running Proxmox, why not just run it in a VM? It'd allow for automatic snapshotting of the machine. There is a good [video](https://www.youtube.com/watch?v=hdoBQNI_Ab8) on this by Techno Tim. Tim has a lot of good videos, and this one is about virtualizing pfSense. diff --git a/content/post/watching-youtube-in-private/index.md b/content/post/watching-youtube-in-private/index.md index 95434e46..e47a7f32 100644 --- a/content/post/watching-youtube-in-private/index.md +++ b/content/post/watching-youtube-in-private/index.md @@ -3,8 +3,7 @@ title: "Watching YouTube in private" date: 2022-12-10T21:46:55-05:00 lastmod: 2022-12-10T21:46:55-05:00 draft: false -keywords: [] -description: "" +comments: true tags: [ "invidious", @@ -15,35 +14,12 @@ tags: "privacy", "self-hosted", ] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" --- - - I recently stumbled upon [yewtu.be](https://yewtu.be) and found it intriguing. It not only allows you to watch YouTube without _being on YouTube_, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it's a hosted instance of [invidious](https://invidious.io/). + + ![image](computerphile.png) The layout is simple, and **JavaScript is not required**. diff --git a/content/post/what-to-do-with-a-homelab/index.md b/content/post/what-to-do-with-a-homelab/index.md index daede185..eff2b36a 100644 --- a/content/post/what-to-do-with-a-homelab/index.md +++ b/content/post/what-to-do-with-a-homelab/index.md @@ -3,21 +3,7 @@ title: "What to do with a homelab" date: 2021-09-06T01:12:54-04:00 lastmod: 2021-09-06T01:12:54-04:00 draft: false -keywords: [] -description: "" -tags: - [ - "tailscale", - "homelab", - "netdata", - "jellyfin", - "plex", - "pihole", - "virtualization", - "adguard", - "grafana", - "self-hosted", - ] +comments: true author: "Dave Gallant" --- diff --git a/content/post/why-i-threw-out-my-dotfiles/index.md b/content/post/why-i-threw-out-my-dotfiles/index.md index c78b6861..30211843 100644 --- a/content/post/why-i-threw-out-my-dotfiles/index.md +++ b/content/post/why-i-threw-out-my-dotfiles/index.md @@ -3,37 +3,12 @@ title: "Why I threw out my dotfiles" date: 2021-09-08T00:42:33-04:00 lastmod: 2021-09-08T00:42:33-04:00 draft: false -keywords: [] -description: "" +comments: true tags: ['nix', 'dotfiles', 'home-manager'] -categories: [] -author: "" - -# You can also close(false) or open(true) something for this content. -# P.S. comment can only be closed -comment: false -toc: false -autoCollapseToc: false -postMetaInFooter: false -hiddenFromHomePage: false -# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright." -contentCopyright: false -reward: false -mathjax: false -mathjaxEnableSingleDollar: false - -flowchartDiagrams: - enable: false - options: "" - -sequenceDiagrams: - enable: false - options: "" - --- +Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (`~/.zshrc`, `~/.config/git/config`, `~/.config/tmux/tmux.conf`, etc). I have tried several different ways to manage them, including [bare git repos](https://www.atlassian.com/git/tutorials/dotfiles) and utilities such as [GNU Stow](https://www.gnu.org/software/stow/). These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: [home-manager](https://github.com/nix-community/home-manager). -Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (`~/.zshrc`, `~/.config/git/config`, `~/.config/tmux/tmux.conf`, etc). I have tried several different ways to manage them, including [bare git repos](https://www.atlassian.com/git/tutorials/dotfiles) and utilities such as [GNU Stow](https://www.gnu.org/software/stow/). These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: [home-manager](https://github.com/nix-community/home-manager). ## What is home-manager? diff --git a/data/json_resume/en.json b/data/json_resume/en.json new file mode 100644 index 00000000..dce4ceac --- /dev/null +++ b/data/json_resume/en.json @@ -0,0 +1,27 @@ +{ + "basics": { + "name": "Dave Gallant", + "label": "Software Engineer", + "image": "", + "email": "me@davegallant.ca", + "summary": "I'm a software tinkerer passionate about infra, security and self-hosting 👋.", + "profiles": [ + { + "network": "LinkTree", + "url": "https://linktr.ee/davegallant" + }, + { + "network": "GitHub", + "url": "https://github.com/davegallant" + }, + { + "network": "Mastodon", + "url": "https://mastodon.social/@davegallant" + }, + { + "network": "LinkedIn", + "url": "https://www.linkedin.com/in/dave-gallant" + } + ] + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..ebccffcd --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module davegallant.github.io + +go 1.21.5 + +require ( + github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102030224-3e3d39381e83 // indirect + github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a // indirect + github.com/schnerring/hugo-theme-gruvbox v0.0.0-20231222001142-c40bfccc26fe // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..c4cb3a71 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102030224-3e3d39381e83 h1:1K2zeS/GlzUztodRODqVdT0L53So3oKQl2W6xv3hk3k= +github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102030224-3e3d39381e83/go.mod h1:BQehNdf/SB/+bCc031OVsLECIgB9ZaN1dfUFKTeOIuo= +github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a h1:EZRiOf0iW5k9lycVv3LngzSsGUxDRszYS4U7ea2r8RY= +github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a/go.mod h1:5dixHC0WHu0w2Aqb8hsOCrIU1OBYr1w5Q6HZAmTub7Q= +github.com/schnerring/hugo-theme-gruvbox v0.0.0-20231222001142-c40bfccc26fe h1:YFCe/83618UT24IqSn7Ka0TSSZ54BNvDJ7n0WzxWgsg= +github.com/schnerring/hugo-theme-gruvbox v0.0.0-20231222001142-c40bfccc26fe/go.mod h1:ZEP0AB4v1k845Jmx9XmOY39CuR7Zud/owFh8wRGgeZg= diff --git a/themes/archie/layouts/partials/comments.html b/layouts/partials/comments.html similarity index 56% rename from themes/archie/layouts/partials/comments.html rename to layouts/partials/comments.html index 167dc4a1..885ba2be 100644 --- a/themes/archie/layouts/partials/comments.html +++ b/layouts/partials/comments.html @@ -1,8 +1,17 @@ + + + {{- $config := .Site.Params.comments -}} {{- $utterancesEnabled := $config.utterances.enable -}} -{{- if and ( $utterancesEnabled ) ( not .Params.disable_comments) -}} +{{- if and ( $utterancesEnabled ) -}}
diff --git a/themes/archie/layouts/partials/comments/utterances.html b/layouts/partials/comments/utterances.html similarity index 100% rename from themes/archie/layouts/partials/comments/utterances.html rename to layouts/partials/comments/utterances.html diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..e90cac60 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6774 @@ +{ + "name": "davegallant.github.io", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "davegallant.github.io", + "version": "0.1.0", + "dependencies": { + "@tabler/icons": "^2.44.0", + "flexsearch": "^0.7.31", + "normalize.css": "^8.0.1", + "prism-themes": "^1.9.0", + "prismjs": "^1.29.0", + "simple-icons": "^10.4.0", + "typeface-fira-code": "^1.1.13", + "typeface-roboto-slab": "^1.1.13" + }, + "devDependencies": { + "@fullhuman/postcss-purgecss": "^5.0.0", + "cssnano": "^6.0.2", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.1", + "husky": "^8.0.3", + "lint-staged": "^15.2.0", + "markdownlint-cli": "^0.38.0", + "postcss": "^8.4.32", + "postcss-cli": "^11.0.0", + "postcss-custom-media": "^10.0.2", + "postcss-import": "^15.1.0", + "postcss-nesting": "^12.0.2", + "postcss-preset-env": "^9.3.0", + "postcss-url": "^10.1.3", + "prettier": "^3.1.1", + "prettier-plugin-go-template": "^0.0.15", + "stylelint": "^16.0.2", + "stylelint-prettier": "^5.0.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.7.tgz", + "integrity": "sha512-9J4aMRJ7A2WRjaRLvsMeWrL69FmEuijtiW1XlK/sG+V0UJiHVYUyvj9mY4WAXfU/hGIiGOgL8e0jJcRyaZTjDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-4.0.0.tgz", + "integrity": "sha512-wjyXB22/h2OvxAr3jldPB7R7kjTUEzopvjitS8jWtyd8fN6xJ8vy1HnHu0ZNfEkqpBJgQ76Q+sBDshWcMvTa/w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-1.1.6.tgz", + "integrity": "sha512-YHPAuFg5iA4qZGzMzvrQwzkvJpesXXyIUyaONflQrjtHB+BcFFbgltJkIkb31dMGO4SE9iZFA4HYpdk7+hnYew==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-1.5.1.tgz", + "integrity": "sha512-x+SajGB2paGrTjPOUorGi8iCztF008YMKXTn+XzGVDBEIVJ/W1121pPerpneJYGOe1m6zWLPLnzOPaznmQxKFw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/color-helpers": "^4.0.0", + "@csstools/css-calc": "^1.1.6" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.5.0.tgz", + "integrity": "sha512-abypo6m9re3clXA00eu5syw+oaPHbJTPapu9C4pzNsJ4hdZDzushT50Zhu+iIYXgEe1CxnRMn7ngsbV+MLrlpQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.2.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.3.tgz", + "integrity": "sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.7.tgz", + "integrity": "sha512-lHPKJDkPUECsyAvD60joYfDmp8UERYxHGkFfyLJFTVK/ERJe0sVlIFLXU5XFxdjNDTerp5L4KeaKG+Z5S94qxQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + } + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-4.0.2.tgz", + "integrity": "sha512-PqM+jvg5T2tB4FHX+akrMGNWAygLupD4FNUjcv4PSvtVuWZ6ISxuo37m4jFGU7Jg3rCfloGzKd0+xfr5Ec3vZQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/selector-specificity": "^3.0.1", + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-3.0.9.tgz", + "integrity": "sha512-6Hbkw/4k73UH121l4LG+LNLKSvrfHqk3GHHH0A6/iFlD0xGmsWAr80Jd0VqXjfYbUTOGmJTOMMoxv3jvNxt1uw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^3.0.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-function": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-2.0.9.tgz", + "integrity": "sha512-fs1SOWJ/44DQSsDeJP+rxAkP2MYkCg6K4ZB8qJwFku2EjurgCAPiPZJvC6w94T1hBBinJwuMfT9qvvvniXyVgw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^3.0.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-exponential-functions": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-1.0.3.tgz", + "integrity": "sha512-IfGtEg3eC4b8Nd/kPgO3SxgKb33YwhHVsL0eJ3UYihx6fzzAiZwNbWmVW9MZTQjZ5GacgKxa4iAHikGvpwuIjw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-calc": "^1.1.6", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-3.0.1.tgz", + "integrity": "sha512-D1lcG2sfotTq6yBEOMV3myFxJLT10F3DLYZJMbiny5YToqzHWodZen8WId3UTimm0mEHitXqAUNL5jdd6RzVdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-1.0.2.tgz", + "integrity": "sha512-zf9KHGM2PTuJEm4ZYg4DTmzCir38EbZBzlMPMbA4jbhLDqXHkqwnQ+Z5+UNrU8y6seVu5B4vzZmZarTFQwe+Ig==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gradients-interpolation-method": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-4.0.9.tgz", + "integrity": "sha512-PSqR6QH7h3ggOl8TsoH73kbwYTKVQjAJauGg6nDKwaGfi5IL5StV//ehrv1C7HuPsHixMTc9YoAuuv1ocT20EQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^3.0.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-3.0.8.tgz", + "integrity": "sha512-CRQEG372Hivmt17rm/Ho22hBQI9K/a6grzGQ21Zwc7dyspmyG0ibmPIW8hn15vJmXqWGeNq7S+L2b8/OrU7O5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-3.0.3.tgz", + "integrity": "sha512-MpcmIL0/uMm/cFWh5V/9nbKKJ7jRr2qTYW5Q6zoE6HZ6uzOBJr2KRERv5/x8xzEBQ1MthDT7iP1EBp9luSQy7g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^3.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-1.0.1.tgz", + "integrity": "sha512-wtb+IbUIrIf8CrN6MLQuFR7nlU5C7PwuebfeEXfjthUha1+XZj2RVi+5k/lukToA24sZkYAiSJfHM8uG/UZIdg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-4.0.4.tgz", + "integrity": "sha512-vTVO/uZixpTVAOQt3qZRUFJ/K1L03OfNkeJ8sFNDVNdVy/zW0h1L5WT7HIPMDUkvSrxQkFaCCybTZkUP7UESlQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/selector-specificity": "^3.0.1", + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-float-and-clear": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-2.0.1.tgz", + "integrity": "sha512-SsrWUNaXKr+e/Uo4R/uIsqJYt3DaggIh/jyZdhy/q8fECoJSKsSMr7nObSLdvoULB69Zb6Bs+sefEIoMG/YfOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overflow": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-1.0.1.tgz", + "integrity": "sha512-Kl4lAbMg0iyztEzDhZuQw8Sj9r2uqFDcU1IPl+AAt2nue8K/f1i7ElvKtXkjhIAmKiy5h2EY8Gt/Cqg0pYFDCw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overscroll-behavior": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-1.0.1.tgz", + "integrity": "sha512-+kHamNxAnX8ojPCtV8WPcUP3XcqMFBSDuBuvT6MHgq7oX4IQxLIXKx64t7g9LiuJzE7vd06Q9qUYR6bh4YnGpQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-resize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-2.0.1.tgz", + "integrity": "sha512-W5Gtwz7oIuFcKa5SmBjQ2uxr8ZoL7M2bkoIf0T1WeNqljMkBrfw1DDA8/J83k57NQ1kcweJEjkJ04pUkmyee3A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-viewport-units": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-2.0.5.tgz", + "integrity": "sha512-2fjSamKN635DSW6fEoyNd2Bkpv3FVblUpgk5cpghIgPW1aDHZE2SYfZK5xQALvjMYZVjfqsD5EbXA7uDVBQVQA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-tokenizer": "^2.2.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-minmax": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.1.2.tgz", + "integrity": "sha512-7qTRTJxW96u2yiEaTep1+8nto1O/rEDacewKqH+Riq5E6EsHTOmGHxkB4Se5Ic5xgDC4I05lLZxzzxnlnSypxA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-calc": "^1.1.6", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/media-query-list-parser": "^2.1.7" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-2.0.5.tgz", + "integrity": "sha512-XHMPasWYPWa9XaUHXU6Iq0RLfoAI+nvGTPj51hOizNsHaAyFiq2SL4JvF1DU8lM6B70+HVzKM09Isbyrr755Bw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/media-query-list-parser": "^2.1.7" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-3.0.1.tgz", + "integrity": "sha512-bwwababZpWRm0ByHaWBxTsDGTMhZKmtUNl3Wt0Eom8AY7ORgXx5qF9SSk1vEFrCi+HOfJT6M6W5KPgzXuQNRwQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-3.0.2.tgz", + "integrity": "sha512-fCapyyT/dUdyPtrelQSIV+d5HqtTgnNP/BEG9IuhgXHt93Wc4CfC1bQ55GzKAjWrZbgakMQ7MLfCXEf3rlZJOw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-3.0.9.tgz", + "integrity": "sha512-l639gpcBfL3ogJe+og1M5FixQn8iGX8+29V7VtTSCUB37VzpzOC05URfde7INIdiJT65DkHzgdJ64/QeYggU8A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^3.0.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-3.0.3.tgz", + "integrity": "sha512-WipTVh6JTMQfeIrzDV4wEPsV9NTzMK2jwXxyH6CGBktuWdivHnkioP/smp1x/0QDPQyx7NTS14RB+GV3zZZYEw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-2.0.9.tgz", + "integrity": "sha512-2UoaRd2iIuzUGtYgteN5fJ0s+OfCiV7PvCnw8MCh3om8+SeVinfG8D5sqBOvImxFVfrp6k60XF5RFlH6oc//fg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^3.0.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-3.0.1.tgz", + "integrity": "sha512-3ZFonK2gfgqg29gUJ2w7xVw2wFJ1eNWVDONjbzGkm73gJHVCYK5fnCqlLr+N+KbEfv2XbWAO0AaOJCFB6Fer6A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-3.0.4.tgz", + "integrity": "sha512-gyNQ2YaOVXPqLR737XtReRPVu7DGKBr9JBDLoiH1T+N1ggV3r4HotRCOC1l6rxVC0zOuU1KiOzUn9Z5W838/rg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-calc": "^1.1.6", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-3.0.4.tgz", + "integrity": "sha512-yUZmbnUemgQmja7SpOZeU45+P49wNEgQguRdyTktFkZsHf7Gof+ZIYfvF6Cm+LsU1PwSupy4yUeEKKjX5+k6cQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/color-helpers": "^4.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-3.0.4.tgz", + "integrity": "sha512-qj4Cxth6c38iNYzfJJWAxt8jsLrZaMVmbfGDDLOlI2YJeZoC3A5Su6/Kr7oXaPFRuspUu+4EQHngOktqVHWfVg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-calc": "^1.1.6", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-3.0.1.tgz", + "integrity": "sha512-dbDnZ2ja2U8mbPP0Hvmt2RMEGBiF1H7oY6HYSpjteXJGihYwgxgTr6KRbbJ/V6c+4wd51M+9980qG4gKVn5ttg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.1.tgz", + "integrity": "sha512-NPljRHkq4a14YzZ3YD406uaxh7s0g6eAq3L9aLOWywoqe8PkYamAvtsh7KNX6c++ihDrJ0RiU+/z7rGnhlZ5ww==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.13" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fullhuman/postcss-purgecss": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-5.0.0.tgz", + "integrity": "sha512-onDS/b/2pMRzqSoj4qOs2tYFmOpaspjTAgvACIHMPiicu1ptajiBruTrjBzTKdxWdX0ldaBb7wj8nEaTLyFkJw==", + "dev": true, + "dependencies": { + "purgecss": "^5.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.0.tgz", + "integrity": "sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", + "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@tabler/icons": { + "version": "2.45.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-2.45.0.tgz", + "integrity": "sha512-J10UDghOni9wlrj5CpKAzychDCABCKYq897mGg0wGFsd+tYLaUdz0dt/HZeGnV8gZJo0hIiTPLGwBp5EW42Qsg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "dependencies": { + "type-fest": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001572", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz", + "integrity": "sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-blank-pseudo": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-6.0.1.tgz", + "integrity": "sha512-goSnEITByxTzU4Oh5oJZrEWudxTqk7L6IXj1UW69pO6Hv0UdX+Vsrt02FFu5DweRh2bLu6WpX/+zsQCu5O1gKw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.1.1.tgz", + "integrity": "sha512-dZ3bVTEEc1vxr3Bek9vGwfB5Z6ESPULhcRvO472mfjVnj8jRcTnKO8/JTczlvxM10Myb+wBM++1MtdO76eWcaQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-functions-list": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", + "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==", + "dev": true, + "engines": { + "node": ">=12 || >=16" + } + }, + "node_modules/css-has-pseudo": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-6.0.1.tgz", + "integrity": "sha512-WwoVKqNxApfEI7dWFyaHoeFCcUPD+lPyjL6lNpRUNX7IyIUuVpawOTwwA5D0ZR6V2xQZonNPVj8kEcxzEaAQfQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/selector-specificity": "^3.0.1", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-9.0.1.tgz", + "integrity": "sha512-iFit06ochwCKPRiWagbTa1OAWCvWWVdEnIFd8BaRrgO8YrrNh4RAWUQTFcYX5tdFZgFl1DJ3iiULchZyEbnF4g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssdb": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.10.0.tgz", + "integrity": "sha512-yGZ5tmA57gWh/uvdQBHs45wwFY0IBh3ypABk5sEubPBPSzXzkNgsWReqx7gdx6uhC+QoFBe+V8JwBB9/hQ6cIA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ] + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.2.tgz", + "integrity": "sha512-Tu9wv8UdN6CoiQnIVkCNvi+0rw/BwFWOJBlg2bVfEyKaadSuE3Gq/DD8tniVvggTJGwK88UjqZp7zL5sv6t1aA==", + "dev": true, + "dependencies": { + "cssnano-preset-default": "^6.0.2", + "lilconfig": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.2.tgz", + "integrity": "sha512-VnZybFeZ63AiVqIUNlxqMxpj9VU8B5j0oKgP7WyVt/7mkyf97KsYkNzsPTV/RVmy54Pg7cBhOK4WATbdCB44gw==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^7.0.0", + "cssnano-utils": "^4.0.1", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.0.1", + "postcss-convert-values": "^6.0.1", + "postcss-discard-comments": "^6.0.1", + "postcss-discard-duplicates": "^6.0.1", + "postcss-discard-empty": "^6.0.1", + "postcss-discard-overridden": "^6.0.1", + "postcss-merge-longhand": "^6.0.1", + "postcss-merge-rules": "^6.0.2", + "postcss-minify-font-values": "^6.0.1", + "postcss-minify-gradients": "^6.0.1", + "postcss-minify-params": "^6.0.1", + "postcss-minify-selectors": "^6.0.1", + "postcss-normalize-charset": "^6.0.1", + "postcss-normalize-display-values": "^6.0.1", + "postcss-normalize-positions": "^6.0.1", + "postcss-normalize-repeat-style": "^6.0.1", + "postcss-normalize-string": "^6.0.1", + "postcss-normalize-timing-functions": "^6.0.1", + "postcss-normalize-unicode": "^6.0.1", + "postcss-normalize-url": "^6.0.1", + "postcss-normalize-whitespace": "^6.0.1", + "postcss-ordered-values": "^6.0.1", + "postcss-reduce-initial": "^6.0.1", + "postcss-reduce-transforms": "^6.0.1", + "postcss-svgo": "^6.0.1", + "postcss-unique-selectors": "^6.0.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.1.tgz", + "integrity": "sha512-6qQuYDqsGoiXssZ3zct6dcMxiqfT6epy7x4R0TQJadd4LWO3sPR6JH6ZByOvVLoZ6EdwPGgd7+DR1EmX3tiXQQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, + "node_modules/cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.616", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", + "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.2.tgz", + "integrity": "sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/flexsearch": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz", + "integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==" + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", + "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^1.0.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", + "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/lint-staged": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", + "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", + "dev": true, + "dependencies": { + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.0", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/listr2": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", + "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-it": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdownlint": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.32.1.tgz", + "integrity": "sha512-3sx9xpi4xlHlokGyHO9k0g3gJbNY4DI6oNEeEYq5gQ4W7UkiJ90VDAnuDl2U+yyXOUa6BX+0gf69ZlTUGIBp6A==", + "dev": true, + "dependencies": { + "markdown-it": "13.0.2", + "markdownlint-micromark": "0.1.7" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.38.0.tgz", + "integrity": "sha512-qkZRKJ4LVq6CJIkRIuJsEHvhWhm+FP0E7yhHvOMrrgdykgFWNYD4wuhZTjvigbJLTKPooP79yPiUDDZBCBI5JA==", + "dev": true, + "dependencies": { + "commander": "~11.1.0", + "get-stdin": "~9.0.0", + "glob": "~10.3.10", + "ignore": "~5.3.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.2.0", + "markdownlint": "~0.32.1", + "minimatch": "~9.0.3", + "run-con": "~1.3.2" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/markdownlint-cli/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/markdownlint-cli/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", + "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/meow": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.0.0.tgz", + "integrity": "sha512-4Hu+75Vo7EOR+8C9RmkabfLijuwd9SrzQ8f0SyC4qZZwU6BlxeOt5ulF3PGCpcMJX4hI+ktpJhea0P6PN1RiWw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" + }, + "node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-6.0.2.tgz", + "integrity": "sha512-IRuCwwAAQbgaLhxQdQcIIK0dCVXg3XDUnzgKD8iwdiYdwU4rMWRWyl/W9/0nA4ihVpq5pyALiHB2veBJ0292pw==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-cli": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.0.tgz", + "integrity": "sha512-xMITAI7M0u1yolVcXJ9XTZiO9aO49mcoKQy6pCDFdMh9kGqhzLVpWxeD/32M/QBmkhcGypZFFOLNLmIW4Pg4RA==", + "dev": true, + "dependencies": { + "chokidar": "^3.3.0", + "dependency-graph": "^0.11.0", + "fs-extra": "^11.0.0", + "get-stdin": "^9.0.0", + "globby": "^14.0.0", + "picocolors": "^1.0.0", + "postcss-load-config": "^5.0.0", + "postcss-reporter": "^7.0.0", + "pretty-hrtime": "^1.0.3", + "read-cache": "^1.0.0", + "slash": "^5.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "postcss": "index.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-6.0.4.tgz", + "integrity": "sha512-YBzfVvVUNR4U3N0imzU1NPKCuwxzfHJkEP6imJxzsJ8LozRKeej9mWmg9Ef1ovJdb0xrGTRVzUxgTrMun5iw/Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^3.0.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-9.0.3.tgz", + "integrity": "sha512-7sEHU4tAS6htlxun8AB9LDrCXoljxaC34tFVRlYKcvO+18r5fvGiXgv5bQzN40+4gXLCyWSMRK5FK31244WcCA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-9.0.2.tgz", + "integrity": "sha512-f+RDEAPW2m8UbJWkSpRfV+QxhSaQhDMihI75DVGJJh4oRIoegjheeRtINFJum9D8BqGJcvD4GLjggTvCwZ4zuA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-colormin": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.0.1.tgz", + "integrity": "sha512-Tb9aR2wCJCzKuNjIeMzVNd0nXjQy25HDgFmmaRsHnP0eP/k8uQWE4S8voX5S2coO5CeKrp+USFs1Ayv9Tpxx6w==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.1.tgz", + "integrity": "sha512-zTd4Vh0HxGkhg5aHtfCogcRHzGkvblfdWlQ53lIh1cJhYcGyIxh2hgtKoVh40AMktRERet+JKdB04nNG19kjmA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-custom-media": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-10.0.2.tgz", + "integrity": "sha512-zcEFNRmDm2fZvTPdI1pIW3W//UruMcLosmMiCdpQnrCsTRzWlKQPYMa1ud9auL0BmrryKK1+JjIGn19K0UjO/w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/cascade-layer-name-parser": "^1.0.5", + "@csstools/css-parser-algorithms": "^2.3.2", + "@csstools/css-tokenizer": "^2.2.1", + "@csstools/media-query-list-parser": "^2.1.5" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-properties": { + "version": "13.3.4", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-13.3.4.tgz", + "integrity": "sha512-9YN0gg9sG3OH+Z9xBrp2PWRb+O4msw+5Sbp3ZgqrblrwKspXVQe5zr5sVqi43gJGwW/Rv1A483PRQUzQOEewvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/cascade-layer-name-parser": "^1.0.7", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-7.1.6.tgz", + "integrity": "sha512-svsjWRaxqL3vAzv71dV0/65P24/FB8TbPX+lWyyf9SZ7aZm4S4NhCn7N3Bg+Z5sZunG3FS8xQ80LrCU9hb37cw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/cascade-layer-name-parser": "^1.0.5", + "@csstools/css-parser-algorithms": "^2.3.2", + "@csstools/css-tokenizer": "^2.2.1", + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-8.0.1.tgz", + "integrity": "sha512-uULohfWBBVoFiZXgsQA24JV6FdKIidQ+ZqxOouhWwdE+qJlALbkS5ScB43ZTjPK+xUZZhlaO/NjfCt5h4IKUfw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.1.tgz", + "integrity": "sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.1.tgz", + "integrity": "sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.1.tgz", + "integrity": "sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.1.tgz", + "integrity": "sha512-qs0ehZMMZpSESbRkw1+inkf51kak6OOzNRaoLd/U7Fatp0aN2HQ1rxGOrJvYcRAN9VpX8kUF13R2ofn8OlvFVA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-5.0.3.tgz", + "integrity": "sha512-QKYpwmaSm6HcdS0ndAuWSNNMv78R1oSySoh3mYBmctHWr2KWcwPJVakdOyU4lvFVW0GRu9wfIQwGeM4p3xU9ow==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^3.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-9.0.1.tgz", + "integrity": "sha512-N2VQ5uPz3Z9ZcqI5tmeholn4d+1H14fKXszpjogZIrFbhaq0zNAtq8sAnw6VLiqGbL8YBzsnu7K9bBkTqaRimQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-8.0.1.tgz", + "integrity": "sha512-NFU3xcY/xwNaapVb+1uJ4n23XImoC86JNwkY/uduytSl2s9Ekc2EpzmRR63+ExitnW3Mab3Fba/wRPCT5oDILA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "dev": true, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-5.0.1.tgz", + "integrity": "sha512-k2z9Cnngc24c0KF4MtMuDdToROYqGMMUQGcE6V0odwjHyOHtaDBlLeRBV70y9/vF7KIbShrTRZ70JjsI1BZyWw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-image-set-function": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-6.0.2.tgz", + "integrity": "sha512-/O1xwqpJiz/apxGQi7UUfv1xUcorvkHZfvCYHPpRxxZj2WvjD0rg0+/+c+u5/Do5CpUg3XvfYxMrhcnjW1ArDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-lab-function": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-6.0.9.tgz", + "integrity": "sha512-PKFAVTBEWJYsoSTD7Kp/OzeiMsXaLX39Pv75XgUyF5VrbMfeTw+JqCGsvDP3dPhclh6BemdCFHcjXBG9gO4UCg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.5.1", + "@csstools/css-parser-algorithms": "^2.5.0", + "@csstools/css-tokenizer": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^3.0.3" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-load-config": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-5.0.2.tgz", + "integrity": "sha512-Q8QR3FYbqOKa0bnC1UQ2bFq9/ulHX5Bi34muzitMr8aDtUelO5xKeJEYC/5smE0jNE9zdB/NBnOwXKexELbRlw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/postcss-logical": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-7.0.1.tgz", + "integrity": "sha512-8GwUQZE0ri0K0HJHkDv87XOLC8DE0msc+HoWLeKdtjDZEwpZ5xuK3QdV6FhmHSQW40LPkg43QzvATRAI3LsRkg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.1.tgz", + "integrity": "sha512-vmr/HZQzaPXc45FRvSctqFTF05UaDnTn5ABX+UtQPJznDWT/QaFbVc/pJ5C2YPxx2J2XcfmWowlKwtCDwiQ5hA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.0.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.0.2.tgz", + "integrity": "sha512-6lm8bl0UfriSfxI+F/cezrebqqP8w702UC6SjZlUlBYwuRVNbmgcJuQU7yePIvD4MNT53r/acQCUAyulrpgmeQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.1", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.0.1.tgz", + "integrity": "sha512-tIwmF1zUPoN6xOtA/2FgVk1ZKrLcCvE0dpZLtzyyte0j9zUeB8RTbCqrHZGjJlxOvNWKMYtunLrrl7HPOiR46w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.1.tgz", + "integrity": "sha512-M1RJWVjd6IOLPl1hYiOd5HQHgpp6cvJVLrieQYS9y07Yo8itAr6jaekzJphaJFR0tcg4kRewCk3kna9uHBxn/w==", + "dev": true, + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^4.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.0.1.tgz", + "integrity": "sha512-eFvGWArqh4khPIgPDu6SZNcaLctx97nO7c59OXnRtGntAp5/VS4gjMhhW9qUFsK6mQ27pEZGt2kR+mPizI+Z9g==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^4.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.1.tgz", + "integrity": "sha512-mfReq5wrS6vkunxvJp6GDuOk+Ak6JV7134gp8L+ANRnV9VwqzTvBtX6lpohooVU750AR0D3pVx2Zn6uCCwOAfQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-nesting": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-12.0.2.tgz", + "integrity": "sha512-63PpJHSeNs93S3ZUIyi+7kKx4JqOIEJ6QYtG3x+0qA4J03+4n0iwsyA1GAHyWxsHYljQS4/4ZK1o2sMi70b5wQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/selector-specificity": "^3.0.1", + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.1.tgz", + "integrity": "sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.1.tgz", + "integrity": "sha512-mc3vxp2bEuCb4LgCcmG1y6lKJu1Co8T+rKHrcbShJwUmKJiEl761qb/QQCfFwlrvSeET3jksolCR/RZuMURudw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.1.tgz", + "integrity": "sha512-HRsq8u/0unKNvm0cvwxcOUEcakFXqZ41fv3FOdPn916XFUrympjr+03oaLkuZENz3HE9RrQE9yU0Xv43ThWjQg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.1.tgz", + "integrity": "sha512-Gbb2nmCy6tTiA7Sh2MBs3fj9W8swonk6lw+dFFeQT68B0Pzwp1kvisJQkdV6rbbMSd9brMlS8I8ts52tAGWmGQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.1.tgz", + "integrity": "sha512-5Fhx/+xzALJD9EI26Aq23hXwmv97Zfy2VFrt5PLT8lAhnBIZvmaT5pQk+NuJ/GWj/QWaKSKbnoKDGLbV6qnhXg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.1.tgz", + "integrity": "sha512-4zcczzHqmCU7L5dqTB9rzeqPWRMc0K2HoR+Bfl+FSMbqGBUcP5LRfgcH4BdRtLuzVQK1/FHdFoGT3F7rkEnY+g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.1.tgz", + "integrity": "sha512-ok9DsI94nEF79MkvmLfHfn8ddnKXA7w+8YuUoz5m7b6TOdoaRCpvu/QMHXQs9+DwUbvp+ytzz04J55CPy77PuQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.1.tgz", + "integrity": "sha512-jEXL15tXSvbjm0yzUV7FBiEXwhIa9H88JOXDGQzmcWoB4mSjZIsmtto066s2iW9FYuIrIF4k04HA2BKAOpbsaQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.1.tgz", + "integrity": "sha512-76i3NpWf6bB8UHlVuLRxG4zW2YykF9CTEcq/9LGAiz2qBuX5cBStadkk0jSkg9a9TCIXbMQz7yzrygKoCW9JuA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-2.0.0.tgz", + "integrity": "sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ==", + "dev": true, + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.1.tgz", + "integrity": "sha512-XXbb1O/MW9HdEhnBxitZpPFbIvDgbo9NK4c/5bOfiKpnIGZDoL2xd7/e6jW5DYLsWxBbs+1nZEnVgnjnlFViaA==", + "dev": true, + "dependencies": { + "cssnano-utils": "^4.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-5.0.1.tgz", + "integrity": "sha512-XzjBYKLd1t6vHsaokMV9URBt2EwC9a7nDhpQpjoPk2HRTSQfokPfyAS/Q7AOrzUu6q+vp/GnrDBGuj/FCaRqrQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "dev": true, + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-9.0.1.tgz", + "integrity": "sha512-JfL+paQOgRQRMoYFc2f73pGuG/Aw3tt4vYMR6UA3cWVMxivviPTnMFnFTczUJOA4K2Zga6xgQVE+PcLs64WC8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-preset-env": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-9.3.0.tgz", + "integrity": "sha512-ycw6doPrqV6QxDCtgiyGDef61bEfiSc59HGM4gOw/wxQxmKnhuEery61oOC/5ViENz/ycpRsuhTexs1kUBTvVw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/postcss-cascade-layers": "^4.0.1", + "@csstools/postcss-color-function": "^3.0.7", + "@csstools/postcss-color-mix-function": "^2.0.7", + "@csstools/postcss-exponential-functions": "^1.0.1", + "@csstools/postcss-font-format-keywords": "^3.0.0", + "@csstools/postcss-gamut-mapping": "^1.0.0", + "@csstools/postcss-gradients-interpolation-method": "^4.0.7", + "@csstools/postcss-hwb-function": "^3.0.6", + "@csstools/postcss-ic-unit": "^3.0.2", + "@csstools/postcss-initial": "^1.0.0", + "@csstools/postcss-is-pseudo-class": "^4.0.3", + "@csstools/postcss-logical-float-and-clear": "^2.0.0", + "@csstools/postcss-logical-overflow": "^1.0.0", + "@csstools/postcss-logical-overscroll-behavior": "^1.0.0", + "@csstools/postcss-logical-resize": "^2.0.0", + "@csstools/postcss-logical-viewport-units": "^2.0.3", + "@csstools/postcss-media-minmax": "^1.1.0", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^2.0.3", + "@csstools/postcss-nested-calc": "^3.0.0", + "@csstools/postcss-normalize-display-values": "^3.0.1", + "@csstools/postcss-oklab-function": "^3.0.7", + "@csstools/postcss-progressive-custom-properties": "^3.0.2", + "@csstools/postcss-relative-color-syntax": "^2.0.7", + "@csstools/postcss-scope-pseudo-class": "^3.0.0", + "@csstools/postcss-stepped-value-functions": "^3.0.2", + "@csstools/postcss-text-decoration-shorthand": "^3.0.3", + "@csstools/postcss-trigonometric-functions": "^3.0.2", + "@csstools/postcss-unset-value": "^3.0.0", + "autoprefixer": "^10.4.16", + "browserslist": "^4.22.1", + "css-blank-pseudo": "^6.0.0", + "css-has-pseudo": "^6.0.0", + "css-prefers-color-scheme": "^9.0.0", + "cssdb": "^7.9.0", + "postcss-attribute-case-insensitive": "^6.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^6.0.2", + "postcss-color-hex-alpha": "^9.0.2", + "postcss-color-rebeccapurple": "^9.0.1", + "postcss-custom-media": "^10.0.2", + "postcss-custom-properties": "^13.3.2", + "postcss-custom-selectors": "^7.1.6", + "postcss-dir-pseudo-class": "^8.0.0", + "postcss-double-position-gradients": "^5.0.2", + "postcss-focus-visible": "^9.0.0", + "postcss-focus-within": "^8.0.0", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^5.0.0", + "postcss-image-set-function": "^6.0.1", + "postcss-lab-function": "^6.0.7", + "postcss-logical": "^7.0.0", + "postcss-nesting": "^12.0.1", + "postcss-opacity-percentage": "^2.0.0", + "postcss-overflow-shorthand": "^5.0.0", + "postcss-page-break": "^3.0.4", + "postcss-place": "^9.0.0", + "postcss-pseudo-class-any-link": "^9.0.0", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^7.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-9.0.1.tgz", + "integrity": "sha512-cKYGGZ9yzUZi+dZd7XT2M8iSDfo+T2Ctbpiizf89uBTBfIpZpjvTavzIJXpCReMVXSKROqzpxClNu6fz4DHM0Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.0.13" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.1.tgz", + "integrity": "sha512-cgzsI2ThG1PMSdSyM9A+bVxiiVgPIVz9f5c6H+TqEv0CA89iCOO81mwLWRWLgOKFtQkKob9nNpnkxG/1RlgFcA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.1.tgz", + "integrity": "sha512-fUbV81OkUe75JM+VYO1gr/IoA2b/dRiH6HvMwhrIBSUrxq3jNZQZitSnugcTLDi1KkQh1eR/zi+iyxviUNBkcQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "dev": true, + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-reporter": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz", + "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "thenby": "^1.3.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", + "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-not": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-7.0.1.tgz", + "integrity": "sha512-1zT5C27b/zeJhchN7fP0kBr16Cc61mu7Si9uWWLoA3Px/D9tIJPKchJCkUH3tPO5D0pCFmGeApAv8XpXBQJ8SQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.1.tgz", + "integrity": "sha512-eWV4Rrqa06LzTgqirOv5Ln6WTGyU7Pbeqj9WEyKo9tpnWixNATVJMeaEcOHOW1ZYyjcG8wSJwX/28DvU3oy3HA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.0.5" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.1.tgz", + "integrity": "sha512-/KCCEpNNR7oXVJ38/Id7GC9Nt0zxO1T3zVbhVaq6F6LSG+3gU3B7+QuTHfD0v8NPEHlzewAout29S0InmB78EQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-url": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz", + "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==", + "dev": true, + "dependencies": { + "make-dir": "~3.1.0", + "mime": "~2.5.2", + "minimatch": "~3.0.4", + "xxhashjs": "~0.2.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-url/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prettier-plugin-go-template": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/prettier-plugin-go-template/-/prettier-plugin-go-template-0.0.15.tgz", + "integrity": "sha512-WqU92E1NokWYNZ9mLE6ijoRg6LtIGdLMePt2C7UBDjXeDH9okcRI3zRqtnWR4s5AloiqyvZ66jNBAa9tmRY5EQ==", + "dev": true, + "dependencies": { + "ulid": "^2.3.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "prettier": "^3.0.0" + } + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/prism-themes": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/prism-themes/-/prism-themes-1.9.0.tgz", + "integrity": "sha512-tX2AYsehKDw1EORwBps+WhBFKc2kxfoFpQAjxBndbZKr4fRmMkv47XN0BghC/K1qwodB1otbe4oF23vUTFDokw==" + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/purgecss": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-5.0.0.tgz", + "integrity": "sha512-RAnuxrGuVyLLTr8uMbKaxDRGWMgK5CCYDfRyUNNcaz5P3kGgD2b7ymQGYEyo2ST7Tl/ScwFgf5l3slKMxHSbrw==", + "dev": true, + "dependencies": { + "commander": "^9.0.0", + "glob": "^8.0.3", + "postcss": "^8.4.4", + "postcss-selector-parser": "^6.0.7" + }, + "bin": { + "purgecss": "bin/purgecss.js" + } + }, + "node_modules/purgecss/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/purgecss/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/purgecss/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/purgecss/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-con": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", + "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~4.1.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-icons": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-10.4.0.tgz", + "integrity": "sha512-XBoU1ljCsWjw59IVkaQ1nKc0PiaDAAKNFVx59ueC0tBy4WY/I4Q040sGj6ok2cZRLT8zBzL1HaTubi8MRqmojQ==", + "engines": { + "node": ">=0.12.18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/simple-icons" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylehacks": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.1.tgz", + "integrity": "sha512-jTqG2aIoX2fYg0YsGvqE4ooE/e75WmaEjnNiP6Ag7irLtHxML8NJRxRxS0HyDpde8DRGuEXTFVHVfR5Tmbxqzg==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/stylelint": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.1.0.tgz", + "integrity": "sha512-Sh1rRV0lN1qxz/QsuuooLWsIZ/ona7NKw/fRZd6y6PyXYdD2W0EAzJ8yJcwSx4Iw/muz0CF09VZ+z4EiTAcKmg==", + "dev": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^2.4.0", + "@csstools/css-tokenizer": "^2.2.2", + "@csstools/media-query-list-parser": "^2.1.6", + "@csstools/selector-specificity": "^3.0.1", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^9.0.0", + "css-functions-list": "^3.2.1", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.3.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.29.0", + "mathml-tag-names": "^2.1.3", + "meow": "^13.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.32", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^7.0.0", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^7.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-prettier": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-5.0.0.tgz", + "integrity": "sha512-RHfSlRJIsaVg5Br94gZVdWlz/rBTyQzZflNE6dXvSxt/GthWMY3gEHsWZEBaVGg7GM+XrtVSp4RznFlB7i0oyw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "prettier": ">=3.0.0", + "stylelint": ">=16.0.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.0.tgz", + "integrity": "sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/stylelint/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/stylelint/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stylelint/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/svgo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", + "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/table/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenby": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz", + "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typeface-fira-code": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/typeface-fira-code/-/typeface-fira-code-1.1.13.tgz", + "integrity": "sha512-8TRlYeIGAqwNajMHB3eSFs58VVfKsAsA0JRVu7z895s/FBl3nrh4PCvbH8tqxadU0UXEbCxNBvZtXn/Jpt7C3Q==" + }, + "node_modules/typeface-roboto-slab": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/typeface-roboto-slab/-/typeface-roboto-slab-1.1.13.tgz", + "integrity": "sha512-2oDTI2Z8GC/ijzhEXPYFA2EmF2Rm446skjY3gK56EzfVEX3BBgil1H9/ifqx9/IfBNwlqVoVs9Ez/g6zOhvC1Q==" + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/ulid": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz", + "integrity": "sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==", + "dev": true, + "bin": { + "ulid": "bin/cli.js" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "dev": true, + "dependencies": { + "cuint": "^0.2.2" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.hugo.json b/package.hugo.json new file mode 100644 index 00000000..55fdf1ae --- /dev/null +++ b/package.hugo.json @@ -0,0 +1,4 @@ +{ + "name": "davegallant.github.io", + "version": "0.1.0" +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..88ba5585 --- /dev/null +++ b/package.json @@ -0,0 +1,68 @@ +{ + "comments": { + "dependencies": { + "@tabler/icons": "github.com/davegallant/hugo-theme-gruvbox", + "flexsearch": "github.com/davegallant/hugo-theme-gruvbox", + "normalize.css": "github.com/davegallant/hugo-theme-gruvbox", + "prism-themes": "github.com/davegallant/hugo-theme-gruvbox", + "prismjs": "github.com/davegallant/hugo-theme-gruvbox", + "simple-icons": "github.com/schnerring/hugo-mod-json-resume", + "typeface-fira-code": "github.com/davegallant/hugo-theme-gruvbox", + "typeface-roboto-slab": "github.com/davegallant/hugo-theme-gruvbox" + }, + "devDependencies": { + "@fullhuman/postcss-purgecss": "github.com/davegallant/hugo-theme-gruvbox", + "cssnano": "github.com/davegallant/hugo-theme-gruvbox", + "eslint": "github.com/davegallant/hugo-theme-gruvbox", + "eslint-config-prettier": "github.com/davegallant/hugo-theme-gruvbox", + "eslint-plugin-prettier": "github.com/davegallant/hugo-theme-gruvbox", + "husky": "github.com/davegallant/hugo-theme-gruvbox", + "lint-staged": "github.com/davegallant/hugo-theme-gruvbox", + "markdownlint-cli": "github.com/davegallant/hugo-theme-gruvbox", + "postcss": "github.com/davegallant/hugo-theme-gruvbox", + "postcss-cli": "github.com/davegallant/hugo-theme-gruvbox", + "postcss-custom-media": "github.com/davegallant/hugo-theme-gruvbox", + "postcss-import": "github.com/davegallant/hugo-theme-gruvbox", + "postcss-nesting": "github.com/davegallant/hugo-theme-gruvbox", + "postcss-preset-env": "github.com/davegallant/hugo-theme-gruvbox", + "postcss-url": "github.com/davegallant/hugo-theme-gruvbox", + "prettier": "github.com/davegallant/hugo-theme-gruvbox", + "prettier-plugin-go-template": "github.com/davegallant/hugo-theme-gruvbox", + "stylelint": "github.com/davegallant/hugo-theme-gruvbox", + "stylelint-prettier": "github.com/davegallant/hugo-theme-gruvbox" + } + }, + "dependencies": { + "@tabler/icons": "^2.44.0", + "flexsearch": "^0.7.31", + "normalize.css": "^8.0.1", + "prism-themes": "^1.9.0", + "prismjs": "^1.29.0", + "simple-icons": "^10.4.0", + "typeface-fira-code": "^1.1.13", + "typeface-roboto-slab": "^1.1.13" + }, + "devDependencies": { + "@fullhuman/postcss-purgecss": "^5.0.0", + "cssnano": "^6.0.2", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.1", + "husky": "^8.0.3", + "lint-staged": "^15.2.0", + "markdownlint-cli": "^0.38.0", + "postcss": "^8.4.32", + "postcss-cli": "^11.0.0", + "postcss-custom-media": "^10.0.2", + "postcss-import": "^15.1.0", + "postcss-nesting": "^12.0.2", + "postcss-preset-env": "^9.3.0", + "postcss-url": "^10.1.3", + "prettier": "^3.1.1", + "prettier-plugin-go-template": "^0.0.15", + "stylelint": "^16.0.2", + "stylelint-prettier": "^5.0.0" + }, + "name": "davegallant.github.io", + "version": "0.1.0" +} diff --git a/public/404.html b/public/404.html index a2d2f0d9..c81c3145 100644 --- a/public/404.html +++ b/public/404.html @@ -1,145 +1,10 @@ - - - - - 404 Page not found - davegallant - - - - - - +404 Page not found +
+

404 Page not found

This is not the page you're looking for.

\ No newline at end of file diff --git a/public/about/index.html b/public/about/index.html deleted file mode 100644 index 3f77220c..00000000 --- a/public/about/index.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - About - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- -
-
-
-

About

- -
- - -

I’m a software tinkerer with a passion for infrastructure, tooling, security, and coffee.

-

Feel free to reach out at me@davegallant.ca.

-
- - - - - - -
-
- -
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 00000000..f6256164 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 00000000..e6f588e2 Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 00000000..3faefa82 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/blog/2020/03/16/appgate-sdp-on-arch-linux/index.html b/public/blog/2020/03/16/appgate-sdp-on-arch-linux/index.html index 075b45c1..a755d007 100644 --- a/public/blog/2020/03/16/appgate-sdp-on-arch-linux/index.html +++ b/public/blog/2020/03/16/appgate-sdp-on-arch-linux/index.html @@ -1,288 +1,68 @@ - - - - AppGate SDP on Arch Linux - davegallant - - - - - - - - +AppGate SDP on Arch Linux +
+

AppGate SDP on Arch Linux

AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP 4.3.2 working on Arch Linux.

Depending on the AppGate SDP Server that is running, you may require a client that is more recent than the latest package on AUR. +As of right now, the latest AUR is 4.2.2-1.

These steps highlight how to get it working with Python3.8 by making a 1 line modification to AppGate source code.

Packaging

We already know the community package is currently out of date, so let’s clone it:

git clone https://aur.archlinux.org/appgate-sdp.git
+cd appgate-sdp
+

You’ll likely notice that the version is not what we want, so let’s modify the PKGBUILD to the following:

# Maintainer: Pawel Mosakowski <pawel at mosakowski dot net>
+pkgname=appgate-sdp
+conflicts=('appgate-sdp-headless')
+pkgver=4.3.2
+_download_pkgver=4.3
+pkgrel=1
+epoch=
+pkgdesc="Software Defined Perimeter - GUI client"
+arch=('x86_64')
+url="https://www.cyxtera.com/essential-defense/appgate-sdp/support"
+license=('custom')
+# dependecies calculated by namcap
+depends=('gconf' 'libsecret' 'gtk3' 'python' 'nss' 'libxss' 'nodejs' 'dnsmasq')
+source=("https://sdpdownloads.cyxtera.com/AppGate-SDP-${_download_pkgver}/clients/${pkgname}_${pkgver}_amd64.deb"
+        "appgatedriver.service")
+options=(staticlibs)
+prepare() {
+    tar -xf data.tar.xz
+}
+package() {
+    cp -dpr "${srcdir}"/{etc,lib,opt,usr} "${pkgdir}"
+    mv -v "$pkgdir/lib/systemd/system" "$pkgdir/usr/lib/systemd/"
+    rm -vrf "$pkgdir/lib"
+    cp -v "$srcdir/appgatedriver.service" "$pkgdir/usr/lib/systemd/system/appgatedriver.service"
+    mkdir -vp "$pkgdir/usr/share/licenses/appgate-sdp"
+    cp -v "$pkgdir/usr/share/doc/appgate/copyright" "$pkgdir/usr/share/licenses/appgate-sdp"
+    cp -v "$pkgdir/usr/share/doc/appgate/LICENSE.github" "$pkgdir/usr/share/licenses/appgate-sdp"
+    cp -v "$pkgdir/usr/share/doc/appgate/LICENSES.chromium.html.bz2" "$pkgdir/usr/share/licenses/appgate-sdp"
+}
+md5sums=('17101aac7623c06d5fbb95f50cf3dbdc'
+         '002644116e20b2d79fdb36b7677ab4cf')
+

Let’s first make sure we have some dependencies. If you do not have yay, check it out.

yay -S dnsmasq gconf
+

Now, let’s install it:

makepkg -si
+

Running the client

Ok, let’s run the client by executing appgate.

It complains about not being able to connect.

Easy fix:

sudo systemctl start appgatedriver.service
+

Now we should be connected… but DNS is not working?

Fixing the DNS

Running resolvectl should display that something is not right.

Why is the DNS not being set by appgate?

$ head -3 /opt/appgate/linux/set_dns
+#!/usr/bin/env python3
+'''
+This is used to set and unset the DNS.
 

It seems like python3 is required for the DNS setting to happen. -Let’s try to run it.

-
$ sudo /opt/appgate/linux/set_dns
-/opt/appgate/linux/set_dns:88: SyntaxWarning: "is" with a literal. Did you mean "=="?
-  servers = [( socket.AF_INET if x.version is 4 else socket.AF_INET6, map(int, x.packed)) for x in servers]
-Traceback (most recent call last):
-  File "/opt/appgate/linux/set_dns", line 30, in <module>
-    import dbus
-ModuleNotFoundError: No module named 'dbus'
-

Ok, let’s install it:

-
$ sudo python3.8 -m pip install dbus-python
-

Will it work now? Not yet. There’s another issue:

-
$ sudo /opt/appgate/linux/set_dns
-/opt/appgate/linux/set_dns:88: SyntaxWarning: "is" with a literal. Did you mean "=="?
-  servers = [( socket.AF_INET if x.version is 4 else socket.AF_INET6, map(int, x.packed)) for x in servers]
-module 'platform' has no attribute 'linux_distribution'
-

This is a breaking change in Python3.8.

-

So what is calling platform.linux_distribution?

-

Let’s search for it:

-
$ sudo grep -r 'linux_distribution' /opt/appgate/linux/
-/opt/appgate/linux/nm.py:    if platform.linux_distribution()[0] != 'Fedora':
-

Aha! So this is in the local AppGate source code. This should be an easy fix. Let’s just replace this line with:

-
if True: # Since we are not using Fedora :)
-

Wrapping up

-

It turns out there are breaking changes in Python3.8.

-

The docs say Deprecated since version 3.5, will be removed in version 3.8: See alternative like the distro package.

-

I suppose this highlights one of the caveats of relying upon the system’s python, rather than having an isolated, dedicated environment for all dependencies.

- - - - - -
- - - - - -
- - - -
-
-
-
-
-
- - - - - - - +Let’s try to run it.

$ sudo /opt/appgate/linux/set_dns
+/opt/appgate/linux/set_dns:88: SyntaxWarning: "is" with a literal. Did you mean "=="?
+  servers = [( socket.AF_INET if x.version is 4 else socket.AF_INET6, map(int, x.packed)) for x in servers]
+Traceback (most recent call last):
+  File "/opt/appgate/linux/set_dns", line 30, in <module>
+    import dbus
+ModuleNotFoundError: No module named 'dbus'
+

Ok, let’s install it:

$ sudo python3.8 -m pip install dbus-python
+

Will it work now? Not yet. There’s another issue:

$ sudo /opt/appgate/linux/set_dns
+/opt/appgate/linux/set_dns:88: SyntaxWarning: "is" with a literal. Did you mean "=="?
+  servers = [( socket.AF_INET if x.version is 4 else socket.AF_INET6, map(int, x.packed)) for x in servers]
+module 'platform' has no attribute 'linux_distribution'
+

This is a breaking change in Python3.8.

So what is calling platform.linux_distribution?

Let’s search for it:

$ sudo grep -r 'linux_distribution' /opt/appgate/linux/
+/opt/appgate/linux/nm.py:    if platform.linux_distribution()[0] != 'Fedora':
+

Aha! So this is in the local AppGate source code. This should be an easy fix. Let’s just replace this line with:

if True: # Since we are not using Fedora :)
+

Wrapping up

It turns out there are breaking changes in Python3.8.

The docs say Deprecated since version 3.5, will be removed in version 3.8: See alternative like the distro package.

I suppose this highlights one of the caveats of relying upon the system’s python, rather than having an isolated, dedicated environment for all dependencies.

\ No newline at end of file diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/index.html b/public/blog/2021/09/06/what-to-do-with-a-homelab/index.html index 3e17a6ed..64b902fe 100644 --- a/public/blog/2021/09/06/what-to-do-with-a-homelab/index.html +++ b/public/blog/2021/09/06/what-to-do-with-a-homelab/index.html @@ -1,244 +1,15 @@ - - - - What to do with a homelab - davegallant - - - - - - - - +What to do with a homelab +
+

What to do with a homelab

A homelab can be an inexpensive way to host a multitude of internal/external services and learn a lot in the process.

Do you want host your own Media server? Ad blocker? Web server? Are you interested in learning more about Linux? Virtualization? Networking? Security? -Building a homelab can be an entertaining playground to enhance your computer skills.

-

One of the best parts about building a homelab is that it doesn’t have to be a large investment in terms of hardware. One of the simplest ways to build a homelab is out of a refurbished computer. -Having multiple machines/nodes provides the advantage of increased redundancy, but starting out with a single node is enough to reap many of the benefits of having a homelab.

-

Virtualization#

-

Virtualizing your hardware is an organized way of dividing up your machine’s resources. This can be done with something such as a Virtual Machine or something lighter like a container using LXC or runC. -Containers have much less overhead in terms of boot time and storage allocation. This Stack Overflow answer sums it up nicely.

-

image

-

A hypervisor such as Proxmox can be installed in minutes on a new machine. It provides a web interface and a straight-forward way to spin up new VMs and containers. Even if your plan is to run mostly docker containers, Proxmox can be a useful abstraction for managing VMs, disks and running scheduled backups. You can even run docker within an LXC container by enabling nested virtualization. You’ll want to ensure that VT-d and VT-x are enabled in the BIOS if you decide to install a hypervisor to manage your virtualization.

-

Services#

-

So what are some useful services to deploy?

-
    -
  • Jellyfin or Plex - basically a self-hosted Netflix that can be used to stream from multiple devices, and the best part is that you manage the content! Unlike Plex, Jellyfin is open source and can be found here.
  • -
  • changedetection - is a self-hosted equivalent to something like visualping.io that will notify you when a webpage changes and keep track of the diffs
  • -
  • Adguard or Pihole - can block a list of known trackers for all clients on your local network. I’ve used pihole for a long time, but have recently switched to Adguard since the UI is more modern and it has the ability to toggle on/off a pre-defined list of services, including Netflix (this is useful if you have stealthy young kids). Either of these will speed up your internet experience, simply because you won’t need to download all of the extra tracking bloat.
  • -
  • Gitea - A lightweight git server. I use this to mirror git repos from GitHub, GitLab, etc.
  • -
  • Homer - A customizable landing page for services you need to access (including the ability to quickly search).
  • -
  • Uptime Kuma - A fancy tool for monitoring the uptime of services.
  • -
-

There is a large number of services you can self-host, including your own applications that you might be developing. awesome-self-hosted provides a curated list of services that might be of interest to you.

-

VPN#

-

You could certainly setup and manage your own VPN by using something like OpenVPN, but there is also something else you can try: tailscale. It is a very quick way to create fully-encrypted connections between clients. With its MagicDNS, your can reference the names of machines like homer rather than using an IP address. By using this mesh-like VPN, you can easily create a secure tunnel to your homelab from anywhere.

-

Monitoring#

-

dashboard

-

Monitoring can become an important aspect of your homelab after it starts to become something that is relied upon. One of the simplest ways to setup some monitoring is using netdata. It can be installed on individual containers, VMs, and also a hypervisor (such as Proxmox). All of the monitoring works out of the box by detecting disks, memory, network interfaces, etc.

-

Additionally, agents installed on different machines can all be centrally viewed in netdata, and it can alert you when some of your infrastructure is down or in a degraded state. Adding additional nodes to netdata is as simple as a 1-line shell command.

-

As mentioned above, Uptime Kuma is a convenient way to track uptime and monitor the availability of your services.

-

uptime-kuma

-

In Summary#

-

Building out a homelab can be a rewarding experience and it doesn’t require buying a rack full of expensive servers to get a significant amount of utility. There are many services that you can run that require very minimal setup, making it possible to get a server up and running in a short period of time, with monitoring, and that can be securely connected to remotely.

- - - - - - -
-
- -
-
-
-
-
-
- - - - -
- - +Building a homelab can be an entertaining playground to enhance your computer skills.

One of the best parts about building a homelab is that it doesn’t have to be a large investment in terms of hardware. One of the simplest ways to build a homelab is out of a refurbished computer. +Having multiple machines/nodes provides the advantage of increased redundancy, but starting out with a single node is enough to reap many of the benefits of having a homelab.

Virtualization

Virtualizing your hardware is an organized way of dividing up your machine’s resources. This can be done with something such as a Virtual Machine or something lighter like a container using LXC or runC. +Containers have much less overhead in terms of boot time and storage allocation. This Stack Overflow answer sums it up nicely.

image

A hypervisor such as Proxmox can be installed in minutes on a new machine. It provides a web interface and a straight-forward way to spin up new VMs and containers. Even if your plan is to run mostly docker containers, Proxmox can be a useful abstraction for managing VMs, disks and running scheduled backups. You can even run docker within an LXC container by enabling nested virtualization. You’ll want to ensure that VT-d and VT-x are enabled in the BIOS if you decide to install a hypervisor to manage your virtualization.

Services

So what are some useful services to deploy?

There is a large number of services you can self-host, including your own applications that you might be developing. awesome-self-hosted provides a curated list of services that might be of interest to you.

VPN

You could certainly setup and manage your own VPN by using something like OpenVPN, but there is also something else you can try: tailscale. It is a very quick way to create fully-encrypted connections between clients. With its MagicDNS, your can reference the names of machines like homer rather than using an IP address. By using this mesh-like VPN, you can easily create a secure tunnel to your homelab from anywhere.

Monitoring

dashboard

Monitoring can become an important aspect of your homelab after it starts to become something that is relied upon. One of the simplest ways to setup some monitoring is using netdata. It can be installed on individual containers, VMs, and also a hypervisor (such as Proxmox). All of the monitoring works out of the box by detecting disks, memory, network interfaces, etc.

Additionally, agents installed on different machines can all be centrally viewed in netdata, and it can alert you when some of your infrastructure is down or in a degraded state. Adding additional nodes to netdata is as simple as a 1-line shell command.

As mentioned above, Uptime Kuma is a convenient way to track uptime and monitor the availability of your services.

uptime-kuma

In Summary

Building out a homelab can be a rewarding experience and it doesn’t require buying a rack full of expensive servers to get a significant amount of utility. There are many services that you can run that require very minimal setup, making it possible to get a server up and running in a short period of time, with monitoring, and that can be securely connected to remotely.

\ No newline at end of file diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_box_3.png new file mode 100644 index 00000000..c4bd8e24 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..6cb24f63 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_box_3.png new file mode 100644 index 00000000..d64e5545 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..84d6a1a2 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_box_3.png new file mode 100644 index 00000000..331ad27f Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..35c55c76 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_box_3.png new file mode 100644 index 00000000..789280b7 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..3c2deefe Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_box_3.png new file mode 100644 index 00000000..735594a3 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..221bcc64 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_box_3.png new file mode 100644 index 00000000..4e6011ee Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..b524a6ae Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_box_3.png new file mode 100644 index 00000000..856fda81 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..367b2845 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_box_3.png new file mode 100644 index 00000000..bdf1fdf9 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..b6fc8f43 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_box_3.png b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_box_3.png new file mode 100644 index 00000000..6ce19142 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_box_3.png differ diff --git a/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_q75_h2_box_3.webp b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..a0f8a0c9 Binary files /dev/null and b/public/blog/2021/09/06/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2021/09/08/why-i-threw-out-my-dotfiles/index.html b/public/blog/2021/09/08/why-i-threw-out-my-dotfiles/index.html index 519572fb..af0a7857 100644 --- a/public/blog/2021/09/08/why-i-threw-out-my-dotfiles/index.html +++ b/public/blog/2021/09/08/why-i-threw-out-my-dotfiles/index.html @@ -1,339 +1,119 @@ - - - - Why I threw out my dotfiles - davegallant - - - - - - - - +Why I threw out my dotfiles +
+

Why I threw out my dotfiles

Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (~/.zshrc, ~/.config/git/config, ~/.config/tmux/tmux.conf, etc). I have tried several different ways to manage them, including bare git repos and utilities such as GNU Stow. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: home-manager.

What is home-manager?

Before understanding home-manager, it is worth briefly discussing what nix is. nix is a package manager that originally spawned from a PhD thesis. Unlike other package managers, it uses symbolic links to keep track of the currently installed packages, keeping around the old ones in case you may want to rollback.

For example, I have used nix to install the package bind which includes dig. You can see that it is available on multiple platforms. The absolute path of dig can be found by running:

$ ls -lh $(which dig)
+lrwxr-xr-x 73 root 31 Dec  1969 /run/current-system/sw/bin/dig -> /nix/store/0r4qdyprljd3dki57jn6c6a8dh2rbg9g-bind-9.16.16-dnsutils/bin/dig
+

Notice that there is a hash included in the file path? This is a nix store path and is computed by the nix package manager. This nix pill does a good job explaining how this hash is computed. All of the nix pills are worth a read, if you are interested in learning more about nix itself. However, using home-manager does not require extensive knowledge of nix.

Part of the nix ecosystem includes nixpkgs. Many popular tools can be found already packaged in this repository. As you can see with these stats, there is a large number of existing packages that are being maintained by the community. Contributing a new package is easy, and anyone can do it!

home-manager leverages the nix package manager (and nixpkgs), as well the nix language so that you can declaratively define your system configuration. I store my nix-config in git so that I can keep track of my packages and configurations, and retain a clean and informative git commit history so that I can understand what changed and why.

Setting up home-manager

⚠️ If you run this on your main machine, make sure you backup your configuration files first. home-manager is pretty good about not overwriting existing configuration, but it is better to have a backup! Alternatively, you could test this out on a VM or cloud instance.

The first thing you should do is install nix:

curl -L https://nixos.org/nix/install | sh
+

It’s generally not a good idea to curl and execute files from the internet (without verifying integrity), so you might want to download the install script first and take a look before executing it!

Open up a new shell in your terminal and running nix should work. If not, run . ~/.nix-profile/etc/profile.d/nix.sh

Now, install home-manager:

nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
+nix-channel --update
+nix-shell '<home-manager>' -A install
+

You should see a wave of /nix/store/* paths being displayed on your screen.

Now, to start off with a basic configuration, open up ~/.config/nixpkgs/home.nix in the editor of your choice and paste this in (you will want to change userName and homeDirectory):

{ config, pkgs, ... }:
+
+{
+  programs.home-manager.enable = true;
+
+  home = {
+    username = "dave";
+    homeDirectory = "/home/dave";
+    stateVersion = "21.11";
+    packages = with pkgs; [
+      bind
+      exa
+      fd
+      ripgrep
+    ];
+  };
+
+  programs = {
+
+    git = {
+      enable = true;
+      aliases = {
+        aa = "add -A .";
+        br = "branch";
+        c = "commit -S";
+        ca = "commit -S --amend";
+        cb = "checkout -b";
+        co = "checkout";
+        d = "diff";
+        l =
+          "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
+      };
+
+      delta = {
+        enable = true;
+
+        options = {
+          features = "line-numbers decorations";
+          whitespace-error-style = "22 reverse";
+          plus-style = "green bold ul '#198214'";
+          decorations = {
+            commit-decoration-style = "bold yellow box ul";
+            file-style = "bold yellow ul";
+            file-decoration-style = "none";
+          };
+        };
+      };
+
+      extraConfig = {
+        push = { default = "current"; };
+        pull = { rebase = true; };
+      };
+
+    };
+
+    starship = {
+      enable = true;
+      enableZshIntegration = true;
+
+      settings = {
+        add_newline = false;
+        scan_timeout = 10;
+      };
+    };
+
+    zsh = {
+      enable = true;
+      enableAutosuggestions = true;
+      enableSyntaxHighlighting = true;
+      history.size = 1000000;
+
+      localVariables = {
+        CASE_SENSITIVE = "true";
+        DISABLE_UNTRACKED_FILES_DIRTY = "true";
+        RPROMPT = ""; # override because macOS defaults to filepath
+        ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE = "fg=#838383,underline";
+        ZSH_DISABLE_COMPFIX = "true";
+      };
+
+      initExtra = ''
+        export PAGER=less
+      '';
+
+      shellAliases = {
+        ".." = "cd ..";
+        grep = "rg --smart-case";
+        ls = "exa -la --git";
+      };
+
+      "oh-my-zsh" = {
+        enable = true;
+        plugins = [
+          "gitfast"
+          "last-working-dir"
+        ];
+      };
+
+    };
+
+  };
+}
+

Save the file and run:

home-manager switch
+

You should see another wave of /nix/store/* paths. The new configuration should now be active.

If you run zsh, you should see that you have starship and access to several other utils such as rg, fd, and exa.

This basic configuration above is also defining your ~/.config/git/config and .zshrc. If you already have either of these files, home-manager will complain about them already existing.

If you run cat ~/.zshrc, you will see the way these configuration files are generated.

You can extend this configuration for programs such as (neo)vim, emacs, alacritty, ssh, etc. To see other programs, take a look at home-manager/modules/programs.

Gateway To Nix

In ways, home-manager can be seen as a gateway to the nix ecosystem. If you have enjoyed the way you can declare user configuration with home-manager, you may be interested in expanding your configuration to include other system dependencies and configuration. For example, in Linux you can define your entire system’s configuration (including the kernel, kernel modules, networking, filesystems, etc) in nix. For macOS, there is nix-darwin that includes nix modules for configuring launchd, dock, and other preferences and services. You may also want to check out Nix Flakes: a more recent feature that allows you declare dependencies, and have them automatically pinned and hashed in flake.lock, similar to that of many modern package managers.

Wrapping up

The title of this post is slightly misleading, since it’s possible to retain some of your dotfiles and have them intermingle with home-manager by including them alongside nix. The idea of defining user configuration using nix can provide a clean way to maintain your configuration, and allow it to be portable across platforms. Is it worth the effort to migrate away from shell scripts and dotfiles? I’d say so.

\ No newline at end of file diff --git a/public/blog/2021/09/17/automatically-rotating-aws-access-keys/index.html b/public/blog/2021/09/17/automatically-rotating-aws-access-keys/index.html index c8778dd6..40d493df 100644 --- a/public/blog/2021/09/17/automatically-rotating-aws-access-keys/index.html +++ b/public/blog/2021/09/17/automatically-rotating-aws-access-keys/index.html @@ -1,202 +1,14 @@ - - - - Automatically rotating AWS access keys - davegallant - - - - - - - - +Automatically rotating AWS access keys +
+

Automatically rotating AWS access keys

Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background.

In the longer term, migrating my local workflows to aws-vault seems like a more secure solution. This would mean that credentials (even temporary session credentials) never have to be written in plaintext to disk (i.e. where AWS suggests). Any existing applications, such as terraform, could be have their credentials passed to them from aws-vault, which retrieves them from the OS’s secure keystore. There is even a rotate command included.

\ No newline at end of file diff --git a/public/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/index.html b/public/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/index.html index b16bdc51..226a1d11 100644 --- a/public/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/index.html +++ b/public/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/index.html @@ -1,286 +1,52 @@ - - - - Replacing docker with podman on macOS (and Linux) - davegallant - - - - - - - - +Replacing docker with podman on macOS (and Linux) +
+

Replacing docker with podman on macOS (and Linux)

There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker:

Docker has been one of the larger influencers in the container world, helping to standardize the OCI Image Format Specification. For many developers, containers have become synonymous with terms like docker and Dockerfile (a file containing build instructions for a container image). Docker has certainly made it very convenient to build and run containers, but it is not the only solution for doing so.

This post briefly describes my experience swapping out docker for podman on macOS.

What is a container?

A container is a standard unit of software that packages up all application dependencies within it. Multiple containers can be run on a host machine all sharing the same kernel as the host. Linux namespaces help provide an isolated view of the system, including mnt, pid, net, ipc, uid, cgroup, and time. There is an in-depth video that discusses what containers are made from, and near the end there is a demonstration on how to build your own containers from the command line.

By easily allowing the necessary dependencies to live alongside the application code, containers make the “works on my machine” problem less of a problem.

Benefits of Podman

One of the most interesting features of Podman is that it is daemonless. There isn’t a process running on your system managing your containers. In contrast, the docker client is reliant upon the docker daemon (often running as root) to be able to build and run containers.

Podman is rootless by default. It is now possible to run the docker daemon rootless as well, but it’s still not the default behaviour.

I’ve also observed that so far my 2019 16" Macbook Pro hasn’t sounded like a jet engine, although I haven’t performed any disk-intensive operations yet.

Installing Podman

Running Podman on macOS is more involved than on Linux, because the podman-machine must run Linux inside of a virtual machine. Fortunately, the installation is made simple with brew (read this if you’re installing Podman on Linux):

brew install podman
+

The podman-machine must be started:

# This is not necessary on Linux
+podman machine init
+podman machine start
+

Running a container

Let’s try to pull an image:

$ podman pull alpine
+Trying to pull docker.io/library/alpine:latest...
+Getting image source signatures
+Copying blob sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e
+Copying config sha256:14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab
+Writing manifest to image destination
+Storing signatures
+14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab
+

If you’re having an issue pulling images, you may need to remove ~/.docker/config.json or remove the set of auths in the configuration as mentioned here.

and then run and exec into the container:

$ podman run --rm -ti alpine
+Error: error preparing container 99ace1ef8a78118e178372d91fd182e8166c399fbebe0f676af59fbf32ce205b for attach: error configuring network namespace for container 99ace1ef8a78118e178372d91fd182e8166c399fbebe0f676af59fbf32ce205b: error adding pod unruffled_bohr_unruffled_bohr to CNI network "podman": unexpected end of JSON input
+

What does this error mean? A bit of searching lead to this github issue.

Until the fix is released, a workaround is to just specify a port (even when it’s not needed):

podman run -p 4242 --rm -ti alpine
+

If you’re reading this from the future, there is a good chance specifying a port won’t be needed.

Another example of running a container with Podman can be found in the Jellyfin Documentation.

Aliasing docker with podman

Force of habit (or other scripts) may have you calling docker. To work around this:

alias docker=podman
+

podman-compose

You may be wondering: what about docker-compose? Well, there claims to be a drop-in replacement for it: podman-compose.

pip3 install --user podman-compose
+

Now let’s create a docker-compose.yml file to test:

cat << EOF >> docker-compose.yml
+version: '2'
+services:
+  hello_world:
+    image: ubuntu
+    command: [/bin/echo, 'Hello world']
+EOF
+

Now run:

$ podman-compose up
+podman pod create --name=davegallant.github.io --share net
+40d61dc6e95216c07d2b21cea6dcb30205bfcaf1260501fe652f05bddf7e595e
+0
+podman create --name=davegallant.github.io_hello_world_1 --pod=davegallant.github.io -l io.podman.compose.config-hash=123 -l io.podman.compose.project=davegallant.github.io -l io.podman.compose.version=0.0.1 -l com.docker.compose.container-number=1 -l com.docker.compose.service=hello_world --add-host hello_world:127.0.0.1 --add-host davegallant.github.io_hello_world_1:127.0.0.1 ubuntu /bin/echo Hello world
+Resolved "ubuntu" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
+Trying to pull docker.io/library/ubuntu:latest...
+Getting image source signatures
+Copying blob sha256:f3ef4ff62e0da0ef761ec1c8a578f3035bef51043e53ae1b13a20b3e03726d17
+Copying blob sha256:f3ef4ff62e0da0ef761ec1c8a578f3035bef51043e53ae1b13a20b3e03726d17
+Copying config sha256:597ce1600cf4ac5f449b66e75e840657bb53864434d6bd82f00b172544c32ee2
+Writing manifest to image destination
+Storing signatures
+1a68b2fed3fdf2037b7aef16d770f22929eec1d799219ce30541df7876918576
+0
+podman start -a davegallant.github.io_hello_world_1
+Hello world
+

This should more or less provide the same results you would come to expect with docker. The README does clearly state that podman-compose is under development.

Summary

Installing Podman on macOS was not seamless, but it was manageable well within 30 minutes. I would recommend giving Podman a try to anyone who is unhappy with experiencing forced docker updates, or who is interested in using a more modern technology for running containers.

One caveat to mention is that there isn’t an official graphical user interface for Podman, but there is an open issue considering one. If you rely heavily on Docker Desktop’s UI, you may not be as interested in using podman yet.

Update: After further usage, bind mounts do not seem to work out of the box when the client and host are on different machines. A rather involved solution using sshfs was shared here.

I had been experimenting with Podman on Linux before writing this, but after listening to this podcast episode, I was inspired to give Podman a try on macOS.

\ No newline at end of file diff --git a/public/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/index.html b/public/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/index.html index 83b7b482..746297ba 100644 --- a/public/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/index.html +++ b/public/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/index.html @@ -1,286 +1,53 @@ - - - - Running K3s in LXC on Proxmox - davegallant - - - - - - - - +Running K3s in LXC on Proxmox +
+

Running K3s in LXC on Proxmox

It has been a while since I’ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I’ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it’d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. LXC containers also provide an efficient way to use a machine’s resources.

What is K3s?

K3s is a Kubernetes distro that advertises itself as a lightweight binary with a much smaller memory-footprint than traditional k8s. K3s is not a fork of k8s as it seeks to remain as close to upstream as it possibly can.

Configure Proxmox

This gist contains snippets and discussion on how to deploy K3s in LXC on Proxmox. It mentions that bridge-nf-call-iptables should be loaded, but I did not understand the benefit of doing this.

Disable swap

There is an issue on Kubernetes regarding swap here. There claims to be support for swap in 1.22, but for now let’s disable it:

sudo sysctl vm.swappiness=0
+sudo swapoff -a
+

It might be worth experimenting with swap enabled in the future to see how that might affect performance.

Enable IP Forwarding

To avoid IP Forwarding issues with Traefik, run the following on the host:

sudo sysctl net.ipv4.ip_forward=1
+sudo sysctl net.ipv6.conf.all.forwarding=1
+sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
+sudo sed -i 's/#net.ipv6.conf.all.forwarding=1/net.ipv6.conf.all.forwarding=1/g' /etc/sysctl.conf
+

Create LXC container

Create an LXC container in the Proxmox interface as you normally would. Remember to:

  • Uncheck unprivileged container
  • Use a LXC template (I chose a debian 11 template downloaded with pveam)
  • In memory, set swap to 0
  • Create and start the container

Modify container config

Now back on the host run pct list to determine what VMID it was given.

Open /etc/pve/lxc/$VMID.conf and append:

lxc.apparmor.profile: unconfined
+lxc.cap.drop:
+lxc.mount.auto: "proc:rw sys:rw"
+lxc.cgroup2.devices.allow: c 10:200 rwm
+

All of the above configurations are described in the manpages. +Notice that cgroup2 is used since Proxmox VE 7.0 has switched to a pure cgroupv2 environment.

Thankfully cgroup v2 support has been supported in k3s with these contributions:

Enable shared host mounts

From within the container, run:

echo '#!/bin/sh -e
+ln -s /dev/console /dev/kmsg
+mount --make-rshared /' > /etc/rc.local
+chmod +x /etc/rc.local
+reboot
+

Install K3s

One of the simplest ways to install K3s on a remote host is to use k3sup. Ensure that you supply a valid CONTAINER_IP and choose the k3s-version you prefer. -As of 2021/11, it is still defaulting to the 1.19 channel, so I overrode it to 1.22 for cgroup v2 support. See the published releases here.

-
ssh-copy-id root@$CONTAINER_IP
-k3sup install --ip $CONTAINER_IP --user root --k3s-version v1.22.3+k3s1
-

If all goes well, you should see a path to the kubeconfig generated. I moved this into ~/.kube/config so that kubectl would read this by default.

-

Wrapping up#

-

Installing K3s in LXC on Proxmox works with a few tweaks to the default configuration. I later followed the Tekton’s Getting Started guide and was able to deploy it in a few commands.

-
$ kubectl get all --namespace tekton-pipelines
-NAME                                               READY   STATUS    RESTARTS      AGE
-pod/tekton-pipelines-webhook-8566ff9b6b-6rnh8      1/1     Running   1 (50m ago)   12h
-pod/tekton-dashboard-6bf858f977-qt4hr              1/1     Running   1 (50m ago)   11h
-pod/tekton-pipelines-controller-69fd7498d8-f57m4   1/1     Running   1 (50m ago)   12h
-
-NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                              AGE
-service/tekton-pipelines-controller   ClusterIP   10.43.44.245    <none>        9090/TCP,8080/TCP                    12h
-service/tekton-pipelines-webhook      ClusterIP   10.43.183.242   <none>        9090/TCP,8008/TCP,443/TCP,8080/TCP   12h
-service/tekton-dashboard              ClusterIP   10.43.87.97     <none>        9097/TCP                             11h
-
-NAME                                          READY   UP-TO-DATE   AVAILABLE   AGE
-deployment.apps/tekton-pipelines-webhook      1/1     1            1           12h
-deployment.apps/tekton-dashboard              1/1     1            1           11h
-deployment.apps/tekton-pipelines-controller   1/1     1            1           12h
-
-NAME                                                     DESIRED   CURRENT   READY   AGE
-replicaset.apps/tekton-pipelines-webhook-8566ff9b6b      1         1         1       12h
-replicaset.apps/tekton-dashboard-6bf858f977              1         1         1       11h
-replicaset.apps/tekton-pipelines-controller-69fd7498d8   1         1         1       12h
-
-NAME                                                           REFERENCE                             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
-horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook   Deployment/tekton-pipelines-webhook   9%/100%   1         5         1          12h
-

I made sure to install Tailscale in the container so that I can easily access K3s from anywhere.

-

If I’m feeling adventurous, I might experiment with K3s rootless.

- - - - - - - -
-
- -
-
-
-
-
-
- - - - -
- - +As of 2021/11, it is still defaulting to the 1.19 channel, so I overrode it to 1.22 for cgroup v2 support. See the published releases here.

ssh-copy-id root@$CONTAINER_IP
+k3sup install --ip $CONTAINER_IP --user root --k3s-version v1.22.3+k3s1
+

If all goes well, you should see a path to the kubeconfig generated. I moved this into ~/.kube/config so that kubectl would read this by default.

Wrapping up

Installing K3s in LXC on Proxmox works with a few tweaks to the default configuration. I later followed the Tekton’s Getting Started guide and was able to deploy it in a few commands.

$ kubectl get all --namespace tekton-pipelines
+NAME                                               READY   STATUS    RESTARTS      AGE
+pod/tekton-pipelines-webhook-8566ff9b6b-6rnh8      1/1     Running   1 (50m ago)   12h
+pod/tekton-dashboard-6bf858f977-qt4hr              1/1     Running   1 (50m ago)   11h
+pod/tekton-pipelines-controller-69fd7498d8-f57m4   1/1     Running   1 (50m ago)   12h
+
+NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                              AGE
+service/tekton-pipelines-controller   ClusterIP   10.43.44.245    <none>        9090/TCP,8080/TCP                    12h
+service/tekton-pipelines-webhook      ClusterIP   10.43.183.242   <none>        9090/TCP,8008/TCP,443/TCP,8080/TCP   12h
+service/tekton-dashboard              ClusterIP   10.43.87.97     <none>        9097/TCP                             11h
+
+NAME                                          READY   UP-TO-DATE   AVAILABLE   AGE
+deployment.apps/tekton-pipelines-webhook      1/1     1            1           12h
+deployment.apps/tekton-dashboard              1/1     1            1           11h
+deployment.apps/tekton-pipelines-controller   1/1     1            1           12h
+
+NAME                                                     DESIRED   CURRENT   READY   AGE
+replicaset.apps/tekton-pipelines-webhook-8566ff9b6b      1         1         1       12h
+replicaset.apps/tekton-dashboard-6bf858f977              1         1         1       11h
+replicaset.apps/tekton-pipelines-controller-69fd7498d8   1         1         1       12h
+
+NAME                                                           REFERENCE                             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
+horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook   Deployment/tekton-pipelines-webhook   9%/100%   1         5         1          12h
+

I made sure to install Tailscale in the container so that I can easily access K3s from anywhere.

If I’m feeling adventurous, I might experiment with K3s rootless.

\ No newline at end of file diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/index.html b/public/blog/2022/03/13/backing-up-gmail-with-synology/index.html index a6ed051a..1f190e78 100644 --- a/public/blog/2022/03/13/backing-up-gmail-with-synology/index.html +++ b/public/blog/2022/03/13/backing-up-gmail-with-synology/index.html @@ -1,222 +1,12 @@ - - - - Backing up gmail with Synology - davegallant - - - - - - - - +Backing up gmail with Synology +
+

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

The thought of completely de-googling has crossed my mind on occassion. Convenience, coupled with my admiration for Google engineering, has prevented me from doing so thus far. Though, I may end up doing so at some point in the future.

Synology MailPlus Server

Synology products are reasonably priced for what you get (essentially a cloud-in-a-box) and there is very little maintenance required. I’ve recently been in interested in syncing and snapshotting my personal data. I’ve setup Synology’s Cloud Sync and keep copies of most of my cloud data.

I’ve used tools such as gmvault with success in the past. Setting this up on a cron seems like a viable option. However, I don’t really need a lot of the features it offers and do not plan to restore this data to another account.

Synology’s MailPlus seems to be a good candidate for backing up this data. By enabling POP3 fetching, it’s possible to fetch all existing emails, as well as periodically fetch all new emails. If a disaster ever did occur, having these emails would be beneficial, as they are an extension of my memory bank.

Installing MailPlus can be done from the Package Center:

image

Next, I went into Synology MailPlus Server and on the left, clicked on Account and ensured my user was marked as active.

Afterwords, I followed these instructions in order to start backing up emails.

When entering the POP3 credentials, I created an app password solely for authenticating to POP3 from the Synology device. This is required because I have 2-Step verification enabled on my account. There doesn’t seem to be a more secure way to access POP3 at the moment. It does seem like app password access is limited in scope (when MFA is enabled). These app passwords can’t be used to login to the main Google account.

I made sure to set the Fetch Range to All in order to get all emails from the beginning of time.

After this, mail started coming in.

image

After fetching 19 years worth of emails, I tried searching for some emails. It only took a few seconds to search through ~50K emails, which is a relief if I ever did have to search for something important.

Securing Synology

Since Synology devices are not hermetically sealed, it’s best to secure them by enabling MFA to help prevent being the victim of ransomware. It is also wise to backup your system settings and volumes to the cloud using a tool such as Hyper Backup. +Encrypting your shared volumes should also be done, since unfortunately DSM does not support full disk encryption.

Summary

Having backups of various forms of cloud data is a good investment, especially in times of war. I certainly feel more at ease for having backed up my emails.

\ No newline at end of file diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_box_3.png b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_box_3.png new file mode 100644 index 00000000..5373c34b Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_box_3.png differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..5ea140f1 Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_box_3.png b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_box_3.png new file mode 100644 index 00000000..05ee5597 Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_box_3.png differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f39a5534 Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_box_3.png b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_box_3.png new file mode 100644 index 00000000..1c62a854 Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_box_3.png differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..c66a5f9f Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_box_3.png b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_box_3.png new file mode 100644 index 00000000..03ab2b69 Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_box_3.png differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..4ce13bd4 Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_box_3.png b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_box_3.png new file mode 100644 index 00000000..09b76aca Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_box_3.png differ diff --git a/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_q75_h2_box_3.webp b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..538df32a Binary files /dev/null and b/public/blog/2022/03/13/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/index.html b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/index.html index 644d223d..31ae4dc8 100644 --- a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/index.html +++ b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/index.html @@ -1,244 +1,12 @@ - - - - Virtualizing my router with pfSense - davegallant - - - - - - - - +Virtualizing my router with pfSense +
+

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

pfSense

I figured this would be a good opportunity to try pfSense. I’ve heard nothing but positive things about pfSense and the fact it’s been around since 2004, based on FreeBSD, and written in PHP gave me the impression that it would be relatively stable (and I’d expect nothing less because it has an important job to do!). pfSense can be run on many different machines, and there are even some officially supported appliances. Since I already have a machine running Proxmox, why not just run it in a VM? It’d allow for automatic snapshotting of the machine. There is a good video on this by Techno Tim. Tim has a lot of good videos, and this one is about virtualizing pfSense.

Router on a stick

I had initially made the assumption that in order to build a router, you would need more than a single NIC (or a dual-port NIC) in order to support both WAN and LAN. This is simply not the case, because VLANs are awesome! In order to create a router, all you need is a single port NIC and a network switch that supports VLANs (also marketed as a managed switch). I picked up the Netgear GS308E because it has both a sufficient amount of ports for my needs, and it supports VLANs. It also has a nice sturdy metal frame which was a pleasant surprise.

After setting up this Netgear switch, it shoud be possible to access the web interface at http://192.168.0.239. It may be at a different address. To find the address, try checking your DHCP leases in your router interface (if you plugged it into an existing router). I realized I was unable to access this interface because I was on a different subnet, so I set my machine’s address to 192.168.0.22 in order to temporarily setup this switch. I assigned a static ip address to the switch (in System > Switch Information) so that it was in the same subnet as the rest of my network.

The web interface is nothing spectactular, but it allows for managing VLANs.

The following configuration will:

  • assign port 1 to be the LAN (connected to the Proxmox machine)
  • assign port 8 to be the WAN (connected to my ISP’s modem)

In the switch’s web interface, I went to VLAN and then 802.1Q, and then clicked on VLAN Configuration. I configured the ports to look like this:

vlan-config

Note that the VLAN Identifier Setting has been setup already with two VLANs (1 and 10). More VLANs can be created (i.e. to isolate IoT devices), but 2 VLANs is all we need for the initial setup of a router.

To replicate the above configuration, add a new VLAN ID 10 (1 should exist by default).

Next, go into VLAN Membership and configure VLAN 1’s port membership to be the following:

vlan-membership-1

and then configure VLAN 10’s port membership to be the following:

vlan-membership-10

Now, go into Port PVID and ensure that port 8 is set to PVID 10.

vlan-port-pvid

This above configuration will dedicate two of the eight ports to WAN and LAN. This will allow the internet to flow into the pfSense from the modem.

Setting up pfSense

pfSense is fairly easy to setup. Just download the latest ISO and boot up the virtual machine. +When setting up the machine, I mostly went with all of the defaults. Configuration can be changed later in the web interface, which is quite a bit simpler.

Since VLANs are going to be leveraged, when you go to Assign Interfaces, VLANs should be setup now like the following:

  • WAN should be vtnet0.10
  • LAN should be vtnet0

After going through the rest of the installation, if everything is connected correctly it should display both WAN and LAN addresses.

If all goes well, the web interface should be running at https://192.168.1.1.

pfsense-dashboard

And this is where the fun begins. There are many tutorials and blogs about how to setup pfSense and various services and packages that can be installed. I’ve already installed pfBlocker-NG.

Summary

It is fairly simple to setup a router with pfSense from within a virtual machine. A physical dedicated routing machine is not necessary and often does not perform as well as software running on faster and more reliable hardware. So far, pfSense has been running for over a week without a single hiccup. pfSense is a mature piece of software that is incredibly powerful and flexible. To avoid some of the instability I had experienced with OpenWrt, I enabled AutoConfigBackup, which is capable of automatically backing up configuration upon every change. I plan to explore and experiment with more services and configuration in the future, so the ability to track all of these changes gives me the peace of mind that experimentation is safe.

\ No newline at end of file diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_box_3.png new file mode 100644 index 00000000..2d9fa4f3 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..dfe254af Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_box_3.png new file mode 100644 index 00000000..75f3d1d1 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..57242a9e Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_box_3.png new file mode 100644 index 00000000..28d24643 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..49d34094 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_box_3.png new file mode 100644 index 00000000..147da493 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f6eec9f9 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_box_3.png new file mode 100644 index 00000000..7fe7e802 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..3247b7f4 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_box_3.png new file mode 100644 index 00000000..becd0d9f Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f85294b9 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_box_3.png new file mode 100644 index 00000000..69ca855a Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..85f43eff Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_box_3.png new file mode 100644 index 00000000..94c74632 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..be088172 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_box_3.png new file mode 100644 index 00000000..afca5534 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..358db32c Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_box_3.png new file mode 100644 index 00000000..14342de1 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..acdb932d Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_box_3.png new file mode 100644 index 00000000..3bc3f3dc Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..568aaf9d Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_box_3.png new file mode 100644 index 00000000..1cce7e4b Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..fa67542b Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_box_3.png new file mode 100644 index 00000000..be30375c Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..1b524eb7 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_box_3.png new file mode 100644 index 00000000..044410f4 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..5925df7f Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_box_3.png b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_box_3.png new file mode 100644 index 00000000..6029089f Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_box_3.png differ diff --git a/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..9645bb15 Binary files /dev/null and b/public/blog/2022/04/02/virtualizing-my-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_box_3.png b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_box_3.png new file mode 100644 index 00000000..3682cacc Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_box_3.png differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f793d980 Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_box_3.png b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_box_3.png new file mode 100644 index 00000000..e50e46f3 Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_box_3.png differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..76f01642 Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_box_3.png b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_box_3.png new file mode 100644 index 00000000..f1e813c6 Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_box_3.png differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..d2cdafbf Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/index.html b/public/blog/2022/12/10/watching-youtube-in-private/index.html index 320fb8c6..0983de46 100644 --- a/public/blog/2022/12/10/watching-youtube-in-private/index.html +++ b/public/blog/2022/12/10/watching-youtube-in-private/index.html @@ -1,267 +1,51 @@ - - - - Watching YouTube in private - davegallant - - - - - - - - +Watching YouTube in private +
+

Watching YouTube in private

I recently stumbled upon yewtu.be and found it intriguing. It not only allows you to watch YouTube without being on YouTube, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it’s a hosted instance of invidious.

image

The layout is simple, and JavaScript is not required.

I started using yewtu.be as my primary client for watching videos. I subscribe to several YouTube channels and I prefer the interface invidiuous provides due to its simplicity. It’s also nice to be in control of my search and watch history.

A few days ago, yewtu.be went down briefly, and that motivated me enough to self-host invidious. There are several other hosted instances listed here, but being able to easily backup my own instance (including subscriptions and watch history) is more compelling in my case.

Hosting invidious

The quickest way to get invidious up is with docker-compose as mentioned in the docs.

I made a few modifications, and ended up with:

version: "3"
+services:
+  invidious:
+    image: quay.io/invidious/invidious
+    restart: unless-stopped
+    ports:
+      - "0.0.0.0:3000:3000"
+    environment:
+      INVIDIOUS_CONFIG: |
+        db:
+          dbname: invidious
+          user: kemal
+          password: kemal
+          host: invidious-db
+          port: 5432
+        check_tables: true        
+    healthcheck:
+      test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/comments/jNQXAC9IVRw || exit 1
+      interval: 30s
+      timeout: 5s
+      retries: 2
+    depends_on:
+      - invidious-db
+
+  invidious-db:
+    image: docker.io/library/postgres:14
+    restart: unless-stopped
+    volumes:
+      - postgresdata:/var/lib/postgresql/data
+      - ./config/sql:/config/sql
+      - ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
+    environment:
+      POSTGRES_DB: invidious
+      POSTGRES_USER: kemal
+      POSTGRES_PASSWORD: kemal
+    healthcheck:
+      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
+
+volumes:
+  postgresdata:
+

After invidious was up and running, I installed Tailscale on it to leverage its MagicDNS, and I’m now able to access this instance from anywhere at http://invidious:3000/feed/subscriptions.

I figured it would be nice to redirect existing YouTube links that others send me, so that I could seamlessly watch the videos using invidious.

I went looking for a way to redirect paths at the browser level. I found the lightweight proxy requestly, which can be used to modify http requests in my browser. I created the following rules:

requestly

Now the link https://www.youtube.com/watch?v=-lz30by8-sU will redirect to http://invidious:3000/watch?v=-lz30by8-sU

I’m still looking for ways to improve this invidious setup. There doesn’t appear to be a way to stream in 4K yet.

\ No newline at end of file diff --git a/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_box_3.png b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_box_3.png new file mode 100644 index 00000000..a2b4db08 Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_box_3.png differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_q75_h2_box_3.webp b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..48af65a9 Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_box_3.png b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_box_3.png new file mode 100644 index 00000000..fdcb6cca Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_box_3.png differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_q75_h2_box_3.webp b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..39e8d85b Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_box_3.png b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_box_3.png new file mode 100644 index 00000000..d999a497 Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_box_3.png differ diff --git a/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_q75_h2_box_3.webp b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..d024bbfb Binary files /dev/null and b/public/blog/2022/12/10/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/index.html b/public/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/index.html index 41ee0345..efd4f436 100644 --- a/public/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/index.html +++ b/public/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/index.html @@ -1,260 +1,20 @@ - - - - Using AKS and SOCKS to connect to a private Azure DB - davegallant - - - - - - - - +Using AKS and SOCKS to connect to a private Azure DB +
+

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Go Public?

Should the database be migrated to public subnets? Ideally not, since it is good practice to host internal infrastructure in restricted subnets.

How do others handle this?

With GCP, connecting to a private db instance from any machine can be achieved with cloud-sql-proxy. This works by proxying requests from your machine to the SQL database instance in the cloud, while the authentication is handled by GCP’s IAM.

So what about Azure? Is there any solution that is as elegant as cloud-sql-proxy?

A Bastion

Similar to what AWS has recommended, perhaps a bastion is the way forward?

Azure has a fully-managed service called Azure Bastion that provides secure access to virtual machines that do not have public IPs. This looks interesting, but unfortunately it costs money and requires an additional virtual machine.

Because this adds cost (and complexity), it does not seem like a desirable option in its current state. If it provided a more seamless connection to the database, it would be more appealing.

SOCKS

2023-12-13: +An alternative to using a socks proxy is socat. This would allow you to relay tcp connections to a pod running in k8s, and then port-forward them to your localhost. +If this sounds more appealing, install krew-net-forward and then run “kubectl net-forward -i mydb.postgres.database.azure.com -p 5432 -l 5432” to access the database through “localhost:5432”

SOCKS is a protocol that enables a way to proxy connections by exchanging network packets between the client and the server. There are many implementations and many readily available container images that can run a SOCKS server.

It’s possible to use this sort of proxy to connect to a private DB, but is it any simpler than using a virtual machine as a jumphost? It wasn’t until I stumbled upon kubectl-plugin-socks5-proxy that I was convinced that using SOCKS could be made simple.

So how does it work? By installing the kubectl plugin and then running kubectl socks5-proxy, a SOCKS proxy server is spun up in a pod and then opens up port-forwarding session using kubectl.

As you can see below, this k8s plugin is wrapped up nicely:

$ kubectl socks5-proxy
+using: namespace=default
+using: port=1080
+using: name=davegallant-proxy
+using: image=serjs/go-socks5-proxy
+Creating SOCKS5 Proxy (Pod)...
+pod/davegallant-proxy created
+

With the above proxy connection open, it is possible to access both the DNS and private IPs accessible within the k8s cluster. In this case, I am able to access the private database, since there is network connectivity between the k8s cluster and the database.

Caveats and Conclusion

The above outlined solution makes some assumptions:

  • there is a k8s cluster
  • the k8s cluster has network connectivity to the desired private database

If these stars align, than this solution might work as a stopgap for accessing a private Azure DB (and I’m assuming this could work similarly on AWS).

It would be nice if Azure provided tooling similar to cloud-sql-proxy, so that using private databases would be more of a convenient experience.

One other thing to note is that some clients (such as dbeaver) do not provide DNS resolution over SOCKS. So in this case, you won’t be able to use DNS as if you were inside the cluster, but instead have to rely on knowing private ip addresses.

\ No newline at end of file diff --git a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_box_3.png b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_box_3.png new file mode 100644 index 00000000..d01addcb Binary files /dev/null and b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_box_3.png differ diff --git a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_q75_h2_box_3.webp b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..aadff9dd Binary files /dev/null and b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_box_3.png b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_box_3.png new file mode 100644 index 00000000..cb8e8661 Binary files /dev/null and b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_box_3.png differ diff --git a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_q75_h2_box_3.webp b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..2a9c9261 Binary files /dev/null and b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_box_3.png b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_box_3.png new file mode 100644 index 00000000..e262f78f Binary files /dev/null and b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_box_3.png differ diff --git a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_q75_h2_box_3.webp b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..81ee6417 Binary files /dev/null and b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_q75_h2_box_3.webp differ diff --git a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/index.html b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/index.html index 63f99b98..4d52f223 100644 --- a/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/index.html +++ b/public/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/index.html @@ -1,356 +1,117 @@ - - - - Setting up Gitea Actions with Tailscale - davegallant - - - - - - - - +Setting up Gitea Actions with Tailscale +
+

Setting up Gitea Actions with Tailscale

In this post I’ll go through the process of setting up Gitea Actions and Tailscale, unlocking a simple and secure way to automate workflows.

What is Gitea?

Gitea is a lightweight and fast git server that has much of the same look and feel as github. I have been using it in my homelab to mirror repositories hosted on other platforms such as github and gitlab. These mirrors take advantage of the decentralized nature of git by serving as “backups”. One of the main reasons I hadn’t been using it more often was due to the lack of integrated CI/CD. This is no longer the case.

Gitea Actions

Gitea Actions have made it into the 1.19.0 release. This feature had been in an experimental state up until 1.21.0 and is now enabled by default 🎉.

So what are they? If you’ve ever used GitHub Actions (and if you’re reading this, I imagine you have), these will look familiar. Gitea Actions essentially enable the ability to run github workflows on gitea. Workflows between gitea and github are not completely interopable, but a lot of the same workflow syntax is already compatible on gitea. You can find a documented list of unsupported workflows syntax.

Actions work by using a custom fork of nekos/act. Workflows run in a new container for every job. If you specify an action such as ‘actions/checkout@v3’, it defaults to downloading the scripts from github.com. To avoid internet egress, you could always clone the required actions to your local gitea instance.

Actions (gitea’s implementation) has me excited because it makes spinning up a network-isolated environment for workflow automation incredibly simple.

Integration with Tailscale

So how does Tailscale help here? Well, more recently I’ve been exposing my self-hosted services through a combination of traefik and the tailscale (through the tailscale-traefik proxy integration described here). This allows for a nice looking dns name (i.e. gitea.my-tailnet-name.ts.net) and automatic tls certificate management. I can also share this tailscale node securely with other tailscale users without configuring any firewall rules on my router.

Deploying Gitea, Traefik, and Tailscale

In my case, the following is already set up:

My preferred approach to deploying code in a homelab environment is with docker compose. I have deployed this in a proxmox lxc container based on debian with a hostname gitea. This could be deployed in any environment and with any hostname (as long you updated the tailscale machine name to your preferred subdomain for magic dns).

The docker-compose.yaml file looks like:

version: "3.7"
+services:
+  gitea:
+    image: gitea/gitea:1.21.1
+    container_name: gitea
+    environment:
+      - USER_UID=1000
+      - USER_GID=1000
+
+      - GITEA__server__DOMAIN=gitea.my-tailnet-name.ts.net
+      - GITEA__server__ROOT_URL=https://gitea.my-tailnet-name.ts.net
+      - GITEA__server__HTTP_ADDR=0.0.0.0
+      - GITEA__server__LFS_JWT_SECRET=my-secret-jwt
+    restart: always
+    volumes:
+      - ./data:/data
+      - /etc/timezone:/etc/timezone:ro
+      - /etc/localtime:/etc/localtime:ro
+  traefik:
+    image: traefik:v3.0.0-beta4
+    container_name: traefik
+    security_opt:
+      - no-new-privileges:true
+    restart: unless-stopped
+    ports:
+      - 80:80
+      - 443:443
+    volumes:
+      - ./traefik/data/traefik.yaml:/traefik.yaml:ro
+      - ./traefik/data/dynamic.yaml:/dynamic.yaml:ro
+      - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
+

traefik/data/traefik.yaml:

entryPoints:
+  https:
+    address: ":443"
+providers:
+  file:
+    filename: dynamic.yaml
+certificatesResolvers:
+  myresolver:
+    tailscale: {}
+log:
+  level: INFO
+

and finally traefik/data/dynamic/dynamic.yaml:

http:
+  routers:
+    gitea:
+      rule: Host(`gitea.my-tailnet-name.ts.net`)
+      entrypoints:
+        - "https"
+      service: gitea
+      tls:
+        certResolver: myresolver
+  services:
+    gitea:
+      loadBalancer:
+        servers:
+          - url: "http://gitea:3000"
+

Something to consider is whether or not you want to use ssh with git. One method to get this to work with containers is to use ssh container passthrough. I decided to keep it simple and not use ssh, since communicating over https is perfectly fine for my use case.

After adding the above configuration, running docker compose up -d should be enough to get an instance up and running. It will be accessible at https://gitea.my-tailnet-name.ts.net from within the tailnet.

Connecting a Runner

I installed the runner by following the docs. I opted for installing it on a separate host (another lxc container) as recommended in the docs. I used the systemd unit file to ensure that the runner comes back online after system reboots. I installed tailscale on this gitea runner as well, so that it can have the same “networking privileges” as the main instance.

After registering this runner and starting the daemon, it appeared in /admin/actions/runners:

image

Running a workflow

Now it’s time start running some automation. I used the demo workflow as a starting point to verify that the runner is executing workflows.

After this, I wanted to make sure that some of my existing workflows could be migrated over.

The following workflow uses a matrix to run a job for several of my hosts using ansible playbooks that will do various tasks such as patching os updates and updating container images.

name: Run ansible
+on:
+  push:
+  schedule:
+    - cron: "0 */12 * * *"
+
+jobs:
+  run-ansible-playbook:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        host:
+          - changedetection
+          - homelab
+          - invidious
+          - jackett
+          - ladder
+          - miniflux
+          - plex
+          - qbittorrent
+          - tailscale-exit-node
+          - uptime-kuma
+    steps:
+      - name: Check out repository code
+        uses: actions/checkout@v4
+      - name: Install ansible
+        run: |
+          apt update && apt install ansible -y          
+      - name: Run playbook
+        uses: dawidd6/action-ansible-playbook@v2
+        with:
+          playbook: playbooks/main.yml
+          requirements: requirements.yml
+          options: |
+            --inventory inventory
+            --limit ${{ matrix.host }}            
+      - name: Send failure notification
+        uses: dawidd6/action-send-mail@v3
+        if: always() && failure()
+        with:
+          server_address: smtp.gmail.com
+          server_port: 465
+          secure: true
+          username: myuser
+          password: ${{ secrets.MAIL_PASSWORD }}
+          subject: ansible runbook '${{ matrix.host }}' failed
+          to: me@davegallant.ca
+          from: RFD Notify
+          body: |
+            ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}            
+

And voilà:

You may be wondering how the gitea runner is allowed to connect to the other hosts using ansible? Well, the nodes are in the same tailnet and have tailscale ssh enabled.

Areas for improvement

One enhancement that I would like to see is the ability to send notifications on workflow failures. Currently, this doesn’t seem possible without adding logic to each workflow.

Conclusion

Gitea Actions are fast and the resource footprint is minimal. My gitea instance is currently using around 250mb of memory and a small fraction of a single cpu core (and the runner is using a similar amount of resources). This is impressive since many alternatives tend to require substantially more resources. It likely helps that the codebase is largely written in go.

By combining gitea with the networking marvel that is tailscale, running workflows becomes simple and fun. Whether you are working on a team or working alone, this setup ensures that your workflows are securely accessible from anywhere with an internet connection.

\ No newline at end of file diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 00000000..b82dfc5d --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #282828 + + + diff --git a/public/categories/index.html b/public/categories/index.html index 8a0756a0..d2c7b251 100644 --- a/public/categories/index.html +++ b/public/categories/index.html @@ -1,171 +1,10 @@ - - - - Categories - davegallant - - - - - - - +Categories +
+

Categories

\ No newline at end of file diff --git a/public/categories/index.xml b/public/categories/index.xml index 4be32f19..cafd74e3 100644 --- a/public/categories/index.xml +++ b/public/categories/index.xml @@ -1,12 +1 @@ - - - - Categories on davegallant - /categories/ - Recent content in Categories on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - - - +Categories onhttps://davegallant.ca/categories/Recent content in Categories onHugo -- gohugo.ioen-usDave Gallant \ No newline at end of file diff --git a/public/categories/page/1/index.html b/public/categories/page/1/index.html new file mode 100644 index 00000000..00816e01 --- /dev/null +++ b/public/categories/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/categories/ + \ No newline at end of file diff --git a/public/css/.gitkeep b/public/css/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/public/css/copy-code-button.min.css b/public/css/copy-code-button.min.css deleted file mode 100644 index a992b573..00000000 --- a/public/css/copy-code-button.min.css +++ /dev/null @@ -1 +0,0 @@ -.highlight-wrapper{display:block}.highlight-wrapper .lntd pre{padding:0}.chroma .lntd pre{border:0 solid #ccc}.chroma .lntd:first-child{padding:7px 7px 7px 10px;margin:0}.chroma .lntd:last-child{padding:7px 10px 7px 7px;margin:0}.highlight{position:relative;z-index:0;padding:0;margin:40px 0 10px;border-radius:4px}.highlight>.chroma{position:static;z-index:1;border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px;border-bottom-right-radius:4px;padding:10px}.copy-code-button{position:absolute;z-index:2;right:0;top:-29px;font-size:13px;font-weight:700;line-height:14px;letter-spacing:.5px;width:65px;color:#fff;background-color:#000;border:1.25px solid #232326;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;white-space:nowrap;padding:6px 6px 7px;margin:0 0 0 1px;cursor:pointer;opacity:.6}.copy-code-button:hover,.copy-code-button:focus,.copy-code-button:active,.copy-code-button:active:hover{color:#222225;background-color:#b3b3b3;opacity:.8}.copyable-text-area{position:absolute;height:0;z-index:-1;opacity:.01}.chroma [data-lang]:before{position:absolute;z-index:0;top:-29px;left:0;content:attr(data-lang);font-size:13px;font-weight:700;color:#fff;background-color:#000;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-left-radius:0;border-bottom-right-radius:0;padding:6px 6px 7px;line-height:14px;opacity:.6;position:absolute;letter-spacing:.5px;border:1.25px solid #232326;margin:0 0 0 1px} \ No newline at end of file diff --git a/public/css/custom.d96bfb9e3314a7699144ab6ae7331d424cbd7fb34a2e890b17e7bb7db4e30f3a.css b/public/css/custom.d96bfb9e3314a7699144ab6ae7331d424cbd7fb34a2e890b17e7bb7db4e30f3a.css deleted file mode 100644 index 5c8be984..00000000 --- a/public/css/custom.d96bfb9e3314a7699144ab6ae7331d424cbd7fb34a2e890b17e7bb7db4e30f3a.css +++ /dev/null @@ -1,15 +0,0 @@ -.hanchor { - visibility: hidden; - color: silver; - font-size: 100%; - transition: 0.2s; - padding-left: 8px; - font-weight: 600; -} - -h2:hover a, -h3:hover a, -h4:hover a { - visibility: visible; - text-decoration: none; -} diff --git a/public/css/dark.d61dc67f7e7db9e2fb71ee6e28efc53086daed613da0bbeb0ef66045420afd17.css b/public/css/dark.d61dc67f7e7db9e2fb71ee6e28efc53086daed613da0bbeb0ef66045420afd17.css deleted file mode 100644 index 6b651fde..00000000 --- a/public/css/dark.d61dc67f7e7db9e2fb71ee6e28efc53086daed613da0bbeb0ef66045420afd17.css +++ /dev/null @@ -1,153 +0,0 @@ -body { - color: white; - background-color: #202124; -} - -::-moz-selection { - background: blue; - color: #fff; - text-shadow: none; -} - -::selection { - background: rgb(212, 240, 32); - color: #000000; - text-shadow: none; -} - -hr { - border-top: 3px dotted blue; -} -code { - background-color: rgb(184, 189, 190); - color: black; - text-decoration: bold; - padding: 0em 0.1em; -} -pre { - background-color: #272822; - line-height: 1.4; - overflow-x: auto; - padding: 1em; -} -blockquote { - border-color: #ddd; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - color: #ddd; -} -h1::before { - color: var(--darkMaincolor); -} -h2::before { - color: var(--darkMaincolor); -} -h3::before { - color: var(--darkMaincolor); -} -h4::before { - color: var(--darkMaincolor); -} -h5::before { - color: var(--darkMaincolor); -} -h6::before { - color: var(--darkMaincolor); -} - -a { - border-bottom: 3px solid var(--darkMaincolor); - color: inherit; -} -a:hover { - background-color: var(--darkMaincolor); - color: black; -} - -.site-description a { - color: #ddd; -} -.site-description a:hover { - color: black; -} - -.tags a { - border-bottom: 3px solid var(--darkMaincolor); -} -.tags a:hover { - background-color: var(--darkMaincolor); - color: black; -} - -.site-title a { - color: white; - text-decoration: none !important; -} - -.header nav, -.footer { - border-color: #333; -} - -.highlight { - background-color: #333; -} -.soc:hover { - color: black; -} -.draft-label { - color: var(--darkMaincolor); - background-color: blue; -} -.highlight pre code[class="language-javaScript"]::before, -.highlight pre code[class="language-js"]::before { - content: "js"; - background: #f7df1e; - color: black; -} -.highlight pre code[class*="language-yml"]::before, -.highlight pre code[class*="language-yaml"]::before { - content: "yaml"; - background: #f71e6a; - color: white; -} -.highlight pre code[class*="language-shell"]::before, -.highlight pre code[class*="language-bash"]::before, -.highlight pre code[class*="language-sh"]::before { - content: "shell"; - background: rgb(118, 137, 118); - color: white; -} -.highlight pre code[class*="language-json"]::before { - content: "json"; - background: dodgerblue; - color: #000000; -} -.highlight pre code[class*="language-python"]::before, -.highlight pre code[class*="language-py"]::before { - content: "py"; - background: blue; - color: yellow; -} -.highlight pre code[class*="language-css"]::before { - content: "css"; - background: cyan; - color: black; -} -.highlight pre code[class*="language-go"]::before { - content: "Go"; - background: cyan; - color: royalblue; -} -.highlight pre code[class*="language-md"]::before, -.highlight pre code[class*="language-md"]::before { - content: "Markdown"; - background: royalblue; - color: whitesmoke; -} diff --git a/public/css/main.5ff68256cc04aa4360600458bf9767c053d7b990cfb09caa0724dd24045068c7.css b/public/css/main.5ff68256cc04aa4360600458bf9767c053d7b990cfb09caa0724dd24045068c7.css deleted file mode 100644 index ad5b32c6..00000000 --- a/public/css/main.5ff68256cc04aa4360600458bf9767c053d7b990cfb09caa0724dd24045068c7.css +++ /dev/null @@ -1,349 +0,0 @@ -/* Markdown */ -:root { - --maincolor: #a15bc2; - --bordercl: #a15bc2; - --callouctcolor: dodgerblue; - --hovercolor: #a15bc2; - --darkMaincolor: #a15bc2; -} -html { - color: #232333; - font-family: "Roboto Mono", monospace; - font-size: 18px; - line-height: 1.6em; -} -body { - display: block; - background-color: #f8f8f8; - margin: 8px; -} -* { - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -::selection { - background: #eef35c; - color: #000000; -} - -p { - font-family: "Roboto Light", sans-serif; - line-height: 1.5; -} - -hr { - border: 0; - border-top: 3px dotted var(--bordercl); - margin: 1em 0; -} - -blockquote { - border-left: 3px solid var(--bordercl); - color: #737373; - margin: 0; - padding-left: 1em; -} - -a { - border-bottom: 3px solid var(--maincolor); - color: inherit; - text-decoration: none; -} -a:hover { - background-color: var(--hovercolor); - color: #fff; -} - -ul { - list-style: none; - padding-left: 2ch; -} -ul li { - text-indent: -2ch; -} -ul > li::before { - content: "* "; - font-weight: bold; -} - -/* Images */ -img { - max-width: 100%; -} - -figure { - box-sizing: border-box; - display: inline-block; - margin: 0; - max-width: 100%; -} - -figure img { - max-height: 500px; -} - -@media screen and (min-width: 600px) { - figure { - padding: 0 40px; - } -} - -figure h4 { - font-size: 1rem; - margin: 0; - margin-bottom: 1em; -} -figure h4::before { - content: "↳ "; -} - -/* Code blocks */ -code { - background-color: #f1f1f1; - padding: 0em 0.1em; -} - -pre { - background-color: #ececec; - line-height: 1.4; - overflow-x: auto; - padding: 1em; -} - -.highlight pre ::selection { - background: var(--maincolor); - color: inherit; -} - -pre code { - background-color: transparent; - color: inherit; - font-size: 100%; - padding: 0; -} - -/* Containers */ -.content { - margin-bottom: 4em; - margin-left: auto; - margin-right: auto; - max-width: 800px; - padding: 0 1ch; - word-wrap: break-word; -} - -/* Header */ -header { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - margin: 1em 0; - line-height: 2.5em; -} - -header .main { - font-size: 1.5rem; -} -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: 1.2rem; - margin-top: 2em; -} - -h1::before { - color: var(--maincolor); -} -h2::before { - color: var(--maincolor); -} -h3::before { - color: var(--maincolor); -} -h4::before { - color: var(--maincolor); -} -h5::before { - color: var(--maincolor); -} -h6::before { - color: var(--maincolor); -} - -.meta { - color: #999; - letter-spacing: -0.5px; -} - -/* Footer */ -footer { - display: flex; - align-items: center; - border-top: 0.4rem dotted var(--bordercl); - padding: 2rem 0rem; - margin-top: 2rem; -} -.soc { - display: flex; - align-items: center; - border-bottom: none; -} -.border { - margin-left: 0.5rem; - margin-right: 0.5rem; - border: 1px solid; -} -.footer-info { - padding: var(--footer-padding); -} - -/* Common */ -.title h1 { - margin-bottom: 0; -} - -time { - color: grey; -} - -/* Posts */ -article .title { - margin-bottom: 1em; -} - -/* Callout */ -.callout { - background-color: var(--callouctcolor); - color: #fff; - padding: 1em; -} - -.callout p { - font-family: "IBM Plex Mono", monospace; - margin: 0; -} - -.callout a { - border-bottom: 3px solid #fff; -} - -.callout a:hover { - background-color: #fff; - color: var(--callouctcolor); -} - -.site-description { - display: flex; - justify-content: space-between; -} -.tags li::before { - content: "- "; -} -.tags a { - border-bottom: 3px solid var(--maincolor); -} -.tags a:hover { - color: white; - background-color: var(--hovercolor); -} -svg { - max-height: 15px; -} -.soc:hover { - color: white; -} -.draft-label { - color: var(--bordercl); - text-decoration: none; - padding: 2px 4px; - border-radius: 4px; - margin-left: 6px; - background-color: #f9f2f4; -} -.highlight { - position: relative; - -webkit-overflow-scrolling: touch; -} -.highlight pre code[class*="language-"] { - -webkit-overflow-scrolling: touch; -} -.highlight pre code[class*="language-"]::before { - background: black; - border-radius: 0 0 0.25rem 0.25rem; - color: white; - font-size: 12px; - letter-spacing: 0.025rem; - padding: 0.1rem 0.5rem; - position: absolute; - right: 1rem; - text-align: right; - text-transform: uppercase; - top: 0; -} - -.highlight pre code[class="language-javaScript"]::before, -.highlight pre code[class="language-js"]::before { - content: "js"; - background: #f7df1e; - color: black; -} -.highlight pre code[class*="language-yml"]::before, -.highlight pre code[class*="language-yaml"]::before { - content: "yaml"; - background: #f71e6a; - color: white; -} -.highlight pre code[class*="language-shell"]::before, -.highlight pre code[class*="language-bash"]::before, -.highlight pre code[class*="language-sh"]::before { - content: "shell"; - background: green; - color: white; -} -.highlight pre code[class*="language-json"]::before { - content: "json"; - background: dodgerblue; - color: #000000; -} -.highlight pre code[class*="language-python"]::before, -.highlight pre code[class*="language-py"]::before { - content: "py"; - background: blue; - color: yellow; -} -.highlight pre code[class*="language-css"]::before { - content: "css"; - background: cyan; - color: black; -} -.highlight pre code[class*="language-go"]::before { - content: "Go"; - background: cyan; - color: royalblue; -} -.highlight pre code[class*="language-md"]::before, -.highlight pre code[class*="language-md"]::before { - content: "Markdown"; - background: royalblue; - color: whitesmoke; -} - -/* table */ -table { - border-spacing: 0; - border-collapse: collapse; -} - -table th { - padding: 6px 13px; - border: 1px solid #dfe2e5; - font-size: large; -} - -table td { - padding: 6px 13px; - border: 1px solid #dfe2e5; -} diff --git a/public/css/non-critical.10bf652274d1149570c93631c19d9e068c317875079471d2fda62260a2d40136a468ceb49a9b091ce868ae2db84cbfdb5e4eab1b465fb9710247eb86f36275a0.css b/public/css/non-critical.10bf652274d1149570c93631c19d9e068c317875079471d2fda62260a2d40136a468ceb49a9b091ce868ae2db84cbfdb5e4eab1b465fb9710247eb86f36275a0.css new file mode 100644 index 00000000..1840b6e3 --- /dev/null +++ b/public/css/non-critical.10bf652274d1149570c93631c19d9e068c317875079471d2fda62260a2d40136a468ceb49a9b091ce868ae2db84cbfdb5e4eab1b465fb9710247eb86f36275a0.css @@ -0,0 +1,3 @@ +div.code-toolbar{position:relative}div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out;z-index:10}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:none;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;-webkit-text-decoration:none;text-decoration:none}pre[class*=language-].line-numbers{counter-reset:linenumber;padding-left:3.8em;position:relative}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{border-right:1px solid #999;font-size:100%;left:-3.8em;letter-spacing:-1px;pointer-events:none;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:3em}.line-numbers-rows>span{counter-increment:linenumber;display:block}.line-numbers-rows>span:before{color:#999;content:counter(linenumber);display:block;padding-right:.8em;text-align:right}.command-line-prompt{border-right:1px solid #999;display:block;float:left;font-size:100%;letter-spacing:-1px;margin-right:1em;pointer-events:none;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none}.command-line-prompt>span:before{content:" ";display:block;opacity:.7;padding-right:.8em}.command-line-prompt>span[data-user]:before{content:"[" attr(data-user) "@" attr(data-host) "] $"}.command-line-prompt>span[data-user=root]:before{content:"[" attr(data-user) "@" attr(data-host) "] #"}.command-line-prompt>span[data-prompt]:before{content:attr(data-prompt)}.command-line-prompt>span[data-continuation-prompt]:before{content:attr(data-continuation-prompt)}.command-line span.token.output{opacity:.7}pre.diff-highlight>code .token.deleted:not(.prefix),pre>code.diff-highlight .token.deleted:not(.prefix){background-color:rgba(255,0,0,.1);color:inherit;display:block}pre.diff-highlight>code .token.inserted:not(.prefix),pre>code.diff-highlight .token.inserted:not(.prefix){background-color:rgba(0,255,128,.1);color:inherit;display:block} + +/*! MIT License | github.com/schnerring/hugo-theme-gruvbox */ \ No newline at end of file diff --git a/public/de/404.html b/public/de/404.html new file mode 100644 index 00000000..81198503 --- /dev/null +++ b/public/de/404.html @@ -0,0 +1,10 @@ +404 Page not found +
+

404 Page not found

This is not the page you're looking for.

\ No newline at end of file diff --git a/public/de/categories/index.html b/public/de/categories/index.html new file mode 100644 index 00000000..8f2293d6 --- /dev/null +++ b/public/de/categories/index.html @@ -0,0 +1,10 @@ +Categories +
+

Categories

\ No newline at end of file diff --git a/public/de/categories/index.xml b/public/de/categories/index.xml new file mode 100644 index 00000000..7acb9f77 --- /dev/null +++ b/public/de/categories/index.xml @@ -0,0 +1 @@ +Categories onhttps://davegallant.ca/de/categories/Recent content in Categories onHugo -- gohugo.iodeDave Gallant \ No newline at end of file diff --git a/public/de/categories/page/1/index.html b/public/de/categories/page/1/index.html new file mode 100644 index 00000000..6fec466f --- /dev/null +++ b/public/de/categories/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/de/categories/ + \ No newline at end of file diff --git a/public/de/index.html b/public/de/index.html new file mode 100644 index 00000000..39d92a76 --- /dev/null +++ b/public/de/index.html @@ -0,0 +1,10 @@ + +
+

\ No newline at end of file diff --git a/public/de/index.xml b/public/de/index.xml new file mode 100644 index 00000000..e0883684 --- /dev/null +++ b/public/de/index.xml @@ -0,0 +1 @@ +<link>https://davegallant.ca/de/</link><description>Recent content on</description><generator>Hugo -- gohugo.io</generator><language>de</language><copyright>Dave Gallant</copyright><atom:link href="https://davegallant.ca/de/index.xml" rel="self" type="application/rss+xml"/></channel></rss> \ No newline at end of file diff --git a/public/de/page/1/index.html b/public/de/page/1/index.html new file mode 100644 index 00000000..4c2416b6 --- /dev/null +++ b/public/de/page/1/index.html @@ -0,0 +1,2 @@ +<!doctype html><html lang=de><head><title>https://davegallant.ca/de/ + \ No newline at end of file diff --git a/public/de/sitemap.xml b/public/de/sitemap.xml new file mode 100644 index 00000000..2924cae0 --- /dev/null +++ b/public/de/sitemap.xml @@ -0,0 +1 @@ +https://davegallant.ca/de/https://davegallant.ca/de/categories/https://davegallant.ca/de/tags/ \ No newline at end of file diff --git a/public/de/tags/index.html b/public/de/tags/index.html new file mode 100644 index 00000000..12d4d80d --- /dev/null +++ b/public/de/tags/index.html @@ -0,0 +1,10 @@ +Tags +
+

Tags

\ No newline at end of file diff --git a/public/de/tags/index.xml b/public/de/tags/index.xml new file mode 100644 index 00000000..f04ab4ab --- /dev/null +++ b/public/de/tags/index.xml @@ -0,0 +1 @@ +Tags onhttps://davegallant.ca/de/tags/Recent content in Tags onHugo -- gohugo.iodeDave Gallant \ No newline at end of file diff --git a/public/de/tags/page/1/index.html b/public/de/tags/page/1/index.html new file mode 100644 index 00000000..4b26cbd8 --- /dev/null +++ b/public/de/tags/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/de/tags/ + \ No newline at end of file diff --git a/public/en/index.html b/public/en/index.html new file mode 100644 index 00000000..6f314ca2 --- /dev/null +++ b/public/en/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca + \ No newline at end of file diff --git a/public/en/sitemap.xml b/public/en/sitemap.xml new file mode 100644 index 00000000..24853c65 --- /dev/null +++ b/public/en/sitemap.xml @@ -0,0 +1 @@ +https://davegallant.ca/2023-12-10T17:22:11-05:00https://davegallant.ca/tags/gitea/2023-12-10T17:22:11-05:00https://davegallant.ca/tags/gitea-actions/2023-12-10T17:22:11-05:00https://davegallant.ca/tags/github-actions/2023-12-10T17:22:11-05:00https://davegallant.ca/post/2023-12-10T17:22:11-05:00https://davegallant.ca/tags/self-hosted/2023-12-10T17:22:11-05:00https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/2023-12-10T17:22:11-05:00https://davegallant.ca/tags/2023-12-10T17:22:11-05:00https://davegallant.ca/tags/tailscale/2023-12-10T17:22:11-05:00https://davegallant.ca/tags/aks/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/aws/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/azure/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/bastion/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/cloud-sql-proxy/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/database/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/eks/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/k8s/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/kubectl-plugin-socks5-proxy/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/proxy/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/socat/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/socks/2023-05-22T16:31:29-04:00https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/2023-05-22T16:31:29-04:00https://davegallant.ca/tags/degoogle/2022-12-10T21:46:55-05:00https://davegallant.ca/tags/invidious/2022-12-10T21:46:55-05:00https://davegallant.ca/tags/privacy/2022-12-10T21:46:55-05:00https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/2022-12-10T21:46:55-05:00https://davegallant.ca/tags/yewtu.be/2022-12-10T21:46:55-05:00https://davegallant.ca/tags/youtube/2022-12-10T21:46:55-05:00https://davegallant.ca/tags/openwrt/2022-04-02T18:50:09-04:00https://davegallant.ca/tags/pfsense/2022-04-02T18:50:09-04:00https://davegallant.ca/tags/proxmox/2022-04-02T18:50:09-04:00https://davegallant.ca/tags/router/2022-04-02T18:50:09-04:00https://davegallant.ca/tags/router-on-a-stick/2022-04-02T18:50:09-04:00https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/2022-04-02T18:50:09-04:00https://davegallant.ca/tags/vlan/2022-04-02T18:50:09-04:00https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/2022-03-13T18:49:10-04:00https://davegallant.ca/tags/backup/2022-03-13T18:49:10-04:00https://davegallant.ca/tags/gmail/2022-03-13T18:49:10-04:00https://davegallant.ca/tags/ransomware/2022-03-13T18:49:10-04:00https://davegallant.ca/tags/synology/2022-03-13T18:49:10-04:00https://davegallant.ca/tags/k3s/2021-11-14T10:07:03-05:00https://davegallant.ca/tags/lxc/2021-11-14T10:07:03-05:00https://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/2021-11-14T10:07:03-05:00https://davegallant.ca/tags/containers/2021-10-11T10:43:35-04:00https://davegallant.ca/tags/docker/2021-10-11T10:43:35-04:00https://davegallant.ca/tags/podman/2021-10-11T10:43:35-04:00https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/2021-10-11T10:43:35-04:00https://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/2021-09-17T12:48:33-04:00https://davegallant.ca/tags/aws-vault/2021-09-17T12:48:33-04:00https://davegallant.ca/tags/python/2021-09-17T12:48:33-04:00https://davegallant.ca/tags/security/2021-09-17T12:48:33-04:00https://davegallant.ca/tags/dotfiles/2021-09-08T00:42:33-04:00https://davegallant.ca/tags/home-manager/2021-09-08T00:42:33-04:00https://davegallant.ca/tags/nix/2021-09-08T00:42:33-04:00https://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/2021-09-08T00:42:33-04:00https://davegallant.ca/blog/2021/09/06/what-to-do-with-a-homelab/2021-09-06T01:12:54-04:00https://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/2020-03-16T22:00:15-04:00https://davegallant.ca/tags/linux/2020-03-16T22:00:15-04:00https://davegallant.ca/tags/vpn/2020-03-16T22:00:15-04:00https://davegallant.ca/categories/ \ No newline at end of file diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 00000000..b8758794 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 00000000..3d10067a Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/fonts/fira-code-latin-300.woff b/public/fonts/fira-code-latin-300.woff new file mode 100644 index 00000000..140a94a4 Binary files /dev/null and b/public/fonts/fira-code-latin-300.woff differ diff --git a/public/fonts/fira-code-latin-300.woff2 b/public/fonts/fira-code-latin-300.woff2 new file mode 100644 index 00000000..86eaa9ca Binary files /dev/null and b/public/fonts/fira-code-latin-300.woff2 differ diff --git a/public/fonts/fira-code-latin-400.woff b/public/fonts/fira-code-latin-400.woff new file mode 100644 index 00000000..10a14ac5 Binary files /dev/null and b/public/fonts/fira-code-latin-400.woff differ diff --git a/public/fonts/fira-code-latin-400.woff2 b/public/fonts/fira-code-latin-400.woff2 new file mode 100644 index 00000000..99f05e3f Binary files /dev/null and b/public/fonts/fira-code-latin-400.woff2 differ diff --git a/public/fonts/fira-code-latin-500.woff b/public/fonts/fira-code-latin-500.woff new file mode 100644 index 00000000..b3a2364c Binary files /dev/null and b/public/fonts/fira-code-latin-500.woff differ diff --git a/public/fonts/fira-code-latin-500.woff2 b/public/fonts/fira-code-latin-500.woff2 new file mode 100644 index 00000000..76695cf4 Binary files /dev/null and b/public/fonts/fira-code-latin-500.woff2 differ diff --git a/public/fonts/fira-code-latin-600.woff b/public/fonts/fira-code-latin-600.woff new file mode 100644 index 00000000..837477ef Binary files /dev/null and b/public/fonts/fira-code-latin-600.woff differ diff --git a/public/fonts/fira-code-latin-600.woff2 b/public/fonts/fira-code-latin-600.woff2 new file mode 100644 index 00000000..677b25ae Binary files /dev/null and b/public/fonts/fira-code-latin-600.woff2 differ diff --git a/public/fonts/fira-code-latin-700.woff b/public/fonts/fira-code-latin-700.woff new file mode 100644 index 00000000..0925d245 Binary files /dev/null and b/public/fonts/fira-code-latin-700.woff differ diff --git a/public/fonts/fira-code-latin-700.woff2 b/public/fonts/fira-code-latin-700.woff2 new file mode 100644 index 00000000..b120bb1b Binary files /dev/null and b/public/fonts/fira-code-latin-700.woff2 differ diff --git a/public/fonts/fira-sans-v10-latin-regular.eot b/public/fonts/fira-sans-v10-latin-regular.eot deleted file mode 100644 index 7abf4c2f..00000000 Binary files a/public/fonts/fira-sans-v10-latin-regular.eot and /dev/null differ diff --git a/public/fonts/fira-sans-v10-latin-regular.svg b/public/fonts/fira-sans-v10-latin-regular.svg deleted file mode 100644 index 1e520978..00000000 --- a/public/fonts/fira-sans-v10-latin-regular.svg +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/fonts/fira-sans-v10-latin-regular.ttf b/public/fonts/fira-sans-v10-latin-regular.ttf deleted file mode 100644 index 572e442e..00000000 Binary files a/public/fonts/fira-sans-v10-latin-regular.ttf and /dev/null differ diff --git a/public/fonts/fira-sans-v10-latin-regular.woff b/public/fonts/fira-sans-v10-latin-regular.woff deleted file mode 100644 index d99ba57a..00000000 Binary files a/public/fonts/fira-sans-v10-latin-regular.woff and /dev/null differ diff --git a/public/fonts/fira-sans-v10-latin-regular.woff2 b/public/fonts/fira-sans-v10-latin-regular.woff2 deleted file mode 100644 index 9bb57603..00000000 Binary files a/public/fonts/fira-sans-v10-latin-regular.woff2 and /dev/null differ diff --git a/public/fonts/ibm-plex-mono-v6-latin-500italic.eot b/public/fonts/ibm-plex-mono-v6-latin-500italic.eot deleted file mode 100644 index 62b89b32..00000000 Binary files a/public/fonts/ibm-plex-mono-v6-latin-500italic.eot and /dev/null differ diff --git a/public/fonts/ibm-plex-mono-v6-latin-500italic.svg b/public/fonts/ibm-plex-mono-v6-latin-500italic.svg deleted file mode 100644 index 6423805a..00000000 --- a/public/fonts/ibm-plex-mono-v6-latin-500italic.svg +++ /dev/null @@ -1,365 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/fonts/ibm-plex-mono-v6-latin-500italic.ttf b/public/fonts/ibm-plex-mono-v6-latin-500italic.ttf deleted file mode 100644 index e4d1ddf0..00000000 Binary files a/public/fonts/ibm-plex-mono-v6-latin-500italic.ttf and /dev/null differ diff --git a/public/fonts/ibm-plex-mono-v6-latin-500italic.woff b/public/fonts/ibm-plex-mono-v6-latin-500italic.woff deleted file mode 100644 index 4504b413..00000000 Binary files a/public/fonts/ibm-plex-mono-v6-latin-500italic.woff and /dev/null differ diff --git a/public/fonts/ibm-plex-mono-v6-latin-500italic.woff2 b/public/fonts/ibm-plex-mono-v6-latin-500italic.woff2 deleted file mode 100644 index 489745d1..00000000 Binary files a/public/fonts/ibm-plex-mono-v6-latin-500italic.woff2 and /dev/null differ diff --git a/public/fonts/roboto-mono-v12-latin-regular.eot b/public/fonts/roboto-mono-v12-latin-regular.eot deleted file mode 100644 index 8c56483c..00000000 Binary files a/public/fonts/roboto-mono-v12-latin-regular.eot and /dev/null differ diff --git a/public/fonts/roboto-mono-v12-latin-regular.svg b/public/fonts/roboto-mono-v12-latin-regular.svg deleted file mode 100644 index 18643286..00000000 --- a/public/fonts/roboto-mono-v12-latin-regular.svg +++ /dev/null @@ -1,405 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/fonts/roboto-mono-v12-latin-regular.ttf b/public/fonts/roboto-mono-v12-latin-regular.ttf deleted file mode 100644 index d5dee83e..00000000 Binary files a/public/fonts/roboto-mono-v12-latin-regular.ttf and /dev/null differ diff --git a/public/fonts/roboto-mono-v12-latin-regular.woff b/public/fonts/roboto-mono-v12-latin-regular.woff deleted file mode 100644 index f319fbfa..00000000 Binary files a/public/fonts/roboto-mono-v12-latin-regular.woff and /dev/null differ diff --git a/public/fonts/roboto-mono-v12-latin-regular.woff2 b/public/fonts/roboto-mono-v12-latin-regular.woff2 deleted file mode 100644 index ed384d22..00000000 Binary files a/public/fonts/roboto-mono-v12-latin-regular.woff2 and /dev/null differ diff --git a/public/fonts/roboto-slab-latin-100.woff b/public/fonts/roboto-slab-latin-100.woff new file mode 100644 index 00000000..4cc73bfc Binary files /dev/null and b/public/fonts/roboto-slab-latin-100.woff differ diff --git a/public/fonts/roboto-slab-latin-100.woff2 b/public/fonts/roboto-slab-latin-100.woff2 new file mode 100644 index 00000000..cc7a1e9d Binary files /dev/null and b/public/fonts/roboto-slab-latin-100.woff2 differ diff --git a/public/fonts/roboto-slab-latin-200.woff b/public/fonts/roboto-slab-latin-200.woff new file mode 100644 index 00000000..e94017f6 Binary files /dev/null and b/public/fonts/roboto-slab-latin-200.woff differ diff --git a/public/fonts/roboto-slab-latin-200.woff2 b/public/fonts/roboto-slab-latin-200.woff2 new file mode 100644 index 00000000..e34ea989 Binary files /dev/null and b/public/fonts/roboto-slab-latin-200.woff2 differ diff --git a/public/fonts/roboto-slab-latin-300.woff b/public/fonts/roboto-slab-latin-300.woff new file mode 100644 index 00000000..349f3053 Binary files /dev/null and b/public/fonts/roboto-slab-latin-300.woff differ diff --git a/public/fonts/roboto-slab-latin-300.woff2 b/public/fonts/roboto-slab-latin-300.woff2 new file mode 100644 index 00000000..3100e32c Binary files /dev/null and b/public/fonts/roboto-slab-latin-300.woff2 differ diff --git a/public/fonts/roboto-slab-latin-400.woff b/public/fonts/roboto-slab-latin-400.woff new file mode 100644 index 00000000..4ef4ab83 Binary files /dev/null and b/public/fonts/roboto-slab-latin-400.woff differ diff --git a/public/fonts/roboto-slab-latin-400.woff2 b/public/fonts/roboto-slab-latin-400.woff2 new file mode 100644 index 00000000..b135852b Binary files /dev/null and b/public/fonts/roboto-slab-latin-400.woff2 differ diff --git a/public/fonts/roboto-slab-latin-500.woff b/public/fonts/roboto-slab-latin-500.woff new file mode 100644 index 00000000..7b21a3ec Binary files /dev/null and b/public/fonts/roboto-slab-latin-500.woff differ diff --git a/public/fonts/roboto-slab-latin-500.woff2 b/public/fonts/roboto-slab-latin-500.woff2 new file mode 100644 index 00000000..ec193de6 Binary files /dev/null and b/public/fonts/roboto-slab-latin-500.woff2 differ diff --git a/public/fonts/roboto-slab-latin-600.woff b/public/fonts/roboto-slab-latin-600.woff new file mode 100644 index 00000000..7c3774e2 Binary files /dev/null and b/public/fonts/roboto-slab-latin-600.woff differ diff --git a/public/fonts/roboto-slab-latin-600.woff2 b/public/fonts/roboto-slab-latin-600.woff2 new file mode 100644 index 00000000..1e20cbf4 Binary files /dev/null and b/public/fonts/roboto-slab-latin-600.woff2 differ diff --git a/public/fonts/roboto-slab-latin-700.woff b/public/fonts/roboto-slab-latin-700.woff new file mode 100644 index 00000000..a1dbdd7f Binary files /dev/null and b/public/fonts/roboto-slab-latin-700.woff differ diff --git a/public/fonts/roboto-slab-latin-700.woff2 b/public/fonts/roboto-slab-latin-700.woff2 new file mode 100644 index 00000000..9813ce22 Binary files /dev/null and b/public/fonts/roboto-slab-latin-700.woff2 differ diff --git a/public/fonts/roboto-slab-latin-800.woff b/public/fonts/roboto-slab-latin-800.woff new file mode 100644 index 00000000..89e8b52d Binary files /dev/null and b/public/fonts/roboto-slab-latin-800.woff differ diff --git a/public/fonts/roboto-slab-latin-800.woff2 b/public/fonts/roboto-slab-latin-800.woff2 new file mode 100644 index 00000000..48c58311 Binary files /dev/null and b/public/fonts/roboto-slab-latin-800.woff2 differ diff --git a/public/fonts/roboto-slab-latin-900.woff b/public/fonts/roboto-slab-latin-900.woff new file mode 100644 index 00000000..88006300 Binary files /dev/null and b/public/fonts/roboto-slab-latin-900.woff differ diff --git a/public/fonts/roboto-slab-latin-900.woff2 b/public/fonts/roboto-slab-latin-900.woff2 new file mode 100644 index 00000000..91ae1576 Binary files /dev/null and b/public/fonts/roboto-slab-latin-900.woff2 differ diff --git a/public/index.html b/public/index.html index d8f0ab24..2fba4e2c 100644 --- a/public/index.html +++ b/public/index.html @@ -1,263 +1,11 @@ - - - - - - davegallant | Home - - - - - - - +— Software Engineer +
+

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

Read more >

Running K3s in LXC on Proxmox

It has been a while since I’ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I’ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it’d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.
Read more >

Automatically rotating AWS access keys

Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.
Read more >

Why I threw out my dotfiles

Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (~/.zshrc, ~/.config/git/config, ~/.config/tmux/tmux.conf, etc). I have tried several different ways to manage them, including bare git repos and utilities such as GNU Stow. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: home-manager.

Read more >
\ No newline at end of file diff --git a/public/index.xml b/public/index.xml index ce459076..4bb989d4 100644 --- a/public/index.xml +++ b/public/index.xml @@ -1,98 +1,26 @@ - - - - davegallant - / - Recent content on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - About - /about/ - Mon, 01 Jan 0001 00:00:00 +0000 - /about/ - I&rsquo;m a software tinkerer with a passion for infrastructure, tooling, security, and coffee. -Feel free to reach out at me@davegallant.ca. - - - Setting up Gitea Actions with Tailscale - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - Backing up gmail with Synology - /blog/2022/03/13/backing-up-gmail-with-synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /blog/2022/03/13/backing-up-gmail-with-synology/ - - - - Running K3s in LXC on Proxmox - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - Sun, 14 Nov 2021 10:07:03 -0500 - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. - - - Replacing docker with podman on macOS (and Linux) - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - Mon, 11 Oct 2021 10:43:35 -0400 - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - - - - Automatically rotating AWS access keys - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - Fri, 17 Sep 2021 12:48:33 -0400 - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - - - - Why I threw out my dotfiles - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - Wed, 08 Sep 2021 00:42:33 -0400 - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - AppGate SDP on Arch Linux - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - Mon, 16 Mar 2020 22:00:15 -0400 - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - <p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> - - - +<link>https://davegallant.ca/</link><description>Recent content on</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Dave Gallant</copyright><lastBuildDate>Sun, 10 Dec 2023 17:22:11 -0500</lastBuildDate><atom:link href="https://davegallant.ca/index.xml" rel="self" type="application/rss+xml"/><item><title>Setting up Gitea Actions with Tailscalehttps://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/<p>In this post I&rsquo;ll go through the process of setting up Gitea Actions and <a +href="https://tailscale.com/" +class="link--external" target="_blank" rel="noreferrer" +>Tailscale</a>, unlocking a simple and secure way to automate workflows.</p>Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p>Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p>Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p>Backing up gmail with Synologyhttps://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/<p>I&rsquo;ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.</p>Running K3s in LXC on Proxmoxhttps://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.Replacing docker with podman on macOS (and Linux)https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/<p>There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker:</p>Automatically rotating AWS access keyshttps://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.Why I threw out my dotfileshttps://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/<p>Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (<code>~/.zshrc</code>, <code>~/.config/git/config</code>, <code>~/.config/tmux/tmux.conf</code>, etc). I have tried several different ways to manage them, including <a +href="https://www.atlassian.com/git/tutorials/dotfiles" +class="link--external" target="_blank" rel="noreferrer" +>bare git repos</a> and utilities such as <a +href="https://www.gnu.org/software/stow/" +class="link--external" target="_blank" rel="noreferrer" +>GNU Stow</a>. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: <a +href="https://github.com/nix-community/home-manager" +class="link--external" target="_blank" rel="noreferrer" +>home-manager</a>.</p>What to do with a homelabhttps://davegallant.ca/blog/2021/09/06/what-to-do-with-a-homelab/Mon, 06 Sep 2021 01:12:54 -0400https://davegallant.ca/blog/2021/09/06/what-to-do-with-a-homelab/<p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p>AppGate SDP on Arch Linuxhttps://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/Mon, 16 Mar 2020 22:00:15 -0400https://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/<p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> \ No newline at end of file diff --git a/public/js/.gitkeep b/public/js/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/public/js/copy-code-button.js b/public/js/copy-code-button.js deleted file mode 100644 index 8ba74296..00000000 --- a/public/js/copy-code-button.js +++ /dev/null @@ -1,59 +0,0 @@ -function createCopyButton(highlightDiv) { - const button = document.createElement("button"); - button.className = "copy-code-button"; - button.type = "button"; - button.innerText = "Copy"; - button.addEventListener("click", () => - copyCodeToClipboard(button, highlightDiv) - ); - highlightDiv.insertBefore(button, highlightDiv.firstChild); - - const wrapper = document.createElement("div"); - wrapper.className = "highlight-wrapper"; - highlightDiv.parentNode.insertBefore(wrapper, highlightDiv); - wrapper.appendChild(highlightDiv); -} - -document - .querySelectorAll(".highlight") - .forEach((highlightDiv) => createCopyButton(highlightDiv)); - -async function copyCodeToClipboard(button, highlightDiv) { - const codeToCopy = highlightDiv - .querySelector("pre > code ") - .innerText.replace(/\n\n/g, "\n") // Fix the double spacing - .replace(/\n$/, ""); // Clean up last empty line - try { - var result = await navigator.permissions.query({ name: "clipboard-write" }); - if (result.state == "granted" || result.state == "prompt") { - await navigator.clipboard.writeText(codeToCopy); - } else { - copyCodeBlockExecCommand(codeToCopy, highlightDiv); - } - } catch (_) { - copyCodeBlockExecCommand(codeToCopy, highlightDiv); - } finally { - button.blur(); - button.innerText = "Copied!"; - setTimeout(function () { - button.innerText = "Copy"; - }, 2000); - } -} - -function copyCodeBlockExecCommand(codeToCopy, highlightDiv) { - const textArea = document.createElement("textArea"); - textArea.contentEditable = "true"; - textArea.readOnly = "false"; - textArea.className = "copyable-text-area"; - textArea.value = codeToCopy; - highlightDiv.insertBefore(textArea, highlightDiv.firstChild); - const range = document.createRange(); - range.selectNodeContents(textArea); - const sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - textArea.setSelectionRange(0, 999999); - document.execCommand("copy"); - highlightDiv.removeChild(textArea); -} diff --git a/public/js/feather.min.js b/public/js/feather.min.js deleted file mode 100644 index d229492e..00000000 --- a/public/js/feather.min.js +++ /dev/null @@ -1,13 +0,0 @@ -!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.feather=n():e.feather=n()}("undefined"!=typeof self?self:this,function(){return function(e){var n={};function i(l){if(n[l])return n[l].exports;var t=n[l]={i:l,l:!1,exports:{}};return e[l].call(t.exports,t,t.exports,i),t.l=!0,t.exports}return i.m=e,i.c=n,i.d=function(e,n,l){i.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:l})},i.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},i.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(n,"a",n),n},i.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},i.p="",i(i.s=61)}([function(e,n,i){var l=i(20)("wks"),t=i(11),r=i(1).Symbol,o="function"==typeof r;(e.exports=function(e){return l[e]||(l[e]=o&&r[e]||(o?r:t)("Symbol."+e))}).store=l},function(e,n){var i=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=i)},function(e,n){var i=e.exports={version:"2.5.6"};"number"==typeof __e&&(__e=i)},function(e,n){var i={}.hasOwnProperty;e.exports=function(e,n){return i.call(e,n)}},function(e,n,i){e.exports=!i(27)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,n,i){var l=i(13);e.exports=function(e){if(!l(e))throw TypeError(e+" is not an object!");return e}},function(e,n,i){var l=i(5),t=i(56),r=i(55),o=Object.defineProperty;n.f=i(4)?Object.defineProperty:function(e,n,i){if(l(e),n=r(n,!0),l(i),t)try{return o(e,n,i)}catch(e){}if("get"in i||"set"in i)throw TypeError("Accessors not supported!");return"value"in i&&(e[n]=i.value),e}},function(e,n,i){var l=i(6),t=i(12);e.exports=i(4)?function(e,n,i){return l.f(e,n,t(1,i))}:function(e,n,i){return e[n]=i,e}},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l=o(i(35)),t=o(i(33)),r=o(i(32));function o(e){return e&&e.__esModule?e:{default:e}}n.default=Object.keys(t.default).map(function(e){return new l.default(e,t.default[e],r.default[e])}).reduce(function(e,n){return e[n.name]=n,e},{})},function(e,n,i){var l=i(20)("keys"),t=i(11);e.exports=function(e){return l[e]||(l[e]=t(e))}},function(e,n){e.exports={}},function(e,n){var i=0,l=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++i+l).toString(36))}},function(e,n){e.exports=function(e,n){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:n}}},function(e,n){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,n){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,n){var i=Math.ceil,l=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?l:i)(e)}},function(e,n,i){var l; -/*! - Copyright (c) 2016 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames -*/ -/*! - Copyright (c) 2016 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames -*/ -!function(){"use strict";var i=function(){function e(){}function n(e,n){for(var i=n.length,l=0;l0?t(l(e),9007199254740991):0}},function(e,n){var i={}.toString;e.exports=function(e){return i.call(e).slice(8,-1)}},function(e,n,i){var l=i(48),t=i(14);e.exports=function(e){return l(t(e))}},function(e,n,i){var l=i(54);e.exports=function(e,n,i){if(l(e),void 0===n)return e;switch(i){case 1:return function(i){return e.call(n,i)};case 2:return function(i,l){return e.call(n,i,l)};case 3:return function(i,l,t){return e.call(n,i,l,t)}}return function(){return e.apply(n,arguments)}}},function(e,n,i){var l=i(1),t=i(7),r=i(3),o=i(11)("src"),a=Function.toString,c=(""+a).split("toString");i(2).inspectSource=function(e){return a.call(e)},(e.exports=function(e,n,i,a){var y="function"==typeof i;y&&(r(i,"name")||t(i,"name",n)),e[n]!==i&&(y&&(r(i,o)||t(i,o,e[n]?""+e[n]:c.join(String(n)))),e===l?e[n]=i:a?e[n]?e[n]=i:t(e,n,i):(delete e[n],t(e,n,i)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[o]||a.call(this)})},function(e,n,i){var l=i(13),t=i(1).document,r=l(t)&&l(t.createElement);e.exports=function(e){return r?t.createElement(e):{}}},function(e,n){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,n,i){var l=i(1),t=i(2),r=i(7),o=i(25),a=i(24),c=function(e,n,i){var y,p,h,x,s=e&c.F,u=e&c.G,d=e&c.S,f=e&c.P,v=e&c.B,g=u?l:d?l[n]||(l[n]={}):(l[n]||{}).prototype,m=u?t:t[n]||(t[n]={}),M=m.prototype||(m.prototype={});for(y in u&&(i=n),i)h=((p=!s&&g&&void 0!==g[y])?g:i)[y],x=v&&p?a(h,l):f&&"function"==typeof h?a(Function.call,h):h,g&&o(g,y,h,e&c.U),m[y]!=h&&r(m,y,x),f&&M[y]!=h&&(M[y]=h)};l.core=t,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,n){e.exports=!1},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l=Object.assign||function(e){for(var n=1;n0&&void 0!==arguments[0]?arguments[0]:{};if("undefined"==typeof document)throw new Error("`feather.replace()` only works in a browser environment.");var n=document.querySelectorAll("[data-feather]");Array.from(n).forEach(function(n){return function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=function(e){return Array.from(e.attributes).reduce(function(e,n){return e[n.name]=n.value,e},{})}(e),o=i["data-feather"];delete i["data-feather"];var a=r.default[o].toSvg(l({},n,i,{class:(0,t.default)(n.class,i.class)})),c=(new DOMParser).parseFromString(a,"image/svg+xml").querySelector("svg");e.parentNode.replaceChild(c,e)}(n,e)})}},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l,t=i(8),r=(l=t)&&l.__esModule?l:{default:l};n.default=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(console.warn("feather.toSvg() is deprecated. Please use feather.icons[name].toSvg() instead."),!e)throw new Error("The required `key` (icon name) parameter is missing.");if(!r.default[e])throw new Error("No icon matching '"+e+"'. See the complete list of icons at https://feathericons.com");return r.default[e].toSvg(n)}},function(e){e.exports={activity:["pulse","health","action","motion"],airplay:["stream","cast","mirroring"],"alert-circle":["warning"],"alert-octagon":["warning"],"alert-triangle":["warning"],"at-sign":["mention"],award:["achievement","badge"],aperture:["camera","photo"],bell:["alarm","notification"],"bell-off":["alarm","notification","silent"],bluetooth:["wireless"],"book-open":["read"],book:["read","dictionary","booklet","magazine"],bookmark:["read","clip","marker","tag"],briefcase:["work","bag","baggage","folder"],clipboard:["copy"],clock:["time","watch","alarm"],"cloud-drizzle":["weather","shower"],"cloud-lightning":["weather","bolt"],"cloud-rain":["weather"],"cloud-snow":["weather","blizzard"],cloud:["weather"],codepen:["logo"],codesandbox:["logo"],coffee:["drink","cup","mug","tea","cafe","hot","beverage"],command:["keyboard","cmd"],compass:["navigation","safari","travel"],copy:["clone","duplicate"],"corner-down-left":["arrow"],"corner-down-right":["arrow"],"corner-left-down":["arrow"],"corner-left-up":["arrow"],"corner-right-down":["arrow"],"corner-right-up":["arrow"],"corner-up-left":["arrow"],"corner-up-right":["arrow"],"credit-card":["purchase","payment","cc"],crop:["photo","image"],crosshair:["aim","target"],database:["storage"],delete:["remove"],disc:["album","cd","dvd","music"],"dollar-sign":["currency","money","payment"],droplet:["water"],edit:["pencil","change"],"edit-2":["pencil","change"],"edit-3":["pencil","change"],eye:["view","watch"],"eye-off":["view","watch"],"external-link":["outbound"],facebook:["logo"],"fast-forward":["music"],figma:["logo","design","tool"],film:["movie","video"],"folder-minus":["directory"],"folder-plus":["directory"],folder:["directory"],frown:["emoji","face","bad","sad","emotion"],gift:["present","box","birthday","party"],"git-branch":["code","version control"],"git-commit":["code","version control"],"git-merge":["code","version control"],"git-pull-request":["code","version control"],github:["logo","version control"],gitlab:["logo","version control"],global:["world","browser","language","translate"],"hard-drive":["computer","server"],hash:["hashtag","number","pound"],headphones:["music","audio"],heart:["like","love"],"help-circle":["question mark"],hexagon:["shape","node.js","logo"],home:["house"],image:["picture"],inbox:["email"],instagram:["logo","camera"],key:["password","login","authentication"],"life-bouy":["help","life ring","support"],linkedin:["logo"],lock:["security","password"],"log-in":["sign in","arrow"],"log-out":["sign out","arrow"],mail:["email"],"map-pin":["location","navigation","travel","marker"],map:["location","navigation","travel"],maximize:["fullscreen"],"maximize-2":["fullscreen","arrows"],meh:["emoji","face","neutral","emotion"],menu:["bars","navigation","hamburger"],"message-circle":["comment","chat"],"message-square":["comment","chat"],"mic-off":["record"],mic:["record"],minimize:["exit fullscreen"],"minimize-2":["exit fullscreen","arrows"],monitor:["tv"],moon:["dark","night"],"more-horizontal":["ellipsis"],"more-vertical":["ellipsis"],"mouse-pointer":["arrow","cursor"],move:["arrows"],navigation:["location","travel"],"navigation-2":["location","travel"],octagon:["stop"],package:["box"],paperclip:["attachment"],pause:["music","stop"],"pause-circle":["music","stop"],"pen-tool":["vector","drawing"],play:["music","start"],"play-circle":["music","start"],plus:["add","new"],"plus-circle":["add","new"],"plus-square":["add","new"],pocket:["logo","save"],power:["on","off"],radio:["signal"],rewind:["music"],rss:["feed","subscribe"],save:["floppy disk"],search:["find","magnifier","magnifying glass"],send:["message","mail","paper airplane"],settings:["cog","edit","gear","preferences"],shield:["security"],"shield-off":["security"],"shopping-bag":["ecommerce","cart","purchase","store"],"shopping-cart":["ecommerce","cart","purchase","store"],shuffle:["music"],"skip-back":["music"],"skip-forward":["music"],slash:["ban","no"],sliders:["settings","controls"],smile:["emoji","face","happy","good","emotion"],speaker:["music"],star:["bookmark","favorite","like"],sun:["brightness","weather","light"],sunrise:["weather"],sunset:["weather"],tag:["label"],target:["bullseye"],terminal:["code","command line"],"thumbs-down":["dislike","bad"],"thumbs-up":["like","good"],"toggle-left":["on","off","switch"],"toggle-right":["on","off","switch"],trash:["garbage","delete","remove"],"trash-2":["garbage","delete","remove"],triangle:["delta"],truck:["delivery","van","shipping"],twitter:["logo"],umbrella:["rain","weather"],"video-off":["camera","movie","film"],video:["camera","movie","film"],voicemail:["phone"],volume:["music","sound","mute"],"volume-1":["music","sound"],"volume-2":["music","sound"],"volume-x":["music","sound","mute"],watch:["clock","time"],wind:["weather","air"],"x-circle":["cancel","close","delete","remove","times"],"x-octagon":["delete","stop","alert","warning","times"],"x-square":["cancel","close","delete","remove","times"],x:["cancel","close","delete","remove","times"],youtube:["logo","video","play"],"zap-off":["flash","camera","lightning"],zap:["flash","camera","lightning"]}},function(e){e.exports={activity:'',airplay:'',"alert-circle":'',"alert-octagon":'',"alert-triangle":'',"align-center":'',"align-justify":'',"align-left":'',"align-right":'',anchor:'',aperture:'',archive:'',"arrow-down-circle":'',"arrow-down-left":'',"arrow-down-right":'',"arrow-down":'',"arrow-left-circle":'',"arrow-left":'',"arrow-right-circle":'',"arrow-right":'',"arrow-up-circle":'',"arrow-up-left":'',"arrow-up-right":'',"arrow-up":'',"at-sign":'',award:'',"bar-chart-2":'',"bar-chart":'',"battery-charging":'',battery:'',"bell-off":'',bell:'',bluetooth:'',bold:'',"book-open":'',book:'',bookmark:'',box:'',briefcase:'',calendar:'',"camera-off":'',camera:'',cast:'',"check-circle":'',"check-square":'',check:'',"chevron-down":'',"chevron-left":'',"chevron-right":'',"chevron-up":'',"chevrons-down":'',"chevrons-left":'',"chevrons-right":'',"chevrons-up":'',chrome:'',circle:'',clipboard:'',clock:'',"cloud-drizzle":'',"cloud-lightning":'',"cloud-off":'',"cloud-rain":'',"cloud-snow":'',cloud:'',code:'',codepen:'',codesandbox:'',coffee:'',columns:'',command:'',compass:'',copy:'',"corner-down-left":'',"corner-down-right":'',"corner-left-down":'',"corner-left-up":'',"corner-right-down":'',"corner-right-up":'',"corner-up-left":'',"corner-up-right":'',cpu:'',"credit-card":'',crop:'',crosshair:'',database:'',delete:'',disc:'',"dollar-sign":'',"download-cloud":'',download:'',droplet:'',"edit-2":'',"edit-3":'',edit:'',"external-link":'',"eye-off":'',eye:'',facebook:'',"fast-forward":'',feather:'',figma:'',"file-minus":'',"file-plus":'',"file-text":'',file:'',film:'',filter:'',flag:'',"folder-minus":'',"folder-plus":'',folder:'',frown:'',gift:'',"git-branch":'',"git-commit":'',"git-merge":'',"git-pull-request":'',github:'',gitlab:'',globe:'',grid:'',"hard-drive":'',hash:'',headphones:'',heart:'',"help-circle":'',hexagon:'',home:'',image:'',inbox:'',info:'',instagram:'',italic:'',key:'',layers:'',layout:'',"life-buoy":'',"link-2":'',link:'',linkedin:'',list:'',loader:'',lock:'',"log-in":'',"log-out":'',mail:'',"map-pin":'',map:'',"maximize-2":'',maximize:'',meh:'',menu:'',"message-circle":'',"message-square":'',"mic-off":'',mic:'',"minimize-2":'',minimize:'',"minus-circle":'',"minus-square":'',minus:'',monitor:'',moon:'',"more-horizontal":'',"more-vertical":'',"mouse-pointer":'',move:'',music:'',"navigation-2":'',navigation:'',octagon:'',package:'',paperclip:'',"pause-circle":'',pause:'',"pen-tool":'',percent:'',"phone-call":'',"phone-forwarded":'',"phone-incoming":'',"phone-missed":'',"phone-off":'',"phone-outgoing":'',phone:'',"pie-chart":'',"play-circle":'',play:'',"plus-circle":'',"plus-square":'',plus:'',pocket:'',power:'',printer:'',radio:'',"refresh-ccw":'',"refresh-cw":'',repeat:'',rewind:'',"rotate-ccw":'',"rotate-cw":'',rss:'',save:'',scissors:'',search:'',send:'',server:'',settings:'',"share-2":'',share:'',"shield-off":'',shield:'',"shopping-bag":'',"shopping-cart":'',shuffle:'',sidebar:'',"skip-back":'',"skip-forward":'',slack:'',slash:'',sliders:'',smartphone:'',smile:'',speaker:'',square:'',star:'',"stop-circle":'',sun:'',sunrise:'',sunset:'',tablet:'',tag:'',target:'',terminal:'',thermometer:'',"thumbs-down":'',"thumbs-up":'',"toggle-left":'',"toggle-right":'',"trash-2":'',trash:'',trello:'',"trending-down":'',"trending-up":'',triangle:'',truck:'',tv:'',twitter:'',type:'',umbrella:'',underline:'',unlock:'',"upload-cloud":'',upload:'',"user-check":'',"user-minus":'',"user-plus":'',"user-x":'',user:'',users:'',"video-off":'',video:'',voicemail:'',"volume-1":'',"volume-2":'',"volume-x":'',volume:'',watch:'',"wifi-off":'',wifi:'',wind:'',"x-circle":'',"x-octagon":'',"x-square":'',x:'',youtube:'',"zap-off":'',zap:'',"zoom-in":'',"zoom-out":''}},function(e){e.exports={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"}},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l=Object.assign||function(e){for(var n=1;n2&&void 0!==arguments[2]?arguments[2]:[];!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=n,this.contents=i,this.tags=t,this.attrs=l({},o.default,{class:"feather feather-"+n})}return t(e,[{key:"toSvg",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return""+this.contents+""}},{key:"toString",value:function(){return this.contents}}]),e}();n.default=c},function(e,n,i){"use strict";var l=o(i(8)),t=o(i(31)),r=o(i(30));function o(e){return e&&e.__esModule?e:{default:e}}e.exports={icons:l.default,toSvg:t.default,replace:r.default}},function(e,n,i){var l=i(0)("iterator"),t=!1;try{var r=[7][l]();r.return=function(){t=!0},Array.from(r,function(){throw 2})}catch(e){}e.exports=function(e,n){if(!n&&!t)return!1;var i=!1;try{var r=[7],o=r[l]();o.next=function(){return{done:i=!0}},r[l]=function(){return o},e(r)}catch(e){}return i}},function(e,n,i){var l=i(22),t=i(0)("toStringTag"),r="Arguments"==l(function(){return arguments}());e.exports=function(e){var n,i,o;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(i=function(e,n){try{return e[n]}catch(e){}}(n=Object(e),t))?i:r?l(n):"Object"==(o=l(n))&&"function"==typeof n.callee?"Arguments":o}},function(e,n,i){var l=i(38),t=i(0)("iterator"),r=i(10);e.exports=i(2).getIteratorMethod=function(e){if(void 0!=e)return e[t]||e["@@iterator"]||r[l(e)]}},function(e,n,i){"use strict";var l=i(6),t=i(12);e.exports=function(e,n,i){n in e?l.f(e,n,t(0,i)):e[n]=i}},function(e,n,i){var l=i(10),t=i(0)("iterator"),r=Array.prototype;e.exports=function(e){return void 0!==e&&(l.Array===e||r[t]===e)}},function(e,n,i){var l=i(5);e.exports=function(e,n,i,t){try{return t?n(l(i)[0],i[1]):n(i)}catch(n){var r=e.return;throw void 0!==r&&l(r.call(e)),n}}},function(e,n,i){"use strict";var l=i(24),t=i(28),r=i(17),o=i(42),a=i(41),c=i(21),y=i(40),p=i(39);t(t.S+t.F*!i(37)(function(e){Array.from(e)}),"Array",{from:function(e){var n,i,t,h,x=r(e),s="function"==typeof this?this:Array,u=arguments.length,d=u>1?arguments[1]:void 0,f=void 0!==d,v=0,g=p(x);if(f&&(d=l(d,u>2?arguments[2]:void 0,2)),void 0==g||s==Array&&a(g))for(i=new s(n=c(x.length));n>v;v++)y(i,v,f?d(x[v],v):x[v]);else for(h=g.call(x),i=new s;!(t=h.next()).done;v++)y(i,v,f?o(h,d,[t.value,v],!0):t.value);return i.length=v,i}})},function(e,n,i){var l=i(3),t=i(17),r=i(9)("IE_PROTO"),o=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=t(e),l(e,r)?e[r]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?o:null}},function(e,n,i){var l=i(1).document;e.exports=l&&l.documentElement},function(e,n,i){var l=i(15),t=Math.max,r=Math.min;e.exports=function(e,n){return(e=l(e))<0?t(e+n,0):r(e,n)}},function(e,n,i){var l=i(23),t=i(21),r=i(46);e.exports=function(e){return function(n,i,o){var a,c=l(n),y=t(c.length),p=r(o,y);if(e&&i!=i){for(;y>p;)if((a=c[p++])!=a)return!0}else for(;y>p;p++)if((e||p in c)&&c[p]===i)return e||p||0;return!e&&-1}}},function(e,n,i){var l=i(22);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==l(e)?e.split(""):Object(e)}},function(e,n,i){var l=i(3),t=i(23),r=i(47)(!1),o=i(9)("IE_PROTO");e.exports=function(e,n){var i,a=t(e),c=0,y=[];for(i in a)i!=o&&l(a,i)&&y.push(i);for(;n.length>c;)l(a,i=n[c++])&&(~r(y,i)||y.push(i));return y}},function(e,n,i){var l=i(49),t=i(19);e.exports=Object.keys||function(e){return l(e,t)}},function(e,n,i){var l=i(6),t=i(5),r=i(50);e.exports=i(4)?Object.defineProperties:function(e,n){t(e);for(var i,o=r(n),a=o.length,c=0;a>c;)l.f(e,i=o[c++],n[i]);return e}},function(e,n,i){var l=i(5),t=i(51),r=i(19),o=i(9)("IE_PROTO"),a=function(){},c=function(){var e,n=i(26)("iframe"),l=r.length;for(n.style.display="none",i(45).appendChild(n),n.src="javascript:",(e=n.contentWindow.document).open(),e.write(" - - - +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;-webkit-text-decoration:underline;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none} - - - - +/*! CC BY-SA 3.0 License | https://stackoverflow.com/a/36118384/1154965 */@keyframes blink{50%{opacity:0}to{opacity:1}} - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- - -
-

A personal blog

- - - -
-

AppGate SDP on Arch Linux

- -
- - - -
-
- - - - - - -
-
- -
- - - - -
- - -
- - - - - -
- - - +/*! MIT License | github.com/schnerring/hugo-theme-gruvbox */:root[data-theme=light]{--bg:var(--bg0);--bg0:#fbf1c7;--bg0_h:#f9f5d7;--bg0_s:#f2e5bc;--bg1:#ebdbb2;--bg2:#d5c4a1;--bg3:#bdae93;--bg4:#a89984;--fg:var(--fg1);--fg0:#282828;--fg1:#3c3836;--fg2:#504945;--fg3:#665c54;--fg4:#7c6f64;--gray1:var(--fg4);--gray2:#928374;--red1:#cc241d;--red2:#9d0006;--green1:#98971a;--green2:#797403;--yellow1:#d79921;--yellow2:#b57614;--blue1:#458588;--blue2:#076678;--purple1:#b16286;--purple2:#8f3f71;--aqua1:#689d6a;--aqua2:#427b58;--orange1:#d65d0e;--orange2:#af3a03}:root[data-theme=dark]{--bg:var(--bg0);--bg0:#282828;--bg0_h:#1d2021;--bg0_s:#32302f;--bg1:#3c3836;--bg2:#504945;--bg3:#665c54;--bg4:#7c6f64;--fg:var(--fg1);--fg0:#fbf1c7;--fg1:#ebdbb2;--fg2:#d5c4a1;--fg3:#bdae93;--fg4:#a89984;--gray1:var(--fg4);--gray2:#928374;--red1:#cc241d;--red2:#fb4934;--green1:#98971a;--green2:#b8bb26;--yellow1:#d79921;--yellow2:#fabd2f;--blue1:#458588;--blue2:#83a598;--purple1:#b16286;--purple2:#d3869b;--aqua1:#689d6a;--aqua2:#8ec07c;--orange1:#d65d0e;--orange2:#fe8019}:root{--primary:var(--blue1);--primary-alt:var(--blue2);--font-monospace:"Fira Code","Lucida Console",Monaco,monospace;--font-sans-serif:Verdana,Helvetica,sans-serif;--font-serif:"Roboto Slab",Georgia,serif}::-moz-selection{background:var(--bg4);color:var(--fg0)}::selection{background:var(--bg4);color:var(--fg0)}.search{display:flex;grid-area:search;margin:0 1rem}#search__text{background:var(--bg2);border:1px solid var(--bg2);border-radius:.2rem;caret-color:var(--fg);color:var(--fg);outline:none;padding:0 .5rem;width:100%}#search__text:hover{border-color:var(--bg3)}#search__text:focus{border-color:var(--bg4)}#search__text::-moz-placeholder{color:var(--fg3)}#search__text::placeholder{color:var(--fg3)}#search__text[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}#search__suggestions{background:var(--bg);border-radius:.2rem;box-shadow:0 .5rem 1rem var(--bg1);font-family:Roboto Slab,Georgia,serif;font-family:var(--font-serif);left:0;margin-top:2rem;position:absolute;width:95vw;z-index:1000}@media (min-width:768px){.search{position:relative}#search__suggestions{width:60vw}}.search__suggestions--hidden{display:none}.search__suggestion-item{border-bottom:1px dashed var(--bg2);display:grid;grid-template-columns:1fr 2fr}.search__suggestion-item:focus,.search__suggestion-item:focus-visible,.search__suggestion-item:hover{background:var(--bg1);cursor:pointer;outline:none}.search__suggestion-item:last-child{border:none}.search__suggestion-description,.search__suggestion-title{margin:1rem 0;padding:0 1rem}.search__suggestion-title{font-weight:700}.search__suggestion-description{border-left:1px solid var(--bg2)}.search__no-results{padding:.75rem}
+

\ No newline at end of file diff --git a/public/post/index.html b/public/post/index.html index 85d295fe..57e561f1 100644 --- a/public/post/index.html +++ b/public/post/index.html @@ -1,184 +1,11 @@ - - - - Posts - davegallant - - - - - - - +Posts +
+

Posts

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

Read more >

Running K3s in LXC on Proxmox

It has been a while since I’ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I’ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it’d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.
Read more >

Automatically rotating AWS access keys

Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.
Read more >

Why I threw out my dotfiles

Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (~/.zshrc, ~/.config/git/config, ~/.config/tmux/tmux.conf, etc). I have tried several different ways to manage them, including bare git repos and utilities such as GNU Stow. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: home-manager.

Read more >
\ No newline at end of file diff --git a/public/post/index.xml b/public/post/index.xml index ef884d54..9fe43d07 100644 --- a/public/post/index.xml +++ b/public/post/index.xml @@ -1,90 +1,26 @@ - - - - Posts on davegallant - /post/ - Recent content in Posts on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - Setting up Gitea Actions with Tailscale - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - Backing up gmail with Synology - /blog/2022/03/13/backing-up-gmail-with-synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /blog/2022/03/13/backing-up-gmail-with-synology/ - - - - Running K3s in LXC on Proxmox - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - Sun, 14 Nov 2021 10:07:03 -0500 - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. - - - Replacing docker with podman on macOS (and Linux) - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - Mon, 11 Oct 2021 10:43:35 -0400 - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - - - - Automatically rotating AWS access keys - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - Fri, 17 Sep 2021 12:48:33 -0400 - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - - - - Why I threw out my dotfiles - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - Wed, 08 Sep 2021 00:42:33 -0400 - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - AppGate SDP on Arch Linux - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - Mon, 16 Mar 2020 22:00:15 -0400 - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - <p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> - - - +Posts onhttps://davegallant.ca/post/Recent content in Posts onHugo -- gohugo.ioen-usDave GallantSun, 10 Dec 2023 17:22:11 -0500Setting up Gitea Actions with Tailscalehttps://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/<p>In this post I&rsquo;ll go through the process of setting up Gitea Actions and <a +href="https://tailscale.com/" +class="link--external" target="_blank" rel="noreferrer" +>Tailscale</a>, unlocking a simple and secure way to automate workflows.</p>Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p>Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p>Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p>Backing up gmail with Synologyhttps://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/<p>I&rsquo;ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.</p>Running K3s in LXC on Proxmoxhttps://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.Replacing docker with podman on macOS (and Linux)https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/<p>There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker:</p>Automatically rotating AWS access keyshttps://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.Why I threw out my dotfileshttps://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/<p>Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (<code>~/.zshrc</code>, <code>~/.config/git/config</code>, <code>~/.config/tmux/tmux.conf</code>, etc). I have tried several different ways to manage them, including <a +href="https://www.atlassian.com/git/tutorials/dotfiles" +class="link--external" target="_blank" rel="noreferrer" +>bare git repos</a> and utilities such as <a +href="https://www.gnu.org/software/stow/" +class="link--external" target="_blank" rel="noreferrer" +>GNU Stow</a>. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: <a +href="https://github.com/nix-community/home-manager" +class="link--external" target="_blank" rel="noreferrer" +>home-manager</a>.</p>What to do with a homelabhttps://davegallant.ca/blog/2021/09/06/what-to-do-with-a-homelab/Mon, 06 Sep 2021 01:12:54 -0400https://davegallant.ca/blog/2021/09/06/what-to-do-with-a-homelab/<p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p>AppGate SDP on Arch Linuxhttps://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/Mon, 16 Mar 2020 22:00:15 -0400https://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/<p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> \ No newline at end of file diff --git a/public/post/page/1/index.html b/public/post/page/1/index.html new file mode 100644 index 00000000..d62b55b7 --- /dev/null +++ b/public/post/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/post/ + \ No newline at end of file diff --git a/public/post/page/2/index.html b/public/post/page/2/index.html new file mode 100644 index 00000000..c620f945 --- /dev/null +++ b/public/post/page/2/index.html @@ -0,0 +1,11 @@ +Posts +
+

Posts

\ No newline at end of file diff --git a/public/prism-themes/prism-gruvbox-dark.min.54aecc64074623a4f9898544dcbdab9e804f1560ef0b38f4cf8e10fcaaf72264e798cb407c601aca6ecd833ec4eb93d66535581f18d45ba202cf848b70dbc332.css b/public/prism-themes/prism-gruvbox-dark.min.54aecc64074623a4f9898544dcbdab9e804f1560ef0b38f4cf8e10fcaaf72264e798cb407c601aca6ecd833ec4eb93d66535581f18d45ba202cf848b70dbc332.css new file mode 100644 index 00000000..85461d3e --- /dev/null +++ b/public/prism-themes/prism-gruvbox-dark.min.54aecc64074623a4f9898544dcbdab9e804f1560ef0b38f4cf8e10fcaaf72264e798cb407c601aca6ecd833ec4eb93d66535581f18d45ba202cf848b70dbc332.css @@ -0,0 +1 @@ +code[class*=language-],pre[class*=language-]{color:#ebdbb2;font-family:Consolas,Monaco,andale mono,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection{color:#fbf1c7;background:#7c6f64}pre[class*=language-]::selection,pre[class*=language-] ::selection,code[class*=language-]::selection,code[class*=language-] ::selection{color:#fbf1c7;background:#7c6f64}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#1d2021}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.comment,.token.prolog,.token.cdata{color:#a89984}.token.delimiter,.token.boolean,.token.keyword,.token.selector,.token.important,.token.atrule{color:#fb4934}.token.operator,.token.punctuation,.token.attr-name{color:#a89984}.token.tag,.token.tag .punctuation,.token.doctype,.token.builtin{color:#fabd2f}.token.entity,.token.number,.token.symbol{color:#d3869b}.token.property,.token.constant,.token.variable{color:#fb4934}.token.string,.token.char{color:#b8bb26}.token.attr-value,.token.attr-value .punctuation{color:#a89984}.token.url{color:#b8bb26;text-decoration:underline}.token.function{color:#fabd2f}.token.regex{background:#b8bb26}.token.bold{font-weight:700}.token.italic{font-style:italic}.token.inserted{background:#a89984}.token.deleted{background:#fb4934} \ No newline at end of file diff --git a/public/prism-themes/prism-gruvbox-light.min.42a221741efe997fcc94187c39d63c555560678789ac9ca856c74a5f0ddb2aa6c50d38b2ffbecc7a99038cbbd2efa99746e862267f781c559e0cfec10b88a5fc.css b/public/prism-themes/prism-gruvbox-light.min.42a221741efe997fcc94187c39d63c555560678789ac9ca856c74a5f0ddb2aa6c50d38b2ffbecc7a99038cbbd2efa99746e862267f781c559e0cfec10b88a5fc.css new file mode 100644 index 00000000..70760814 --- /dev/null +++ b/public/prism-themes/prism-gruvbox-light.min.42a221741efe997fcc94187c39d63c555560678789ac9ca856c74a5f0ddb2aa6c50d38b2ffbecc7a99038cbbd2efa99746e862267f781c559e0cfec10b88a5fc.css @@ -0,0 +1 @@ +code[class*=language-],pre[class*=language-]{color:#3c3836;font-family:Consolas,Monaco,andale mono,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection{color:#282828;background:#a89984}pre[class*=language-]::selection,pre[class*=language-] ::selection,code[class*=language-]::selection,code[class*=language-] ::selection{color:#282828;background:#a89984}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f9f5d7}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.comment,.token.prolog,.token.cdata{color:#7c6f64}.token.delimiter,.token.boolean,.token.keyword,.token.selector,.token.important,.token.atrule{color:#9d0006}.token.operator,.token.punctuation,.token.attr-name{color:#7c6f64}.token.tag,.token.tag .punctuation,.token.doctype,.token.builtin{color:#b57614}.token.entity,.token.number,.token.symbol{color:#8f3f71}.token.property,.token.constant,.token.variable{color:#9d0006}.token.string,.token.char{color:#797403}.token.attr-value,.token.attr-value .punctuation{color:#7c6f64}.token.url{color:#797403;text-decoration:underline}.token.function{color:#b57614}.token.regex{background:#797403}.token.bold{font-weight:700}.token.italic{font-style:italic}.token.inserted{background:#7c6f64}.token.deleted{background:#9d0006} \ No newline at end of file diff --git a/public/richard-hendricks.webp b/public/richard-hendricks.webp new file mode 100644 index 00000000..570ed0c3 Binary files /dev/null and b/public/richard-hendricks.webp differ diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg new file mode 100644 index 00000000..927bb59c --- /dev/null +++ b/public/safari-pinned-tab.svg @@ -0,0 +1,37 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 00000000..26228d21 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "hugo-theme-gruvbox", + "short_name": "hugo-theme-gruvbox", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#282828", + "background_color": "#282828", + "display": "standalone" +} diff --git a/public/sitemap.xml b/public/sitemap.xml index 78fd965a..15c4b465 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -1,210 +1 @@ - - - - /about/ - - / - 2023-12-10T17:22:11-05:00 - - /tags/gitea/ - 2023-12-10T17:22:11-05:00 - - /tags/gitea-actions/ - 2023-12-10T17:22:11-05:00 - - /tags/github-actions/ - 2023-12-10T17:22:11-05:00 - - /post/ - 2023-12-10T17:22:11-05:00 - - /tags/self-hosted/ - 2023-12-10T17:22:11-05:00 - - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - 2023-12-10T17:22:11-05:00 - - /tags/ - 2023-12-10T17:22:11-05:00 - - /tags/tailscale/ - 2023-12-10T17:22:11-05:00 - - /tags/aks/ - 2023-05-22T16:31:29-04:00 - - /tags/aws/ - 2023-05-22T16:31:29-04:00 - - /tags/azure/ - 2023-05-22T16:31:29-04:00 - - /tags/bastion/ - 2023-05-22T16:31:29-04:00 - - /tags/cloud-sql-proxy/ - 2023-05-22T16:31:29-04:00 - - /tags/database/ - 2023-05-22T16:31:29-04:00 - - /tags/eks/ - 2023-05-22T16:31:29-04:00 - - /tags/k8s/ - 2023-05-22T16:31:29-04:00 - - /tags/kubectl-plugin-socks5-proxy/ - 2023-05-22T16:31:29-04:00 - - /tags/proxy/ - 2023-05-22T16:31:29-04:00 - - /tags/socat/ - 2023-05-22T16:31:29-04:00 - - /tags/socks/ - 2023-05-22T16:31:29-04:00 - - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - 2023-05-22T16:31:29-04:00 - - /tags/degoogle/ - 2022-12-10T21:46:55-05:00 - - /tags/invidious/ - 2022-12-10T21:46:55-05:00 - - /tags/privacy/ - 2022-12-10T21:46:55-05:00 - - /blog/2022/12/10/watching-youtube-in-private/ - 2022-12-10T21:46:55-05:00 - - /tags/yewtu.be/ - 2022-12-10T21:46:55-05:00 - - /tags/youtube/ - 2022-12-10T21:46:55-05:00 - - /tags/openwrt/ - 2022-04-02T18:50:09-04:00 - - /tags/pfsense/ - 2022-04-02T18:50:09-04:00 - - /tags/proxmox/ - 2022-04-02T18:50:09-04:00 - - /tags/router/ - 2022-04-02T18:50:09-04:00 - - /tags/router-on-a-stick/ - 2022-04-02T18:50:09-04:00 - - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - 2022-04-02T18:50:09-04:00 - - /tags/vlan/ - 2022-04-02T18:50:09-04:00 - - /blog/2022/03/13/backing-up-gmail-with-synology/ - 2022-03-13T18:49:10-04:00 - - /tags/backup/ - 2022-03-13T18:49:10-04:00 - - /tags/gmail/ - 2022-03-13T18:49:10-04:00 - - /tags/ransomware/ - 2022-03-13T18:49:10-04:00 - - /tags/synology/ - 2022-03-13T18:49:10-04:00 - - /tags/k3s/ - 2021-11-14T10:07:03-05:00 - - /tags/lxc/ - 2021-11-14T10:07:03-05:00 - - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - 2021-11-14T10:07:03-05:00 - - /tags/containers/ - 2021-10-11T10:43:35-04:00 - - /tags/docker/ - 2021-10-11T10:43:35-04:00 - - /tags/podman/ - 2021-10-11T10:43:35-04:00 - - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - 2021-10-11T10:43:35-04:00 - - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - 2021-09-17T12:48:33-04:00 - - /tags/aws-vault/ - 2021-09-17T12:48:33-04:00 - - /tags/python/ - 2021-09-17T12:48:33-04:00 - - /tags/security/ - 2021-09-17T12:48:33-04:00 - - /tags/dotfiles/ - 2021-09-08T00:42:33-04:00 - - /tags/home-manager/ - 2021-09-08T00:42:33-04:00 - - /tags/nix/ - 2021-09-08T00:42:33-04:00 - - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - 2021-09-08T00:42:33-04:00 - - /tags/adguard/ - 2021-09-06T01:12:54-04:00 - - /tags/grafana/ - 2021-09-06T01:12:54-04:00 - - /tags/homelab/ - 2021-09-06T01:12:54-04:00 - - /tags/jellyfin/ - 2021-09-06T01:12:54-04:00 - - /tags/netdata/ - 2021-09-06T01:12:54-04:00 - - /tags/pihole/ - 2021-09-06T01:12:54-04:00 - - /tags/plex/ - 2021-09-06T01:12:54-04:00 - - /tags/virtualization/ - 2021-09-06T01:12:54-04:00 - - /blog/2021/09/06/what-to-do-with-a-homelab/ - 2021-09-06T01:12:54-04:00 - - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - 2020-03-16T22:00:15-04:00 - - /tags/linux/ - 2020-03-16T22:00:15-04:00 - - /tags/vpn/ - 2020-03-16T22:00:15-04:00 - - /categories/ - - +https://davegallant.ca/en/sitemap.xml2023-12-10T17:22:11-05:00https://davegallant.ca/de/sitemap.xml \ No newline at end of file diff --git a/public/tags/adguard/index.html b/public/tags/adguard/index.html deleted file mode 100644 index 653b5306..00000000 --- a/public/tags/adguard/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - adguard - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "adguard"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/adguard/index.xml b/public/tags/adguard/index.xml deleted file mode 100644 index ae85989e..00000000 --- a/public/tags/adguard/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - adguard on davegallant - /tags/adguard/ - Recent content in adguard on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/aks/index.html b/public/tags/aks/index.html index be248656..dc0feef4 100644 --- a/public/tags/aks/index.html +++ b/public/tags/aks/index.html @@ -1,164 +1,10 @@ - - - - aks - davegallant - - - - - - - +aks +
+

aks

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/aks/index.xml b/public/tags/aks/index.xml index 707d33fe..2aa3cfb6 100644 --- a/public/tags/aks/index.xml +++ b/public/tags/aks/index.xml @@ -1,20 +1 @@ - - - - aks on davegallant - /tags/aks/ - Recent content in aks on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +aks onhttps://davegallant.ca/tags/aks/Recent content in aks onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/aks/page/1/index.html b/public/tags/aks/page/1/index.html new file mode 100644 index 00000000..88d67da2 --- /dev/null +++ b/public/tags/aks/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/aks/ + \ No newline at end of file diff --git a/public/tags/aws-vault/index.html b/public/tags/aws-vault/index.html index 054b5dbe..53dd97e7 100644 --- a/public/tags/aws-vault/index.html +++ b/public/tags/aws-vault/index.html @@ -1,164 +1,11 @@ - - - - aws-vault - davegallant - - - - - - - +aws-vault +
+

aws-vault

Automatically rotating AWS access keys

Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.
Read more >
\ No newline at end of file diff --git a/public/tags/aws-vault/index.xml b/public/tags/aws-vault/index.xml index 401bc6f1..f9636cfe 100644 --- a/public/tags/aws-vault/index.xml +++ b/public/tags/aws-vault/index.xml @@ -1,20 +1,2 @@ - - - - aws-vault on davegallant - /tags/aws-vault/ - Recent content in aws-vault on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Fri, 17 Sep 2021 12:48:33 -0400 - - - Automatically rotating AWS access keys - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - Fri, 17 Sep 2021 12:48:33 -0400 - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - - - - +aws-vault onhttps://davegallant.ca/tags/aws-vault/Recent content in aws-vault onHugo -- gohugo.ioen-usDave GallantFri, 17 Sep 2021 12:48:33 -0400Automatically rotating AWS access keyshttps://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution. \ No newline at end of file diff --git a/public/tags/aws-vault/page/1/index.html b/public/tags/aws-vault/page/1/index.html new file mode 100644 index 00000000..3c2c7d61 --- /dev/null +++ b/public/tags/aws-vault/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/aws-vault/ + \ No newline at end of file diff --git a/public/tags/aws/index.html b/public/tags/aws/index.html index 42f89099..8a45a246 100644 --- a/public/tags/aws/index.html +++ b/public/tags/aws/index.html @@ -1,166 +1,11 @@ - - - - aws - davegallant - - - - - - - +aws +
+

aws

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >

Automatically rotating AWS access keys

Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.
Read more >
\ No newline at end of file diff --git a/public/tags/aws/index.xml b/public/tags/aws/index.xml index 3f0c7757..887343b2 100644 --- a/public/tags/aws/index.xml +++ b/public/tags/aws/index.xml @@ -1,27 +1,2 @@ - - - - aws on davegallant - /tags/aws/ - Recent content in aws on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - Automatically rotating AWS access keys - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - Fri, 17 Sep 2021 12:48:33 -0400 - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - - - - +aws onhttps://davegallant.ca/tags/aws/Recent content in aws onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p>Automatically rotating AWS access keyshttps://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution. \ No newline at end of file diff --git a/public/tags/aws/page/1/index.html b/public/tags/aws/page/1/index.html new file mode 100644 index 00000000..418ba199 --- /dev/null +++ b/public/tags/aws/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/aws/ + \ No newline at end of file diff --git a/public/tags/azure/index.html b/public/tags/azure/index.html index d7ed5c85..05dd7c42 100644 --- a/public/tags/azure/index.html +++ b/public/tags/azure/index.html @@ -1,164 +1,10 @@ - - - - azure - davegallant - - - - - - - +azure +
+

azure

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/azure/index.xml b/public/tags/azure/index.xml index 7c8445cf..260889d4 100644 --- a/public/tags/azure/index.xml +++ b/public/tags/azure/index.xml @@ -1,20 +1 @@ - - - - azure on davegallant - /tags/azure/ - Recent content in azure on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +azure onhttps://davegallant.ca/tags/azure/Recent content in azure onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/azure/page/1/index.html b/public/tags/azure/page/1/index.html new file mode 100644 index 00000000..ddbca9d2 --- /dev/null +++ b/public/tags/azure/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/azure/ + \ No newline at end of file diff --git a/public/tags/backup/index.html b/public/tags/backup/index.html index 577147dc..c87f6650 100644 --- a/public/tags/backup/index.html +++ b/public/tags/backup/index.html @@ -1,164 +1,10 @@ - - - - backup - davegallant - - - - - - - +backup +
+

backup

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

Read more >
\ No newline at end of file diff --git a/public/tags/backup/index.xml b/public/tags/backup/index.xml index fe290b4e..559602da 100644 --- a/public/tags/backup/index.xml +++ b/public/tags/backup/index.xml @@ -1,20 +1 @@ - - - - backup on davegallant - /tags/backup/ - Recent content in backup on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 13 Mar 2022 18:49:10 -0400 - - - Backing up gmail with Synology - /blog/2022/03/13/backing-up-gmail-with-synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /blog/2022/03/13/backing-up-gmail-with-synology/ - - - - +backup onhttps://davegallant.ca/tags/backup/Recent content in backup onHugo -- gohugo.ioen-usDave GallantSun, 13 Mar 2022 18:49:10 -0400Backing up gmail with Synologyhttps://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/<p>I&rsquo;ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.</p> \ No newline at end of file diff --git a/public/tags/backup/page/1/index.html b/public/tags/backup/page/1/index.html new file mode 100644 index 00000000..c2cd852b --- /dev/null +++ b/public/tags/backup/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/backup/ + \ No newline at end of file diff --git a/public/tags/bastion/index.html b/public/tags/bastion/index.html index 63f4a40e..f4bab744 100644 --- a/public/tags/bastion/index.html +++ b/public/tags/bastion/index.html @@ -1,164 +1,10 @@ - - - - bastion - davegallant - - - - - - - +bastion +
+

bastion

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/bastion/index.xml b/public/tags/bastion/index.xml index 342ac5e4..bd233403 100644 --- a/public/tags/bastion/index.xml +++ b/public/tags/bastion/index.xml @@ -1,20 +1 @@ - - - - bastion on davegallant - /tags/bastion/ - Recent content in bastion on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +bastion onhttps://davegallant.ca/tags/bastion/Recent content in bastion onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/bastion/page/1/index.html b/public/tags/bastion/page/1/index.html new file mode 100644 index 00000000..3995775b --- /dev/null +++ b/public/tags/bastion/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/bastion/ + \ No newline at end of file diff --git a/public/tags/cloud-sql-proxy/index.html b/public/tags/cloud-sql-proxy/index.html index 5492cfcf..2ccd9194 100644 --- a/public/tags/cloud-sql-proxy/index.html +++ b/public/tags/cloud-sql-proxy/index.html @@ -1,164 +1,10 @@ - - - - cloud-sql-proxy - davegallant - - - - - - - +cloud-sql-proxy +
+

cloud-sql-proxy

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/cloud-sql-proxy/index.xml b/public/tags/cloud-sql-proxy/index.xml index 1f44bf97..8d1bba22 100644 --- a/public/tags/cloud-sql-proxy/index.xml +++ b/public/tags/cloud-sql-proxy/index.xml @@ -1,20 +1 @@ - - - - cloud-sql-proxy on davegallant - /tags/cloud-sql-proxy/ - Recent content in cloud-sql-proxy on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +cloud-sql-proxy onhttps://davegallant.ca/tags/cloud-sql-proxy/Recent content in cloud-sql-proxy onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/cloud-sql-proxy/page/1/index.html b/public/tags/cloud-sql-proxy/page/1/index.html new file mode 100644 index 00000000..38574192 --- /dev/null +++ b/public/tags/cloud-sql-proxy/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/cloud-sql-proxy/ + \ No newline at end of file diff --git a/public/tags/containers/index.html b/public/tags/containers/index.html index bd5b7f44..b3fac91d 100644 --- a/public/tags/containers/index.html +++ b/public/tags/containers/index.html @@ -1,164 +1,10 @@ - - - - containers - davegallant - - - - - - - +containers +
+

containers

\ No newline at end of file diff --git a/public/tags/containers/index.xml b/public/tags/containers/index.xml index 2e8af29b..2d92c824 100644 --- a/public/tags/containers/index.xml +++ b/public/tags/containers/index.xml @@ -1,20 +1 @@ - - - - containers on davegallant - /tags/containers/ - Recent content in containers on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 11 Oct 2021 10:43:35 -0400 - - - Replacing docker with podman on macOS (and Linux) - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - Mon, 11 Oct 2021 10:43:35 -0400 - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - - - - +containers onhttps://davegallant.ca/tags/containers/Recent content in containers onHugo -- gohugo.ioen-usDave GallantMon, 11 Oct 2021 10:43:35 -0400Replacing docker with podman on macOS (and Linux)https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/<p>There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker:</p> \ No newline at end of file diff --git a/public/tags/containers/page/1/index.html b/public/tags/containers/page/1/index.html new file mode 100644 index 00000000..8263919b --- /dev/null +++ b/public/tags/containers/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/containers/ + \ No newline at end of file diff --git a/public/tags/database/index.html b/public/tags/database/index.html index 2bbd7de7..efdfdd9c 100644 --- a/public/tags/database/index.html +++ b/public/tags/database/index.html @@ -1,164 +1,10 @@ - - - - database - davegallant - - - - - - - +database +
+

database

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/database/index.xml b/public/tags/database/index.xml index 5cb12113..9e069a7c 100644 --- a/public/tags/database/index.xml +++ b/public/tags/database/index.xml @@ -1,20 +1 @@ - - - - database on davegallant - /tags/database/ - Recent content in database on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +database onhttps://davegallant.ca/tags/database/Recent content in database onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/database/page/1/index.html b/public/tags/database/page/1/index.html new file mode 100644 index 00000000..4ce5b9ef --- /dev/null +++ b/public/tags/database/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/database/ + \ No newline at end of file diff --git a/public/tags/degoogle/index.html b/public/tags/degoogle/index.html index 75fc0344..f84223d0 100644 --- a/public/tags/degoogle/index.html +++ b/public/tags/degoogle/index.html @@ -1,166 +1,10 @@ - - - - degoogle - davegallant - - - - - - - +degoogle +
+

degoogle

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

Read more >
\ No newline at end of file diff --git a/public/tags/degoogle/index.xml b/public/tags/degoogle/index.xml index d5d12219..7aa8652e 100644 --- a/public/tags/degoogle/index.xml +++ b/public/tags/degoogle/index.xml @@ -1,27 +1,7 @@ - - - - degoogle on davegallant - /tags/degoogle/ - Recent content in degoogle on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 10 Dec 2022 21:46:55 -0500 - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - Backing up gmail with Synology - /blog/2022/03/13/backing-up-gmail-with-synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /blog/2022/03/13/backing-up-gmail-with-synology/ - - - - +degoogle onhttps://davegallant.ca/tags/degoogle/Recent content in degoogle onHugo -- gohugo.ioen-usDave GallantSat, 10 Dec 2022 21:46:55 -0500Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p>Backing up gmail with Synologyhttps://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/<p>I&rsquo;ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.</p> \ No newline at end of file diff --git a/public/tags/degoogle/page/1/index.html b/public/tags/degoogle/page/1/index.html new file mode 100644 index 00000000..18580c40 --- /dev/null +++ b/public/tags/degoogle/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/degoogle/ + \ No newline at end of file diff --git a/public/tags/docker/index.html b/public/tags/docker/index.html index 67d680ea..daa6b60f 100644 --- a/public/tags/docker/index.html +++ b/public/tags/docker/index.html @@ -1,164 +1,10 @@ - - - - docker - davegallant - - - - - - - +docker +
+

docker

\ No newline at end of file diff --git a/public/tags/docker/index.xml b/public/tags/docker/index.xml index 3d4a4099..6b33030a 100644 --- a/public/tags/docker/index.xml +++ b/public/tags/docker/index.xml @@ -1,20 +1 @@ - - - - docker on davegallant - /tags/docker/ - Recent content in docker on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 11 Oct 2021 10:43:35 -0400 - - - Replacing docker with podman on macOS (and Linux) - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - Mon, 11 Oct 2021 10:43:35 -0400 - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - - - - +docker onhttps://davegallant.ca/tags/docker/Recent content in docker onHugo -- gohugo.ioen-usDave GallantMon, 11 Oct 2021 10:43:35 -0400Replacing docker with podman on macOS (and Linux)https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/<p>There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker:</p> \ No newline at end of file diff --git a/public/tags/docker/page/1/index.html b/public/tags/docker/page/1/index.html new file mode 100644 index 00000000..16f39441 --- /dev/null +++ b/public/tags/docker/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/docker/ + \ No newline at end of file diff --git a/public/tags/dotfiles/index.html b/public/tags/dotfiles/index.html index edd6fc00..aef8a6e4 100644 --- a/public/tags/dotfiles/index.html +++ b/public/tags/dotfiles/index.html @@ -1,164 +1,10 @@ - - - - dotfiles - davegallant - - - - - - - +dotfiles +
+

dotfiles

Why I threw out my dotfiles

Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (~/.zshrc, ~/.config/git/config, ~/.config/tmux/tmux.conf, etc). I have tried several different ways to manage them, including bare git repos and utilities such as GNU Stow. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: home-manager.

Read more >
\ No newline at end of file diff --git a/public/tags/dotfiles/index.xml b/public/tags/dotfiles/index.xml index e3da0e41..ac227db3 100644 --- a/public/tags/dotfiles/index.xml +++ b/public/tags/dotfiles/index.xml @@ -1,20 +1,10 @@ - - - - dotfiles on davegallant - /tags/dotfiles/ - Recent content in dotfiles on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Wed, 08 Sep 2021 00:42:33 -0400 - - - Why I threw out my dotfiles - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - Wed, 08 Sep 2021 00:42:33 -0400 - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - - - - +dotfiles onhttps://davegallant.ca/tags/dotfiles/Recent content in dotfiles onHugo -- gohugo.ioen-usDave GallantWed, 08 Sep 2021 00:42:33 -0400Why I threw out my dotfileshttps://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/<p>Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (<code>~/.zshrc</code>, <code>~/.config/git/config</code>, <code>~/.config/tmux/tmux.conf</code>, etc). I have tried several different ways to manage them, including <a +href="https://www.atlassian.com/git/tutorials/dotfiles" +class="link--external" target="_blank" rel="noreferrer" +>bare git repos</a> and utilities such as <a +href="https://www.gnu.org/software/stow/" +class="link--external" target="_blank" rel="noreferrer" +>GNU Stow</a>. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: <a +href="https://github.com/nix-community/home-manager" +class="link--external" target="_blank" rel="noreferrer" +>home-manager</a>.</p> \ No newline at end of file diff --git a/public/tags/dotfiles/page/1/index.html b/public/tags/dotfiles/page/1/index.html new file mode 100644 index 00000000..2a67c2e8 --- /dev/null +++ b/public/tags/dotfiles/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/dotfiles/ + \ No newline at end of file diff --git a/public/tags/eks/index.html b/public/tags/eks/index.html index 898cfc08..26eb9642 100644 --- a/public/tags/eks/index.html +++ b/public/tags/eks/index.html @@ -1,164 +1,10 @@ - - - - eks - davegallant - - - - - - - +eks +
+

eks

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/eks/index.xml b/public/tags/eks/index.xml index 762578e9..db5f83bb 100644 --- a/public/tags/eks/index.xml +++ b/public/tags/eks/index.xml @@ -1,20 +1 @@ - - - - eks on davegallant - /tags/eks/ - Recent content in eks on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +eks onhttps://davegallant.ca/tags/eks/Recent content in eks onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/eks/page/1/index.html b/public/tags/eks/page/1/index.html new file mode 100644 index 00000000..0992031c --- /dev/null +++ b/public/tags/eks/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/eks/ + \ No newline at end of file diff --git a/public/tags/gitea-actions/index.html b/public/tags/gitea-actions/index.html index 2b35a12e..da79bf11 100644 --- a/public/tags/gitea-actions/index.html +++ b/public/tags/gitea-actions/index.html @@ -1,164 +1,10 @@ - - - - gitea actions - davegallant - - - - - - - +gitea actions +
+

gitea actions

\ No newline at end of file diff --git a/public/tags/gitea-actions/index.xml b/public/tags/gitea-actions/index.xml index f7fb679d..ddb1f1ce 100644 --- a/public/tags/gitea-actions/index.xml +++ b/public/tags/gitea-actions/index.xml @@ -1,20 +1,4 @@ - - - - gitea actions on davegallant - /tags/gitea-actions/ - Recent content in gitea actions on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - Setting up Gitea Actions with Tailscale - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - - - - +gitea actions onhttps://davegallant.ca/tags/gitea-actions/Recent content in gitea actions onHugo -- gohugo.ioen-usDave GallantSun, 10 Dec 2023 17:22:11 -0500Setting up Gitea Actions with Tailscalehttps://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/<p>In this post I&rsquo;ll go through the process of setting up Gitea Actions and <a +href="https://tailscale.com/" +class="link--external" target="_blank" rel="noreferrer" +>Tailscale</a>, unlocking a simple and secure way to automate workflows.</p> \ No newline at end of file diff --git a/public/tags/gitea-actions/page/1/index.html b/public/tags/gitea-actions/page/1/index.html new file mode 100644 index 00000000..1f74ae55 --- /dev/null +++ b/public/tags/gitea-actions/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/gitea-actions/ + \ No newline at end of file diff --git a/public/tags/gitea/index.html b/public/tags/gitea/index.html index ad1a29d5..e59f1c98 100644 --- a/public/tags/gitea/index.html +++ b/public/tags/gitea/index.html @@ -1,164 +1,10 @@ - - - - gitea - davegallant - - - - - - - +gitea +
+

gitea

\ No newline at end of file diff --git a/public/tags/gitea/index.xml b/public/tags/gitea/index.xml index 16938766..2cb6a598 100644 --- a/public/tags/gitea/index.xml +++ b/public/tags/gitea/index.xml @@ -1,20 +1,4 @@ - - - - gitea on davegallant - /tags/gitea/ - Recent content in gitea on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - Setting up Gitea Actions with Tailscale - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - - - - +gitea onhttps://davegallant.ca/tags/gitea/Recent content in gitea onHugo -- gohugo.ioen-usDave GallantSun, 10 Dec 2023 17:22:11 -0500Setting up Gitea Actions with Tailscalehttps://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/<p>In this post I&rsquo;ll go through the process of setting up Gitea Actions and <a +href="https://tailscale.com/" +class="link--external" target="_blank" rel="noreferrer" +>Tailscale</a>, unlocking a simple and secure way to automate workflows.</p> \ No newline at end of file diff --git a/public/tags/gitea/page/1/index.html b/public/tags/gitea/page/1/index.html new file mode 100644 index 00000000..3eb973a9 --- /dev/null +++ b/public/tags/gitea/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/gitea/ + \ No newline at end of file diff --git a/public/tags/github-actions/index.html b/public/tags/github-actions/index.html index 63411199..c36fdd35 100644 --- a/public/tags/github-actions/index.html +++ b/public/tags/github-actions/index.html @@ -1,164 +1,10 @@ - - - - github actions - davegallant - - - - - - - +github actions +
+

github actions

\ No newline at end of file diff --git a/public/tags/github-actions/index.xml b/public/tags/github-actions/index.xml index 82b11f07..25b2abd4 100644 --- a/public/tags/github-actions/index.xml +++ b/public/tags/github-actions/index.xml @@ -1,20 +1,4 @@ - - - - github actions on davegallant - /tags/github-actions/ - Recent content in github actions on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - Setting up Gitea Actions with Tailscale - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - - - - +github actions onhttps://davegallant.ca/tags/github-actions/Recent content in github actions onHugo -- gohugo.ioen-usDave GallantSun, 10 Dec 2023 17:22:11 -0500Setting up Gitea Actions with Tailscalehttps://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/<p>In this post I&rsquo;ll go through the process of setting up Gitea Actions and <a +href="https://tailscale.com/" +class="link--external" target="_blank" rel="noreferrer" +>Tailscale</a>, unlocking a simple and secure way to automate workflows.</p> \ No newline at end of file diff --git a/public/tags/github-actions/page/1/index.html b/public/tags/github-actions/page/1/index.html new file mode 100644 index 00000000..15c0730a --- /dev/null +++ b/public/tags/github-actions/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/github-actions/ + \ No newline at end of file diff --git a/public/tags/gmail/index.html b/public/tags/gmail/index.html index 082d379d..81d4a726 100644 --- a/public/tags/gmail/index.html +++ b/public/tags/gmail/index.html @@ -1,164 +1,10 @@ - - - - gmail - davegallant - - - - - - - +gmail +
+

gmail

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

Read more >
\ No newline at end of file diff --git a/public/tags/gmail/index.xml b/public/tags/gmail/index.xml index 0a6163fd..86071bf5 100644 --- a/public/tags/gmail/index.xml +++ b/public/tags/gmail/index.xml @@ -1,20 +1 @@ - - - - gmail on davegallant - /tags/gmail/ - Recent content in gmail on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 13 Mar 2022 18:49:10 -0400 - - - Backing up gmail with Synology - /blog/2022/03/13/backing-up-gmail-with-synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /blog/2022/03/13/backing-up-gmail-with-synology/ - - - - +gmail onhttps://davegallant.ca/tags/gmail/Recent content in gmail onHugo -- gohugo.ioen-usDave GallantSun, 13 Mar 2022 18:49:10 -0400Backing up gmail with Synologyhttps://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/<p>I&rsquo;ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.</p> \ No newline at end of file diff --git a/public/tags/gmail/page/1/index.html b/public/tags/gmail/page/1/index.html new file mode 100644 index 00000000..a6186dd4 --- /dev/null +++ b/public/tags/gmail/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/gmail/ + \ No newline at end of file diff --git a/public/tags/grafana/index.html b/public/tags/grafana/index.html deleted file mode 100644 index 95035184..00000000 --- a/public/tags/grafana/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - grafana - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "grafana"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/grafana/index.xml b/public/tags/grafana/index.xml deleted file mode 100644 index 12ba4752..00000000 --- a/public/tags/grafana/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - grafana on davegallant - /tags/grafana/ - Recent content in grafana on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/home-manager/index.html b/public/tags/home-manager/index.html index fbd4ba67..ccf81d95 100644 --- a/public/tags/home-manager/index.html +++ b/public/tags/home-manager/index.html @@ -1,164 +1,10 @@ - - - - home-manager - davegallant - - - - - - - +home-manager +
+

home-manager

Why I threw out my dotfiles

Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (~/.zshrc, ~/.config/git/config, ~/.config/tmux/tmux.conf, etc). I have tried several different ways to manage them, including bare git repos and utilities such as GNU Stow. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: home-manager.

Read more >
\ No newline at end of file diff --git a/public/tags/home-manager/index.xml b/public/tags/home-manager/index.xml index ec6775eb..63097033 100644 --- a/public/tags/home-manager/index.xml +++ b/public/tags/home-manager/index.xml @@ -1,20 +1,10 @@ - - - - home-manager on davegallant - /tags/home-manager/ - Recent content in home-manager on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Wed, 08 Sep 2021 00:42:33 -0400 - - - Why I threw out my dotfiles - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - Wed, 08 Sep 2021 00:42:33 -0400 - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - - - - +home-manager onhttps://davegallant.ca/tags/home-manager/Recent content in home-manager onHugo -- gohugo.ioen-usDave GallantWed, 08 Sep 2021 00:42:33 -0400Why I threw out my dotfileshttps://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/<p>Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (<code>~/.zshrc</code>, <code>~/.config/git/config</code>, <code>~/.config/tmux/tmux.conf</code>, etc). I have tried several different ways to manage them, including <a +href="https://www.atlassian.com/git/tutorials/dotfiles" +class="link--external" target="_blank" rel="noreferrer" +>bare git repos</a> and utilities such as <a +href="https://www.gnu.org/software/stow/" +class="link--external" target="_blank" rel="noreferrer" +>GNU Stow</a>. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: <a +href="https://github.com/nix-community/home-manager" +class="link--external" target="_blank" rel="noreferrer" +>home-manager</a>.</p> \ No newline at end of file diff --git a/public/tags/home-manager/page/1/index.html b/public/tags/home-manager/page/1/index.html new file mode 100644 index 00000000..d6fe0a36 --- /dev/null +++ b/public/tags/home-manager/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/home-manager/ + \ No newline at end of file diff --git a/public/tags/homelab/index.html b/public/tags/homelab/index.html deleted file mode 100644 index f96b7390..00000000 --- a/public/tags/homelab/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - homelab - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "homelab"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/homelab/index.xml b/public/tags/homelab/index.xml deleted file mode 100644 index 81e3fa46..00000000 --- a/public/tags/homelab/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - homelab on davegallant - /tags/homelab/ - Recent content in homelab on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/index.html b/public/tags/index.html index 0025440d..baec6ebb 100644 --- a/public/tags/index.html +++ b/public/tags/index.html @@ -1,383 +1,10 @@ - - - - Tags - davegallant - - - - - - - +Tags +
+

Tags

\ No newline at end of file diff --git a/public/tags/index.xml b/public/tags/index.xml index 81e719ec..64b2e494 100644 --- a/public/tags/index.xml +++ b/public/tags/index.xml @@ -1,384 +1 @@ - - - - Tags on davegallant - /tags/ - Recent content in Tags on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - gitea - /tags/gitea/ - Sun, 10 Dec 2023 17:22:11 -0500 - /tags/gitea/ - - - - gitea actions - /tags/gitea-actions/ - Sun, 10 Dec 2023 17:22:11 -0500 - /tags/gitea-actions/ - - - - github actions - /tags/github-actions/ - Sun, 10 Dec 2023 17:22:11 -0500 - /tags/github-actions/ - - - - self-hosted - /tags/self-hosted/ - Sun, 10 Dec 2023 17:22:11 -0500 - /tags/self-hosted/ - - - - tailscale - /tags/tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /tags/tailscale/ - - - - aks - /tags/aks/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/aks/ - - - - aws - /tags/aws/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/aws/ - - - - azure - /tags/azure/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/azure/ - - - - bastion - /tags/bastion/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/bastion/ - - - - cloud-sql-proxy - /tags/cloud-sql-proxy/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/cloud-sql-proxy/ - - - - database - /tags/database/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/database/ - - - - eks - /tags/eks/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/eks/ - - - - k8s - /tags/k8s/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/k8s/ - - - - kubectl-plugin-socks5-proxy - /tags/kubectl-plugin-socks5-proxy/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/kubectl-plugin-socks5-proxy/ - - - - proxy - /tags/proxy/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/proxy/ - - - - socat - /tags/socat/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/socat/ - - - - socks - /tags/socks/ - Mon, 22 May 2023 16:31:29 -0400 - /tags/socks/ - - - - degoogle - /tags/degoogle/ - Sat, 10 Dec 2022 21:46:55 -0500 - /tags/degoogle/ - - - - invidious - /tags/invidious/ - Sat, 10 Dec 2022 21:46:55 -0500 - /tags/invidious/ - - - - privacy - /tags/privacy/ - Sat, 10 Dec 2022 21:46:55 -0500 - /tags/privacy/ - - - - yewtu.be - /tags/yewtu.be/ - Sat, 10 Dec 2022 21:46:55 -0500 - /tags/yewtu.be/ - - - - youtube - /tags/youtube/ - Sat, 10 Dec 2022 21:46:55 -0500 - /tags/youtube/ - - - - openwrt - /tags/openwrt/ - Sat, 02 Apr 2022 18:50:09 -0400 - /tags/openwrt/ - - - - pfsense - /tags/pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /tags/pfsense/ - - - - proxmox - /tags/proxmox/ - Sat, 02 Apr 2022 18:50:09 -0400 - /tags/proxmox/ - - - - router - /tags/router/ - Sat, 02 Apr 2022 18:50:09 -0400 - /tags/router/ - - - - router-on-a-stick - /tags/router-on-a-stick/ - Sat, 02 Apr 2022 18:50:09 -0400 - /tags/router-on-a-stick/ - - - - vlan - /tags/vlan/ - Sat, 02 Apr 2022 18:50:09 -0400 - /tags/vlan/ - - - - backup - /tags/backup/ - Sun, 13 Mar 2022 18:49:10 -0400 - /tags/backup/ - - - - gmail - /tags/gmail/ - Sun, 13 Mar 2022 18:49:10 -0400 - /tags/gmail/ - - - - ransomware - /tags/ransomware/ - Sun, 13 Mar 2022 18:49:10 -0400 - /tags/ransomware/ - - - - synology - /tags/synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /tags/synology/ - - - - k3s - /tags/k3s/ - Sun, 14 Nov 2021 10:07:03 -0500 - /tags/k3s/ - - - - lxc - /tags/lxc/ - Sun, 14 Nov 2021 10:07:03 -0500 - /tags/lxc/ - - - - containers - /tags/containers/ - Mon, 11 Oct 2021 10:43:35 -0400 - /tags/containers/ - - - - docker - /tags/docker/ - Mon, 11 Oct 2021 10:43:35 -0400 - /tags/docker/ - - - - podman - /tags/podman/ - Mon, 11 Oct 2021 10:43:35 -0400 - /tags/podman/ - - - - aws-vault - /tags/aws-vault/ - Fri, 17 Sep 2021 12:48:33 -0400 - /tags/aws-vault/ - - - - python - /tags/python/ - Fri, 17 Sep 2021 12:48:33 -0400 - /tags/python/ - - - - security - /tags/security/ - Fri, 17 Sep 2021 12:48:33 -0400 - /tags/security/ - - - - dotfiles - /tags/dotfiles/ - Wed, 08 Sep 2021 00:42:33 -0400 - /tags/dotfiles/ - - - - home-manager - /tags/home-manager/ - Wed, 08 Sep 2021 00:42:33 -0400 - /tags/home-manager/ - - - - nix - /tags/nix/ - Wed, 08 Sep 2021 00:42:33 -0400 - /tags/nix/ - - - - adguard - /tags/adguard/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/adguard/ - - - - grafana - /tags/grafana/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/grafana/ - - - - homelab - /tags/homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/homelab/ - - - - jellyfin - /tags/jellyfin/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/jellyfin/ - - - - netdata - /tags/netdata/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/netdata/ - - - - pihole - /tags/pihole/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/pihole/ - - - - plex - /tags/plex/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/plex/ - - - - virtualization - /tags/virtualization/ - Mon, 06 Sep 2021 01:12:54 -0400 - /tags/virtualization/ - - - - linux - /tags/linux/ - Mon, 16 Mar 2020 22:00:15 -0400 - /tags/linux/ - - - - vpn - /tags/vpn/ - Mon, 16 Mar 2020 22:00:15 -0400 - /tags/vpn/ - - - - +Tags onhttps://davegallant.ca/tags/Recent content in Tags onHugo -- gohugo.ioen-usDave GallantSun, 10 Dec 2023 17:22:11 -0500giteahttps://davegallant.ca/tags/gitea/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/tags/gitea/gitea actionshttps://davegallant.ca/tags/gitea-actions/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/tags/gitea-actions/github actionshttps://davegallant.ca/tags/github-actions/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/tags/github-actions/self-hostedhttps://davegallant.ca/tags/self-hosted/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/tags/self-hosted/tailscalehttps://davegallant.ca/tags/tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/tags/tailscale/akshttps://davegallant.ca/tags/aks/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/aks/awshttps://davegallant.ca/tags/aws/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/aws/azurehttps://davegallant.ca/tags/azure/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/azure/bastionhttps://davegallant.ca/tags/bastion/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/bastion/cloud-sql-proxyhttps://davegallant.ca/tags/cloud-sql-proxy/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/cloud-sql-proxy/databasehttps://davegallant.ca/tags/database/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/database/ekshttps://davegallant.ca/tags/eks/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/eks/k8shttps://davegallant.ca/tags/k8s/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/k8s/kubectl-plugin-socks5-proxyhttps://davegallant.ca/tags/kubectl-plugin-socks5-proxy/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/kubectl-plugin-socks5-proxy/proxyhttps://davegallant.ca/tags/proxy/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/proxy/socathttps://davegallant.ca/tags/socat/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/socat/sockshttps://davegallant.ca/tags/socks/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/tags/socks/degooglehttps://davegallant.ca/tags/degoogle/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/tags/degoogle/invidioushttps://davegallant.ca/tags/invidious/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/tags/invidious/privacyhttps://davegallant.ca/tags/privacy/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/tags/privacy/yewtu.behttps://davegallant.ca/tags/yewtu.be/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/tags/yewtu.be/youtubehttps://davegallant.ca/tags/youtube/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/tags/youtube/openwrthttps://davegallant.ca/tags/openwrt/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/tags/openwrt/pfsensehttps://davegallant.ca/tags/pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/tags/pfsense/proxmoxhttps://davegallant.ca/tags/proxmox/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/tags/proxmox/routerhttps://davegallant.ca/tags/router/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/tags/router/router-on-a-stickhttps://davegallant.ca/tags/router-on-a-stick/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/tags/router-on-a-stick/vlanhttps://davegallant.ca/tags/vlan/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/tags/vlan/backuphttps://davegallant.ca/tags/backup/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/tags/backup/gmailhttps://davegallant.ca/tags/gmail/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/tags/gmail/ransomwarehttps://davegallant.ca/tags/ransomware/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/tags/ransomware/synologyhttps://davegallant.ca/tags/synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/tags/synology/k3shttps://davegallant.ca/tags/k3s/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/tags/k3s/lxchttps://davegallant.ca/tags/lxc/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/tags/lxc/containershttps://davegallant.ca/tags/containers/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/tags/containers/dockerhttps://davegallant.ca/tags/docker/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/tags/docker/podmanhttps://davegallant.ca/tags/podman/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/tags/podman/aws-vaulthttps://davegallant.ca/tags/aws-vault/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/tags/aws-vault/pythonhttps://davegallant.ca/tags/python/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/tags/python/securityhttps://davegallant.ca/tags/security/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/tags/security/dotfileshttps://davegallant.ca/tags/dotfiles/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/tags/dotfiles/home-managerhttps://davegallant.ca/tags/home-manager/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/tags/home-manager/nixhttps://davegallant.ca/tags/nix/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/tags/nix/linuxhttps://davegallant.ca/tags/linux/Mon, 16 Mar 2020 22:00:15 -0400https://davegallant.ca/tags/linux/vpnhttps://davegallant.ca/tags/vpn/Mon, 16 Mar 2020 22:00:15 -0400https://davegallant.ca/tags/vpn/ \ No newline at end of file diff --git a/public/tags/invidious/index.html b/public/tags/invidious/index.html index b150122c..c2e0942b 100644 --- a/public/tags/invidious/index.html +++ b/public/tags/invidious/index.html @@ -1,164 +1,10 @@ - - - - invidious - davegallant - - - - - - - +invidious +
+

invidious

\ No newline at end of file diff --git a/public/tags/invidious/index.xml b/public/tags/invidious/index.xml index f943e8f5..b5781a75 100644 --- a/public/tags/invidious/index.xml +++ b/public/tags/invidious/index.xml @@ -1,20 +1,7 @@ - - - - invidious on davegallant - /tags/invidious/ - Recent content in invidious on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 10 Dec 2022 21:46:55 -0500 - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - +invidious onhttps://davegallant.ca/tags/invidious/Recent content in invidious onHugo -- gohugo.ioen-usDave GallantSat, 10 Dec 2022 21:46:55 -0500Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p> \ No newline at end of file diff --git a/public/tags/invidious/page/1/index.html b/public/tags/invidious/page/1/index.html new file mode 100644 index 00000000..dafc2b82 --- /dev/null +++ b/public/tags/invidious/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/invidious/ + \ No newline at end of file diff --git a/public/tags/jellyfin/index.html b/public/tags/jellyfin/index.html deleted file mode 100644 index 94406450..00000000 --- a/public/tags/jellyfin/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - jellyfin - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "jellyfin"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/jellyfin/index.xml b/public/tags/jellyfin/index.xml deleted file mode 100644 index 2651bc09..00000000 --- a/public/tags/jellyfin/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - jellyfin on davegallant - /tags/jellyfin/ - Recent content in jellyfin on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/k3s/index.html b/public/tags/k3s/index.html index 6ba176fc..3460c632 100644 --- a/public/tags/k3s/index.html +++ b/public/tags/k3s/index.html @@ -1,164 +1,10 @@ - - - - k3s - davegallant - - - - - - - +k3s +
+

k3s

Running K3s in LXC on Proxmox

It has been a while since I’ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I’ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it’d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.
Read more >
\ No newline at end of file diff --git a/public/tags/k3s/index.xml b/public/tags/k3s/index.xml index 2a593c0d..d2a10d67 100644 --- a/public/tags/k3s/index.xml +++ b/public/tags/k3s/index.xml @@ -1,20 +1 @@ - - - - k3s on davegallant - /tags/k3s/ - Recent content in k3s on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 14 Nov 2021 10:07:03 -0500 - - - Running K3s in LXC on Proxmox - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - Sun, 14 Nov 2021 10:07:03 -0500 - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. - - - +k3s onhttps://davegallant.ca/tags/k3s/Recent content in k3s onHugo -- gohugo.ioen-usDave GallantSun, 14 Nov 2021 10:07:03 -0500Running K3s in LXC on Proxmoxhttps://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. \ No newline at end of file diff --git a/public/tags/k3s/page/1/index.html b/public/tags/k3s/page/1/index.html new file mode 100644 index 00000000..ea2a99c5 --- /dev/null +++ b/public/tags/k3s/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/k3s/ + \ No newline at end of file diff --git a/public/tags/k8s/index.html b/public/tags/k8s/index.html index 698c11b1..d9c5f679 100644 --- a/public/tags/k8s/index.html +++ b/public/tags/k8s/index.html @@ -1,164 +1,10 @@ - - - - k8s - davegallant - - - - - - - +k8s +
+

k8s

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/k8s/index.xml b/public/tags/k8s/index.xml index 4232cf60..8ea9eb72 100644 --- a/public/tags/k8s/index.xml +++ b/public/tags/k8s/index.xml @@ -1,20 +1 @@ - - - - k8s on davegallant - /tags/k8s/ - Recent content in k8s on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +k8s onhttps://davegallant.ca/tags/k8s/Recent content in k8s onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/k8s/page/1/index.html b/public/tags/k8s/page/1/index.html new file mode 100644 index 00000000..487724de --- /dev/null +++ b/public/tags/k8s/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/k8s/ + \ No newline at end of file diff --git a/public/tags/kubectl-plugin-socks5-proxy/index.html b/public/tags/kubectl-plugin-socks5-proxy/index.html index cc278358..ccc499ad 100644 --- a/public/tags/kubectl-plugin-socks5-proxy/index.html +++ b/public/tags/kubectl-plugin-socks5-proxy/index.html @@ -1,164 +1,10 @@ - - - - kubectl-plugin-socks5-proxy - davegallant - - - - - - - +kubectl-plugin-socks5-proxy +
+

kubectl-plugin-socks5-proxy

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/kubectl-plugin-socks5-proxy/index.xml b/public/tags/kubectl-plugin-socks5-proxy/index.xml index 6f17e736..8862e1fc 100644 --- a/public/tags/kubectl-plugin-socks5-proxy/index.xml +++ b/public/tags/kubectl-plugin-socks5-proxy/index.xml @@ -1,20 +1 @@ - - - - kubectl-plugin-socks5-proxy on davegallant - /tags/kubectl-plugin-socks5-proxy/ - Recent content in kubectl-plugin-socks5-proxy on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +kubectl-plugin-socks5-proxy onhttps://davegallant.ca/tags/kubectl-plugin-socks5-proxy/Recent content in kubectl-plugin-socks5-proxy onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/kubectl-plugin-socks5-proxy/page/1/index.html b/public/tags/kubectl-plugin-socks5-proxy/page/1/index.html new file mode 100644 index 00000000..b6189550 --- /dev/null +++ b/public/tags/kubectl-plugin-socks5-proxy/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/kubectl-plugin-socks5-proxy/ + \ No newline at end of file diff --git a/public/tags/linux/index.html b/public/tags/linux/index.html index 19df7f38..3792bdba 100644 --- a/public/tags/linux/index.html +++ b/public/tags/linux/index.html @@ -1,164 +1,10 @@ - - - - linux - davegallant - - - - - - - +linux +
+

linux

\ No newline at end of file diff --git a/public/tags/linux/index.xml b/public/tags/linux/index.xml index 07886016..2229adc1 100644 --- a/public/tags/linux/index.xml +++ b/public/tags/linux/index.xml @@ -1,20 +1 @@ - - - - linux on davegallant - /tags/linux/ - Recent content in linux on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 16 Mar 2020 22:00:15 -0400 - - - AppGate SDP on Arch Linux - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - Mon, 16 Mar 2020 22:00:15 -0400 - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - <p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> - - - +linux onhttps://davegallant.ca/tags/linux/Recent content in linux onHugo -- gohugo.ioen-usDave GallantMon, 16 Mar 2020 22:00:15 -0400AppGate SDP on Arch Linuxhttps://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/Mon, 16 Mar 2020 22:00:15 -0400https://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/<p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> \ No newline at end of file diff --git a/public/tags/linux/page/1/index.html b/public/tags/linux/page/1/index.html new file mode 100644 index 00000000..8652f2ea --- /dev/null +++ b/public/tags/linux/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/linux/ + \ No newline at end of file diff --git a/public/tags/lxc/index.html b/public/tags/lxc/index.html index 718bc277..7f354fb5 100644 --- a/public/tags/lxc/index.html +++ b/public/tags/lxc/index.html @@ -1,164 +1,10 @@ - - - - lxc - davegallant - - - - - - - +lxc +
+

lxc

Running K3s in LXC on Proxmox

It has been a while since I’ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I’ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it’d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.
Read more >
\ No newline at end of file diff --git a/public/tags/lxc/index.xml b/public/tags/lxc/index.xml index 17b37b0b..c69c0e4f 100644 --- a/public/tags/lxc/index.xml +++ b/public/tags/lxc/index.xml @@ -1,20 +1 @@ - - - - lxc on davegallant - /tags/lxc/ - Recent content in lxc on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 14 Nov 2021 10:07:03 -0500 - - - Running K3s in LXC on Proxmox - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - Sun, 14 Nov 2021 10:07:03 -0500 - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. - - - +lxc onhttps://davegallant.ca/tags/lxc/Recent content in lxc onHugo -- gohugo.ioen-usDave GallantSun, 14 Nov 2021 10:07:03 -0500Running K3s in LXC on Proxmoxhttps://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. \ No newline at end of file diff --git a/public/tags/lxc/page/1/index.html b/public/tags/lxc/page/1/index.html new file mode 100644 index 00000000..6c10a7b7 --- /dev/null +++ b/public/tags/lxc/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/lxc/ + \ No newline at end of file diff --git a/public/tags/netdata/index.html b/public/tags/netdata/index.html deleted file mode 100644 index eedbc9ff..00000000 --- a/public/tags/netdata/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - netdata - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "netdata"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/netdata/index.xml b/public/tags/netdata/index.xml deleted file mode 100644 index b5b095cc..00000000 --- a/public/tags/netdata/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - netdata on davegallant - /tags/netdata/ - Recent content in netdata on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/nix/index.html b/public/tags/nix/index.html index ef041c02..dad70197 100644 --- a/public/tags/nix/index.html +++ b/public/tags/nix/index.html @@ -1,164 +1,10 @@ - - - - nix - davegallant - - - - - - - +nix +
+

nix

Why I threw out my dotfiles

Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (~/.zshrc, ~/.config/git/config, ~/.config/tmux/tmux.conf, etc). I have tried several different ways to manage them, including bare git repos and utilities such as GNU Stow. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: home-manager.

Read more >
\ No newline at end of file diff --git a/public/tags/nix/index.xml b/public/tags/nix/index.xml index 3062ceb1..ca3cfefb 100644 --- a/public/tags/nix/index.xml +++ b/public/tags/nix/index.xml @@ -1,20 +1,10 @@ - - - - nix on davegallant - /tags/nix/ - Recent content in nix on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Wed, 08 Sep 2021 00:42:33 -0400 - - - Why I threw out my dotfiles - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - Wed, 08 Sep 2021 00:42:33 -0400 - /blog/2021/09/08/why-i-threw-out-my-dotfiles/ - - - - +nix onhttps://davegallant.ca/tags/nix/Recent content in nix onHugo -- gohugo.ioen-usDave GallantWed, 08 Sep 2021 00:42:33 -0400Why I threw out my dotfileshttps://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/Wed, 08 Sep 2021 00:42:33 -0400https://davegallant.ca/blog/2021/09/08/why-i-threw-out-my-dotfiles/<p>Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (<code>~/.zshrc</code>, <code>~/.config/git/config</code>, <code>~/.config/tmux/tmux.conf</code>, etc). I have tried several different ways to manage them, including <a +href="https://www.atlassian.com/git/tutorials/dotfiles" +class="link--external" target="_blank" rel="noreferrer" +>bare git repos</a> and utilities such as <a +href="https://www.gnu.org/software/stow/" +class="link--external" target="_blank" rel="noreferrer" +>GNU Stow</a>. These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: <a +href="https://github.com/nix-community/home-manager" +class="link--external" target="_blank" rel="noreferrer" +>home-manager</a>.</p> \ No newline at end of file diff --git a/public/tags/nix/page/1/index.html b/public/tags/nix/page/1/index.html new file mode 100644 index 00000000..dde23c66 --- /dev/null +++ b/public/tags/nix/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/nix/ + \ No newline at end of file diff --git a/public/tags/openwrt/index.html b/public/tags/openwrt/index.html index c13a31a8..f826905b 100644 --- a/public/tags/openwrt/index.html +++ b/public/tags/openwrt/index.html @@ -1,164 +1,10 @@ - - - - openwrt - davegallant - - - - - - - +openwrt +
+

openwrt

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >
\ No newline at end of file diff --git a/public/tags/openwrt/index.xml b/public/tags/openwrt/index.xml index 89e1f866..4dc5f18c 100644 --- a/public/tags/openwrt/index.xml +++ b/public/tags/openwrt/index.xml @@ -1,20 +1,7 @@ - - - - openwrt on davegallant - /tags/openwrt/ - Recent content in openwrt on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 02 Apr 2022 18:50:09 -0400 - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - +openwrt onhttps://davegallant.ca/tags/openwrt/Recent content in openwrt onHugo -- gohugo.ioen-usDave GallantSat, 02 Apr 2022 18:50:09 -0400Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p> \ No newline at end of file diff --git a/public/tags/openwrt/page/1/index.html b/public/tags/openwrt/page/1/index.html new file mode 100644 index 00000000..81d698db --- /dev/null +++ b/public/tags/openwrt/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/openwrt/ + \ No newline at end of file diff --git a/public/tags/page/1/index.html b/public/tags/page/1/index.html new file mode 100644 index 00000000..585e0606 --- /dev/null +++ b/public/tags/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/ + \ No newline at end of file diff --git a/public/tags/page/2/index.html b/public/tags/page/2/index.html new file mode 100644 index 00000000..d2015078 --- /dev/null +++ b/public/tags/page/2/index.html @@ -0,0 +1,12 @@ +Tags +
+

Tags

\ No newline at end of file diff --git a/public/tags/page/3/index.html b/public/tags/page/3/index.html new file mode 100644 index 00000000..8bd828f0 --- /dev/null +++ b/public/tags/page/3/index.html @@ -0,0 +1,12 @@ +Tags +
+

Tags

\ No newline at end of file diff --git a/public/tags/page/4/index.html b/public/tags/page/4/index.html new file mode 100644 index 00000000..7ad1453c --- /dev/null +++ b/public/tags/page/4/index.html @@ -0,0 +1,12 @@ +Tags +
+

Tags

\ No newline at end of file diff --git a/public/tags/page/5/index.html b/public/tags/page/5/index.html new file mode 100644 index 00000000..b13f3bdd --- /dev/null +++ b/public/tags/page/5/index.html @@ -0,0 +1,11 @@ +Tags +
+

Tags

\ No newline at end of file diff --git a/public/tags/pfsense/index.html b/public/tags/pfsense/index.html index 08f829d2..846ee46f 100644 --- a/public/tags/pfsense/index.html +++ b/public/tags/pfsense/index.html @@ -1,164 +1,10 @@ - - - - pfsense - davegallant - - - - - - - +pfsense +
+

pfsense

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >
\ No newline at end of file diff --git a/public/tags/pfsense/index.xml b/public/tags/pfsense/index.xml index a2e8f5a9..67499526 100644 --- a/public/tags/pfsense/index.xml +++ b/public/tags/pfsense/index.xml @@ -1,20 +1,7 @@ - - - - pfsense on davegallant - /tags/pfsense/ - Recent content in pfsense on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 02 Apr 2022 18:50:09 -0400 - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - +pfsense onhttps://davegallant.ca/tags/pfsense/Recent content in pfsense onHugo -- gohugo.ioen-usDave GallantSat, 02 Apr 2022 18:50:09 -0400Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p> \ No newline at end of file diff --git a/public/tags/pfsense/page/1/index.html b/public/tags/pfsense/page/1/index.html new file mode 100644 index 00000000..157cfc35 --- /dev/null +++ b/public/tags/pfsense/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/pfsense/ + \ No newline at end of file diff --git a/public/tags/pihole/index.html b/public/tags/pihole/index.html deleted file mode 100644 index 5dbc9459..00000000 --- a/public/tags/pihole/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - pihole - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "pihole"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/pihole/index.xml b/public/tags/pihole/index.xml deleted file mode 100644 index 3d3ec83d..00000000 --- a/public/tags/pihole/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - pihole on davegallant - /tags/pihole/ - Recent content in pihole on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/plex/index.html b/public/tags/plex/index.html deleted file mode 100644 index 85f54482..00000000 --- a/public/tags/plex/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - plex - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "plex"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/plex/index.xml b/public/tags/plex/index.xml deleted file mode 100644 index a4b4ab86..00000000 --- a/public/tags/plex/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - plex on davegallant - /tags/plex/ - Recent content in plex on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/podman/index.html b/public/tags/podman/index.html index 4c39e3e8..56d87759 100644 --- a/public/tags/podman/index.html +++ b/public/tags/podman/index.html @@ -1,164 +1,10 @@ - - - - podman - davegallant - - - - - - - +podman +
+

podman

\ No newline at end of file diff --git a/public/tags/podman/index.xml b/public/tags/podman/index.xml index 77127e4b..82de6cb5 100644 --- a/public/tags/podman/index.xml +++ b/public/tags/podman/index.xml @@ -1,20 +1 @@ - - - - podman on davegallant - /tags/podman/ - Recent content in podman on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 11 Oct 2021 10:43:35 -0400 - - - Replacing docker with podman on macOS (and Linux) - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - Mon, 11 Oct 2021 10:43:35 -0400 - /blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/ - - - - +podman onhttps://davegallant.ca/tags/podman/Recent content in podman onHugo -- gohugo.ioen-usDave GallantMon, 11 Oct 2021 10:43:35 -0400Replacing docker with podman on macOS (and Linux)https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/Mon, 11 Oct 2021 10:43:35 -0400https://davegallant.ca/blog/2021/10/11/replacing-docker-with-podman-on-macos-and-linux/<p>There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker:</p> \ No newline at end of file diff --git a/public/tags/podman/page/1/index.html b/public/tags/podman/page/1/index.html new file mode 100644 index 00000000..2b764eee --- /dev/null +++ b/public/tags/podman/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/podman/ + \ No newline at end of file diff --git a/public/tags/privacy/index.html b/public/tags/privacy/index.html index d574635e..a7a1bfbd 100644 --- a/public/tags/privacy/index.html +++ b/public/tags/privacy/index.html @@ -1,164 +1,10 @@ - - - - privacy - davegallant - - - - - - - +privacy +
+

privacy

\ No newline at end of file diff --git a/public/tags/privacy/index.xml b/public/tags/privacy/index.xml index 699df5a3..124ee17c 100644 --- a/public/tags/privacy/index.xml +++ b/public/tags/privacy/index.xml @@ -1,20 +1,7 @@ - - - - privacy on davegallant - /tags/privacy/ - Recent content in privacy on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 10 Dec 2022 21:46:55 -0500 - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - +privacy onhttps://davegallant.ca/tags/privacy/Recent content in privacy onHugo -- gohugo.ioen-usDave GallantSat, 10 Dec 2022 21:46:55 -0500Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p> \ No newline at end of file diff --git a/public/tags/privacy/page/1/index.html b/public/tags/privacy/page/1/index.html new file mode 100644 index 00000000..3bc670b6 --- /dev/null +++ b/public/tags/privacy/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/privacy/ + \ No newline at end of file diff --git a/public/tags/proxmox/index.html b/public/tags/proxmox/index.html index c30abba2..68155883 100644 --- a/public/tags/proxmox/index.html +++ b/public/tags/proxmox/index.html @@ -1,166 +1,10 @@ - - - - proxmox - davegallant - - - - - - - +proxmox +
+

proxmox

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >

Running K3s in LXC on Proxmox

It has been a while since I’ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I’ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it’d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.
Read more >
\ No newline at end of file diff --git a/public/tags/proxmox/index.xml b/public/tags/proxmox/index.xml index e7c9d23b..d91573b6 100644 --- a/public/tags/proxmox/index.xml +++ b/public/tags/proxmox/index.xml @@ -1,27 +1,7 @@ - - - - proxmox on davegallant - /tags/proxmox/ - Recent content in proxmox on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 02 Apr 2022 18:50:09 -0400 - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - Running K3s in LXC on Proxmox - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - Sun, 14 Nov 2021 10:07:03 -0500 - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. - - - +proxmox onhttps://davegallant.ca/tags/proxmox/Recent content in proxmox onHugo -- gohugo.ioen-usDave GallantSat, 02 Apr 2022 18:50:09 -0400Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p>Running K3s in LXC on Proxmoxhttps://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. \ No newline at end of file diff --git a/public/tags/proxmox/page/1/index.html b/public/tags/proxmox/page/1/index.html new file mode 100644 index 00000000..2c416186 --- /dev/null +++ b/public/tags/proxmox/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/proxmox/ + \ No newline at end of file diff --git a/public/tags/proxy/index.html b/public/tags/proxy/index.html index bfc6bebe..f75a6f49 100644 --- a/public/tags/proxy/index.html +++ b/public/tags/proxy/index.html @@ -1,164 +1,10 @@ - - - - proxy - davegallant - - - - - - - +proxy +
+

proxy

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/proxy/index.xml b/public/tags/proxy/index.xml index 21848886..bf2cb834 100644 --- a/public/tags/proxy/index.xml +++ b/public/tags/proxy/index.xml @@ -1,20 +1 @@ - - - - proxy on davegallant - /tags/proxy/ - Recent content in proxy on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +proxy onhttps://davegallant.ca/tags/proxy/Recent content in proxy onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/proxy/page/1/index.html b/public/tags/proxy/page/1/index.html new file mode 100644 index 00000000..4e67a12e --- /dev/null +++ b/public/tags/proxy/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/proxy/ + \ No newline at end of file diff --git a/public/tags/python/index.html b/public/tags/python/index.html index b5caebcd..dc61f653 100644 --- a/public/tags/python/index.html +++ b/public/tags/python/index.html @@ -1,166 +1,11 @@ - - - - python - davegallant - - - - - - - +python +
+

python

Automatically rotating AWS access keys

Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.
Read more >
\ No newline at end of file diff --git a/public/tags/python/index.xml b/public/tags/python/index.xml index 47745cab..6da8677c 100644 --- a/public/tags/python/index.xml +++ b/public/tags/python/index.xml @@ -1,27 +1,2 @@ - - - - python on davegallant - /tags/python/ - Recent content in python on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Fri, 17 Sep 2021 12:48:33 -0400 - - - Automatically rotating AWS access keys - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - Fri, 17 Sep 2021 12:48:33 -0400 - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - - - - AppGate SDP on Arch Linux - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - Mon, 16 Mar 2020 22:00:15 -0400 - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - <p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> - - - +python onhttps://davegallant.ca/tags/python/Recent content in python onHugo -- gohugo.ioen-usDave GallantFri, 17 Sep 2021 12:48:33 -0400Automatically rotating AWS access keyshttps://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.AppGate SDP on Arch Linuxhttps://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/Mon, 16 Mar 2020 22:00:15 -0400https://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/<p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> \ No newline at end of file diff --git a/public/tags/python/page/1/index.html b/public/tags/python/page/1/index.html new file mode 100644 index 00000000..d0130f89 --- /dev/null +++ b/public/tags/python/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/python/ + \ No newline at end of file diff --git a/public/tags/ransomware/index.html b/public/tags/ransomware/index.html index fe8e723c..d6d2d78b 100644 --- a/public/tags/ransomware/index.html +++ b/public/tags/ransomware/index.html @@ -1,164 +1,10 @@ - - - - ransomware - davegallant - - - - - - - +ransomware +
+

ransomware

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

Read more >
\ No newline at end of file diff --git a/public/tags/ransomware/index.xml b/public/tags/ransomware/index.xml index c81fe074..bc0d63d1 100644 --- a/public/tags/ransomware/index.xml +++ b/public/tags/ransomware/index.xml @@ -1,20 +1 @@ - - - - ransomware on davegallant - /tags/ransomware/ - Recent content in ransomware on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 13 Mar 2022 18:49:10 -0400 - - - Backing up gmail with Synology - /blog/2022/03/13/backing-up-gmail-with-synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /blog/2022/03/13/backing-up-gmail-with-synology/ - - - - +ransomware onhttps://davegallant.ca/tags/ransomware/Recent content in ransomware onHugo -- gohugo.ioen-usDave GallantSun, 13 Mar 2022 18:49:10 -0400Backing up gmail with Synologyhttps://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/<p>I&rsquo;ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.</p> \ No newline at end of file diff --git a/public/tags/ransomware/page/1/index.html b/public/tags/ransomware/page/1/index.html new file mode 100644 index 00000000..53f73a72 --- /dev/null +++ b/public/tags/ransomware/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/ransomware/ + \ No newline at end of file diff --git a/public/tags/router-on-a-stick/index.html b/public/tags/router-on-a-stick/index.html index 6be6d7ef..23db1472 100644 --- a/public/tags/router-on-a-stick/index.html +++ b/public/tags/router-on-a-stick/index.html @@ -1,164 +1,10 @@ - - - - router-on-a-stick - davegallant - - - - - - - +router-on-a-stick +
+

router-on-a-stick

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >
\ No newline at end of file diff --git a/public/tags/router-on-a-stick/index.xml b/public/tags/router-on-a-stick/index.xml index 69fe7f75..643f9f09 100644 --- a/public/tags/router-on-a-stick/index.xml +++ b/public/tags/router-on-a-stick/index.xml @@ -1,20 +1,7 @@ - - - - router-on-a-stick on davegallant - /tags/router-on-a-stick/ - Recent content in router-on-a-stick on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 02 Apr 2022 18:50:09 -0400 - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - +router-on-a-stick onhttps://davegallant.ca/tags/router-on-a-stick/Recent content in router-on-a-stick onHugo -- gohugo.ioen-usDave GallantSat, 02 Apr 2022 18:50:09 -0400Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p> \ No newline at end of file diff --git a/public/tags/router-on-a-stick/page/1/index.html b/public/tags/router-on-a-stick/page/1/index.html new file mode 100644 index 00000000..eb3855c4 --- /dev/null +++ b/public/tags/router-on-a-stick/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/router-on-a-stick/ + \ No newline at end of file diff --git a/public/tags/router/index.html b/public/tags/router/index.html index e84341e6..bc1599ec 100644 --- a/public/tags/router/index.html +++ b/public/tags/router/index.html @@ -1,164 +1,10 @@ - - - - router - davegallant - - - - - - - +router +
+

router

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >
\ No newline at end of file diff --git a/public/tags/router/index.xml b/public/tags/router/index.xml index f8dca18b..9de756d8 100644 --- a/public/tags/router/index.xml +++ b/public/tags/router/index.xml @@ -1,20 +1,7 @@ - - - - router on davegallant - /tags/router/ - Recent content in router on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 02 Apr 2022 18:50:09 -0400 - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - +router onhttps://davegallant.ca/tags/router/Recent content in router onHugo -- gohugo.ioen-usDave GallantSat, 02 Apr 2022 18:50:09 -0400Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p> \ No newline at end of file diff --git a/public/tags/router/page/1/index.html b/public/tags/router/page/1/index.html new file mode 100644 index 00000000..4b10d0c1 --- /dev/null +++ b/public/tags/router/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/router/ + \ No newline at end of file diff --git a/public/tags/security/index.html b/public/tags/security/index.html index f0d14ac7..624feba8 100644 --- a/public/tags/security/index.html +++ b/public/tags/security/index.html @@ -1,164 +1,11 @@ - - - - security - davegallant - - - - - - - +security +
+

security

Automatically rotating AWS access keys

Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution.
Read more >
\ No newline at end of file diff --git a/public/tags/security/index.xml b/public/tags/security/index.xml index 09784fee..d9651378 100644 --- a/public/tags/security/index.xml +++ b/public/tags/security/index.xml @@ -1,20 +1,2 @@ - - - - security on davegallant - /tags/security/ - Recent content in security on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Fri, 17 Sep 2021 12:48:33 -0400 - - - Automatically rotating AWS access keys - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - Fri, 17 Sep 2021 12:48:33 -0400 - /blog/2021/09/17/automatically-rotating-aws-access-keys/ - - - - +security onhttps://davegallant.ca/tags/security/Recent content in security onHugo -- gohugo.ioen-usDave GallantFri, 17 Sep 2021 12:48:33 -0400Automatically rotating AWS access keyshttps://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Fri, 17 Sep 2021 12:48:33 -0400https://davegallant.ca/blog/2021/09/17/automatically-rotating-aws-access-keys/Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a script since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background. +In the longer term, migrating my local workflows to aws-vault seems like a more secure solution. \ No newline at end of file diff --git a/public/tags/security/page/1/index.html b/public/tags/security/page/1/index.html new file mode 100644 index 00000000..25eca25f --- /dev/null +++ b/public/tags/security/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/security/ + \ No newline at end of file diff --git a/public/tags/self-hosted/index.html b/public/tags/self-hosted/index.html index bdf08f51..9aa59ade 100644 --- a/public/tags/self-hosted/index.html +++ b/public/tags/self-hosted/index.html @@ -1,172 +1,10 @@ - - - - self-hosted - davegallant - - - - - - - +self-hosted +
+

self-hosted

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >

Running K3s in LXC on Proxmox

It has been a while since I’ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I’ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it’d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment.
Read more >
\ No newline at end of file diff --git a/public/tags/self-hosted/index.xml b/public/tags/self-hosted/index.xml index b8591f52..dd073c1d 100644 --- a/public/tags/self-hosted/index.xml +++ b/public/tags/self-hosted/index.xml @@ -1,48 +1,16 @@ - - - - self-hosted on davegallant - /tags/self-hosted/ - Recent content in self-hosted on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - Setting up Gitea Actions with Tailscale - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - Running K3s in LXC on Proxmox - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - Sun, 14 Nov 2021 10:07:03 -0500 - /blog/2021/11/14/running-k3s-in-lxc-on-proxmox/ - It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - +self-hosted onhttps://davegallant.ca/tags/self-hosted/Recent content in self-hosted onHugo -- gohugo.ioen-usDave GallantSun, 10 Dec 2023 17:22:11 -0500Setting up Gitea Actions with Tailscalehttps://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/<p>In this post I&rsquo;ll go through the process of setting up Gitea Actions and <a +href="https://tailscale.com/" +class="link--external" target="_blank" rel="noreferrer" +>Tailscale</a>, unlocking a simple and secure way to automate workflows.</p>Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p>Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p>Running K3s in LXC on Proxmoxhttps://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/Sun, 14 Nov 2021 10:07:03 -0500https://davegallant.ca/blog/2021/11/14/running-k3s-in-lxc-on-proxmox/It has been a while since I&rsquo;ve actively used Kubernetes and wanted to explore the evolution of tools such as Helm and Tekton. I decided to deploy K3s, since I&rsquo;ve had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it&rsquo;d be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. \ No newline at end of file diff --git a/public/tags/self-hosted/page/1/index.html b/public/tags/self-hosted/page/1/index.html new file mode 100644 index 00000000..086df59a --- /dev/null +++ b/public/tags/self-hosted/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/self-hosted/ + \ No newline at end of file diff --git a/public/tags/socat/index.html b/public/tags/socat/index.html index 093830ca..2db011ba 100644 --- a/public/tags/socat/index.html +++ b/public/tags/socat/index.html @@ -1,164 +1,10 @@ - - - - socat - davegallant - - - - - - - +socat +
+

socat

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/socat/index.xml b/public/tags/socat/index.xml index 7b8bd3f1..a6706323 100644 --- a/public/tags/socat/index.xml +++ b/public/tags/socat/index.xml @@ -1,20 +1 @@ - - - - socat on davegallant - /tags/socat/ - Recent content in socat on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +socat onhttps://davegallant.ca/tags/socat/Recent content in socat onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/socat/page/1/index.html b/public/tags/socat/page/1/index.html new file mode 100644 index 00000000..ad996afe --- /dev/null +++ b/public/tags/socat/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/socat/ + \ No newline at end of file diff --git a/public/tags/socks/index.html b/public/tags/socks/index.html index 9ba30526..fe732e26 100644 --- a/public/tags/socks/index.html +++ b/public/tags/socks/index.html @@ -1,164 +1,10 @@ - - - - socks - davegallant - - - - - - - +socks +
+

socks

Using AKS and SOCKS to connect to a private Azure DB

I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I’d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I’d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.

Read more >
\ No newline at end of file diff --git a/public/tags/socks/index.xml b/public/tags/socks/index.xml index cb51cb92..75904b11 100644 --- a/public/tags/socks/index.xml +++ b/public/tags/socks/index.xml @@ -1,20 +1 @@ - - - - socks on davegallant - /tags/socks/ - Recent content in socks on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 22 May 2023 16:31:29 -0400 - - - Using AKS and SOCKS to connect to a private Azure DB - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - Mon, 22 May 2023 16:31:29 -0400 - /blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/ - - - - +socks onhttps://davegallant.ca/tags/socks/Recent content in socks onHugo -- gohugo.ioen-usDave GallantMon, 22 May 2023 16:31:29 -0400Using AKS and SOCKS to connect to a private Azure DBhttps://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/Mon, 22 May 2023 16:31:29 -0400https://davegallant.ca/blog/2023/05/22/using-aks-and-socks-to-connect-to-a-private-azure-db/<p>I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I&rsquo;d rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I&rsquo;d like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.</p> \ No newline at end of file diff --git a/public/tags/socks/page/1/index.html b/public/tags/socks/page/1/index.html new file mode 100644 index 00000000..af06bea1 --- /dev/null +++ b/public/tags/socks/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/socks/ + \ No newline at end of file diff --git a/public/tags/synology/index.html b/public/tags/synology/index.html index a5c1f554..43bcfad8 100644 --- a/public/tags/synology/index.html +++ b/public/tags/synology/index.html @@ -1,164 +1,10 @@ - - - - synology - davegallant - - - - - - - +synology +
+

synology

Backing up gmail with Synology

I’ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.

Read more >
\ No newline at end of file diff --git a/public/tags/synology/index.xml b/public/tags/synology/index.xml index fed3da7c..d580a435 100644 --- a/public/tags/synology/index.xml +++ b/public/tags/synology/index.xml @@ -1,20 +1 @@ - - - - synology on davegallant - /tags/synology/ - Recent content in synology on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 13 Mar 2022 18:49:10 -0400 - - - Backing up gmail with Synology - /blog/2022/03/13/backing-up-gmail-with-synology/ - Sun, 13 Mar 2022 18:49:10 -0400 - /blog/2022/03/13/backing-up-gmail-with-synology/ - - - - +synology onhttps://davegallant.ca/tags/synology/Recent content in synology onHugo -- gohugo.ioen-usDave GallantSun, 13 Mar 2022 18:49:10 -0400Backing up gmail with Synologyhttps://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/Sun, 13 Mar 2022 18:49:10 -0400https://davegallant.ca/blog/2022/03/13/backing-up-gmail-with-synology/<p>I&rsquo;ve used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.</p> \ No newline at end of file diff --git a/public/tags/synology/page/1/index.html b/public/tags/synology/page/1/index.html new file mode 100644 index 00000000..13d7a6b6 --- /dev/null +++ b/public/tags/synology/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/synology/ + \ No newline at end of file diff --git a/public/tags/tailscale/index.html b/public/tags/tailscale/index.html index 1e1c0e23..bb50566e 100644 --- a/public/tags/tailscale/index.html +++ b/public/tags/tailscale/index.html @@ -1,168 +1,10 @@ - - - - tailscale - davegallant - - - - - - - +tailscale +
+

tailscale

\ No newline at end of file diff --git a/public/tags/tailscale/index.xml b/public/tags/tailscale/index.xml index 51c32e93..6174d081 100644 --- a/public/tags/tailscale/index.xml +++ b/public/tags/tailscale/index.xml @@ -1,34 +1,10 @@ - - - - tailscale on davegallant - /tags/tailscale/ - Recent content in tailscale on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sun, 10 Dec 2023 17:22:11 -0500 - - - Setting up Gitea Actions with Tailscale - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - Sun, 10 Dec 2023 17:22:11 -0500 - /blog/2023/12/10/setting-up-gitea-actions-with-tailscale/ - - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - +tailscale onhttps://davegallant.ca/tags/tailscale/Recent content in tailscale onHugo -- gohugo.ioen-usDave GallantSun, 10 Dec 2023 17:22:11 -0500Setting up Gitea Actions with Tailscalehttps://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/Sun, 10 Dec 2023 17:22:11 -0500https://davegallant.ca/blog/2023/12/10/setting-up-gitea-actions-with-tailscale/<p>In this post I&rsquo;ll go through the process of setting up Gitea Actions and <a +href="https://tailscale.com/" +class="link--external" target="_blank" rel="noreferrer" +>Tailscale</a>, unlocking a simple and secure way to automate workflows.</p>Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p> \ No newline at end of file diff --git a/public/tags/tailscale/page/1/index.html b/public/tags/tailscale/page/1/index.html new file mode 100644 index 00000000..461e5205 --- /dev/null +++ b/public/tags/tailscale/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/tailscale/ + \ No newline at end of file diff --git a/public/tags/virtualization/index.html b/public/tags/virtualization/index.html deleted file mode 100644 index 4a600add..00000000 --- a/public/tags/virtualization/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - virtualization - davegallant - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - -

Entries tagged - "virtualization"

- - - - -
-
-
-
-
-
- -
- - - - -
- - -
- - - - -
- - diff --git a/public/tags/virtualization/index.xml b/public/tags/virtualization/index.xml deleted file mode 100644 index 9bc5f209..00000000 --- a/public/tags/virtualization/index.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - virtualization on davegallant - /tags/virtualization/ - Recent content in virtualization on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 06 Sep 2021 01:12:54 -0400 - - - What to do with a homelab - /blog/2021/09/06/what-to-do-with-a-homelab/ - Mon, 06 Sep 2021 01:12:54 -0400 - /blog/2021/09/06/what-to-do-with-a-homelab/ - <p>A homelab can be an inexpensive way to host a multitude of internal/external services and learn <em>a lot</em> in the process.</p> - - - diff --git a/public/tags/vlan/index.html b/public/tags/vlan/index.html index 838e8e5d..25c00849 100644 --- a/public/tags/vlan/index.html +++ b/public/tags/vlan/index.html @@ -1,164 +1,10 @@ - - - - vlan - davegallant - - - - - - - +vlan +
+

vlan

Virtualizing my router with pfSense

My aging router has been running OpenWrt for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a large index of packages. Ever since I’ve connected some standalone wireless access points, I’ve had less of a need for an off-the-shelf all-in-one wireless router combo. I’ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!

Read more >
\ No newline at end of file diff --git a/public/tags/vlan/index.xml b/public/tags/vlan/index.xml index 22b97ec0..d9b6ec52 100644 --- a/public/tags/vlan/index.xml +++ b/public/tags/vlan/index.xml @@ -1,20 +1,7 @@ - - - - vlan on davegallant - /tags/vlan/ - Recent content in vlan on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 02 Apr 2022 18:50:09 -0400 - - - Virtualizing my router with pfSense - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - Sat, 02 Apr 2022 18:50:09 -0400 - /blog/2022/04/02/virtualizing-my-router-with-pfsense/ - - - - +vlan onhttps://davegallant.ca/tags/vlan/Recent content in vlan onHugo -- gohugo.ioen-usDave GallantSat, 02 Apr 2022 18:50:09 -0400Virtualizing my router with pfSensehttps://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/Sat, 02 Apr 2022 18:50:09 -0400https://davegallant.ca/blog/2022/04/02/virtualizing-my-router-with-pfsense/<p>My aging router has been running <a +href="https://en.wikipedia.org/wiki/OpenWrt" +class="link--external" target="_blank" rel="noreferrer" +>OpenWrt</a> for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a <a +href="https://openwrt.org/packages/index/start" +class="link--external" target="_blank" rel="noreferrer" +>large index of packages</a>. Ever since I&rsquo;ve connected some standalone wireless access points, I&rsquo;ve had less of a need for an off-the-shelf all-in-one wireless router combo. I&rsquo;ve also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!</p> \ No newline at end of file diff --git a/public/tags/vlan/page/1/index.html b/public/tags/vlan/page/1/index.html new file mode 100644 index 00000000..d1fd6d73 --- /dev/null +++ b/public/tags/vlan/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/vlan/ + \ No newline at end of file diff --git a/public/tags/vpn/index.html b/public/tags/vpn/index.html index c6560307..94911498 100644 --- a/public/tags/vpn/index.html +++ b/public/tags/vpn/index.html @@ -1,164 +1,10 @@ - - - - vpn - davegallant - - - - - - - +vpn +
+

vpn

\ No newline at end of file diff --git a/public/tags/vpn/index.xml b/public/tags/vpn/index.xml index e6d19dd6..b7b1f74e 100644 --- a/public/tags/vpn/index.xml +++ b/public/tags/vpn/index.xml @@ -1,20 +1 @@ - - - - vpn on davegallant - /tags/vpn/ - Recent content in vpn on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Mon, 16 Mar 2020 22:00:15 -0400 - - - AppGate SDP on Arch Linux - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - Mon, 16 Mar 2020 22:00:15 -0400 - /blog/2020/03/16/appgate-sdp-on-arch-linux/ - <p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> - - - +vpn onhttps://davegallant.ca/tags/vpn/Recent content in vpn onHugo -- gohugo.ioen-usDave GallantMon, 16 Mar 2020 22:00:15 -0400AppGate SDP on Arch Linuxhttps://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/Mon, 16 Mar 2020 22:00:15 -0400https://davegallant.ca/blog/2020/03/16/appgate-sdp-on-arch-linux/<p>AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP <code>4.3.2</code> working on Arch Linux.</p> \ No newline at end of file diff --git a/public/tags/vpn/page/1/index.html b/public/tags/vpn/page/1/index.html new file mode 100644 index 00000000..4f939251 --- /dev/null +++ b/public/tags/vpn/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/vpn/ + \ No newline at end of file diff --git a/public/tags/yewtu.be/index.html b/public/tags/yewtu.be/index.html index 18008ebf..a45a7cd2 100644 --- a/public/tags/yewtu.be/index.html +++ b/public/tags/yewtu.be/index.html @@ -1,164 +1,10 @@ - - - - yewtu.be - davegallant - - - - - - - +yewtu.be +
+

yewtu.be

\ No newline at end of file diff --git a/public/tags/yewtu.be/index.xml b/public/tags/yewtu.be/index.xml index c3c5b1f8..5a5b64a6 100644 --- a/public/tags/yewtu.be/index.xml +++ b/public/tags/yewtu.be/index.xml @@ -1,20 +1,7 @@ - - - - yewtu.be on davegallant - /tags/yewtu.be/ - Recent content in yewtu.be on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 10 Dec 2022 21:46:55 -0500 - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - +yewtu.be onhttps://davegallant.ca/tags/yewtu.be/Recent content in yewtu.be onHugo -- gohugo.ioen-usDave GallantSat, 10 Dec 2022 21:46:55 -0500Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p> \ No newline at end of file diff --git a/public/tags/yewtu.be/page/1/index.html b/public/tags/yewtu.be/page/1/index.html new file mode 100644 index 00000000..fc054d1a --- /dev/null +++ b/public/tags/yewtu.be/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/yewtu.be/ + \ No newline at end of file diff --git a/public/tags/youtube/index.html b/public/tags/youtube/index.html index 79e4d534..256b7d65 100644 --- a/public/tags/youtube/index.html +++ b/public/tags/youtube/index.html @@ -1,164 +1,10 @@ - - - - youtube - davegallant - - - - - - - +youtube +
+

youtube

\ No newline at end of file diff --git a/public/tags/youtube/index.xml b/public/tags/youtube/index.xml index fc69a3f2..815ca175 100644 --- a/public/tags/youtube/index.xml +++ b/public/tags/youtube/index.xml @@ -1,20 +1,7 @@ - - - - youtube on davegallant - /tags/youtube/ - Recent content in youtube on davegallant - Hugo -- gohugo.io - en-us - Dave Gallant - Sat, 10 Dec 2022 21:46:55 -0500 - - - Watching YouTube in private - /blog/2022/12/10/watching-youtube-in-private/ - Sat, 10 Dec 2022 21:46:55 -0500 - /blog/2022/12/10/watching-youtube-in-private/ - - - - +youtube onhttps://davegallant.ca/tags/youtube/Recent content in youtube onHugo -- gohugo.ioen-usDave GallantSat, 10 Dec 2022 21:46:55 -0500Watching YouTube in privatehttps://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/Sat, 10 Dec 2022 21:46:55 -0500https://davegallant.ca/blog/2022/12/10/watching-youtube-in-private/<p>I recently stumbled upon <a +href="https://yewtu.be" +class="link--external" target="_blank" rel="noreferrer" +>yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it&rsquo;s a hosted instance of <a +href="https://invidious.io/" +class="link--external" target="_blank" rel="noreferrer" +>invidious</a>.</p> \ No newline at end of file diff --git a/public/tags/youtube/page/1/index.html b/public/tags/youtube/page/1/index.html new file mode 100644 index 00000000..daee085d --- /dev/null +++ b/public/tags/youtube/page/1/index.html @@ -0,0 +1,2 @@ +https://davegallant.ca/tags/youtube/ + \ No newline at end of file diff --git a/resources/_gen/assets/css/css/non-critical.css_c3f8c1bd69b669b02aeceffdffce2ae7.content b/resources/_gen/assets/css/css/non-critical.css_c3f8c1bd69b669b02aeceffdffce2ae7.content new file mode 100644 index 00000000..1840b6e3 --- /dev/null +++ b/resources/_gen/assets/css/css/non-critical.css_c3f8c1bd69b669b02aeceffdffce2ae7.content @@ -0,0 +1,3 @@ +div.code-toolbar{position:relative}div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out;z-index:10}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:none;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;-webkit-text-decoration:none;text-decoration:none}pre[class*=language-].line-numbers{counter-reset:linenumber;padding-left:3.8em;position:relative}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{border-right:1px solid #999;font-size:100%;left:-3.8em;letter-spacing:-1px;pointer-events:none;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:3em}.line-numbers-rows>span{counter-increment:linenumber;display:block}.line-numbers-rows>span:before{color:#999;content:counter(linenumber);display:block;padding-right:.8em;text-align:right}.command-line-prompt{border-right:1px solid #999;display:block;float:left;font-size:100%;letter-spacing:-1px;margin-right:1em;pointer-events:none;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none}.command-line-prompt>span:before{content:" ";display:block;opacity:.7;padding-right:.8em}.command-line-prompt>span[data-user]:before{content:"[" attr(data-user) "@" attr(data-host) "] $"}.command-line-prompt>span[data-user=root]:before{content:"[" attr(data-user) "@" attr(data-host) "] #"}.command-line-prompt>span[data-prompt]:before{content:attr(data-prompt)}.command-line-prompt>span[data-continuation-prompt]:before{content:attr(data-continuation-prompt)}.command-line span.token.output{opacity:.7}pre.diff-highlight>code .token.deleted:not(.prefix),pre>code.diff-highlight .token.deleted:not(.prefix){background-color:rgba(255,0,0,.1);color:inherit;display:block}pre.diff-highlight>code .token.inserted:not(.prefix),pre>code.diff-highlight .token.inserted:not(.prefix){background-color:rgba(0,255,128,.1);color:inherit;display:block} + +/*! MIT License | github.com/schnerring/hugo-theme-gruvbox */ \ No newline at end of file diff --git a/resources/_gen/assets/css/css/non-critical.css_c3f8c1bd69b669b02aeceffdffce2ae7.json b/resources/_gen/assets/css/css/non-critical.css_c3f8c1bd69b669b02aeceffdffce2ae7.json new file mode 100644 index 00000000..44f7df07 --- /dev/null +++ b/resources/_gen/assets/css/css/non-critical.css_c3f8c1bd69b669b02aeceffdffce2ae7.json @@ -0,0 +1 @@ +{"Target":"css/non-critical.10bf652274d1149570c93631c19d9e068c317875079471d2fda62260a2d40136a468ceb49a9b091ce868ae2db84cbfdb5e4eab1b465fb9710247eb86f36275a0.css","MediaType":"text/css","Data":{"Integrity":"sha512-EL9lInTRFJVwyTYxwZ2eBowxeHUHlHHS/aYiYKLUATakaM60mpsJHOhori24TL/bXk6rG0ZfuXECR+uG82J1oA=="}} \ No newline at end of file diff --git a/resources/_gen/assets/css/css/non-critical.css_dec9ec4ba6a8398679fa2a3d8d143c1a.content b/resources/_gen/assets/css/css/non-critical.css_dec9ec4ba6a8398679fa2a3d8d143c1a.content new file mode 100644 index 00000000..59e0384c --- /dev/null +++ b/resources/_gen/assets/css/css/non-critical.css_dec9ec4ba6a8398679fa2a3d8d143c1a.content @@ -0,0 +1,228 @@ +/*! purgecss start ignore */ + +/* Prism Plugins */ + +/*prismjs/plugins/toolbar/prism-toolbar.css*/ + +div.code-toolbar { + position: relative; +} + +div.code-toolbar > .toolbar { + position: absolute; + z-index: 10; + top: .3em; + right: .2em; + transition: opacity 0.3s ease-in-out; + opacity: 0; +} + +div.code-toolbar:hover > .toolbar { + opacity: 1; +} + +/* Separate line b/c rules are thrown out if selector is invalid. + IE11 and old Edge versions don't support :focus-within. */ + +div.code-toolbar:focus-within > .toolbar { + opacity: 1; +} + +div.code-toolbar > .toolbar > .toolbar-item { + display: inline-block; +} + +div.code-toolbar > .toolbar > .toolbar-item > a { + cursor: pointer; +} + +div.code-toolbar > .toolbar > .toolbar-item > button { + background: none; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + padding: 0; + -webkit-user-select: none; /* for button */ + -moz-user-select: none; + -ms-user-select: none; +} + +div.code-toolbar > .toolbar > .toolbar-item > a, +div.code-toolbar > .toolbar > .toolbar-item > button, +div.code-toolbar > .toolbar > .toolbar-item > span { + color: #bbb; + font-size: .8em; + padding: 0 .5em; + background: #f5f2f0; + background: rgba(224, 224, 224, 0.2); + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); + border-radius: .5em; +} + +div.code-toolbar > .toolbar > .toolbar-item > a:hover, +div.code-toolbar > .toolbar > .toolbar-item > a:focus, +div.code-toolbar > .toolbar > .toolbar-item > button:hover, +div.code-toolbar > .toolbar > .toolbar-item > button:focus, +div.code-toolbar > .toolbar > .toolbar-item > span:hover, +div.code-toolbar > .toolbar > .toolbar-item > span:focus { + color: inherit; + text-decoration: none; +} + +/*prismjs/plugins/line-numbers/prism-line-numbers.css*/ + +pre[class*="language-"].line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; +} + +pre[class*="language-"].line-numbers > code { + position: relative; + white-space: inherit; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + +.line-numbers-rows > span { + display: block; + counter-increment: linenumber; + } + +.line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; + } + +/*prismjs/plugins/command-line/prism-command-line.css*/ + +.command-line-prompt { + border-right: 1px solid #999; + display: block; + float: left; + font-size: 100%; + letter-spacing: -1px; + margin-right: 1em; + pointer-events: none; + text-align: right; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.command-line-prompt > span:before { + opacity: 0.7; + content: ' '; + display: block; + padding-right: 0.8em; +} + +.command-line-prompt > span[data-user]:before { + content: "[" attr(data-user) "@" attr(data-host) "] $"; +} + +.command-line-prompt > span[data-user="root"]:before { + content: "[" attr(data-user) "@" attr(data-host) "] #"; +} + +.command-line-prompt > span[data-prompt]:before { + content: attr(data-prompt); +} + +.command-line-prompt > span[data-continuation-prompt]:before { + content: attr(data-continuation-prompt); +} + +.command-line span.token.output { + /* Make shell output lines a bit lighter to distinguish them from shell commands */ + opacity: 0.7; +} + +/*prismjs/plugins/diff-highlight/prism-diff-highlight.css*/ + +pre.diff-highlight > code .token.deleted:not(.prefix), +pre > code.diff-highlight .token.deleted:not(.prefix) { + background-color: rgba(255, 0, 0, .1); + color: inherit; + display: block; +} + +pre.diff-highlight > code .token.inserted:not(.prefix), +pre > code.diff-highlight .token.inserted:not(.prefix) { + background-color: rgba(0, 255, 128, .1); + color: inherit; + display: block; +} + +/* Prism Font */ + +code, +kbd, +code[class*="language-"], +pre[class*="language-"] { + font-family: var(--font-monospace); +} + +/*! purgecss end ignore */ + +/* Default license header for non-vendor CSS source code that follows */ + +/*! MIT License | github.com/schnerring/hugo-theme-gruvbox */ + +/* + Bootstrap 5 breakpoints + See: https://getbootstrap.com/docs/5.0/layout/breakpoints/#available-breakpoints +*/ + +footer { + align-items: center; + color: var(--fg3); + display: flex; + font-family: var(--font-monospace); + font-size: 0.8rem; + justify-content: center; + padding-bottom: 0.5rem; + padding-top: 2rem; + text-align: center; +} + +.pagination { + display: flex; + margin-top: 2rem; +} + +.pagination__button { + color: var(--primary-alt); + font-family: var(--font-monospace); + font-size: 1.125rem; +} + +.pagination__button:hover { + color: var(--primary); +} + +.pagination__button--next { + margin-left: auto; +} diff --git a/resources/_gen/assets/css/css/non-critical.css_dec9ec4ba6a8398679fa2a3d8d143c1a.json b/resources/_gen/assets/css/css/non-critical.css_dec9ec4ba6a8398679fa2a3d8d143c1a.json new file mode 100644 index 00000000..670c5c54 --- /dev/null +++ b/resources/_gen/assets/css/css/non-critical.css_dec9ec4ba6a8398679fa2a3d8d143c1a.json @@ -0,0 +1 @@ +{"Target":"css/non-critical.css","MediaType":"text/css","Data":{}} \ No newline at end of file diff --git a/resources/_gen/assets/other_cc26ecf2d7346e08055fecc1a84afc79.content b/resources/_gen/assets/other_cc26ecf2d7346e08055fecc1a84afc79.content new file mode 100644 index 00000000..3740bec7 --- /dev/null +++ b/resources/_gen/assets/other_cc26ecf2d7346e08055fecc1a84afc79.content @@ -0,0 +1,7 @@ +@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:100;src:local("Roboto Slab Thin "),local("Roboto Slab-Thin"),url(/fonts/roboto-slab-latin-100.woff2) format("woff2"),url(/fonts/roboto-slab-latin-100.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:200;src:local("Roboto Slab Extra Light "),local("Roboto Slab-Extra Light"),url(/fonts/roboto-slab-latin-200.woff2) format("woff2"),url(/fonts/roboto-slab-latin-200.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:300;src:local("Roboto Slab Light "),local("Roboto Slab-Light"),url(/fonts/roboto-slab-latin-300.woff2) format("woff2"),url(/fonts/roboto-slab-latin-300.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:400;src:local("Roboto Slab Regular "),local("Roboto Slab-Regular"),url(/fonts/roboto-slab-latin-400.woff2) format("woff2"),url(/fonts/roboto-slab-latin-400.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:500;src:local("Roboto Slab Medium "),local("Roboto Slab-Medium"),url(/fonts/roboto-slab-latin-500.woff2) format("woff2"),url(/fonts/roboto-slab-latin-500.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:600;src:local("Roboto Slab SemiBold "),local("Roboto Slab-SemiBold"),url(/fonts/roboto-slab-latin-600.woff2) format("woff2"),url(/fonts/roboto-slab-latin-600.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:700;src:local("Roboto Slab Bold "),local("Roboto Slab-Bold"),url(/fonts/roboto-slab-latin-700.woff2) format("woff2"),url(/fonts/roboto-slab-latin-700.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:800;src:local("Roboto Slab ExtraBold "),local("Roboto Slab-ExtraBold"),url(/fonts/roboto-slab-latin-800.woff2) format("woff2"),url(/fonts/roboto-slab-latin-800.woff) format("woff")}@font-face{font-display:swap;font-family:Roboto Slab;font-style:normal;font-weight:900;src:local("Roboto Slab Black "),local("Roboto Slab-Black"),url(/fonts/roboto-slab-latin-900.woff2) format("woff2"),url(/fonts/roboto-slab-latin-900.woff) format("woff")}@font-face{font-display:swap;font-family:Fira Code;font-style:normal;font-weight:300;src:local("Fira Code Light "),local("Fira Code-Light"),url(/fonts/fira-code-latin-300.woff2) format("woff2"),url(/fonts/fira-code-latin-300.woff) format("woff")}@font-face{font-display:swap;font-family:Fira Code;font-style:normal;font-weight:400;src:local("Fira Code Regular "),local("Fira Code-Regular"),url(/fonts/fira-code-latin-400.woff2) format("woff2"),url(/fonts/fira-code-latin-400.woff) format("woff")}@font-face{font-display:swap;font-family:Fira Code;font-style:normal;font-weight:500;src:local("Fira Code Medium "),local("Fira Code-Medium"),url(/fonts/fira-code-latin-500.woff2) format("woff2"),url(/fonts/fira-code-latin-500.woff) format("woff")}@font-face{font-display:swap;font-family:Fira Code;font-style:normal;font-weight:600;src:local("Fira Code SemiBold "),local("Fira Code-SemiBold"),url(/fonts/fira-code-latin-600.woff2) format("woff2"),url(/fonts/fira-code-latin-600.woff) format("woff")}@font-face{font-display:swap;font-family:Fira Code;font-style:normal;font-weight:700;src:local("Fira Code Bold "),local("Fira Code-Bold"),url(/fonts/fira-code-latin-700.woff2) format("woff2"),url(/fonts/fira-code-latin-700.woff) format("woff")} + +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;-webkit-text-decoration:underline;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none} + +/*! CC BY-SA 3.0 License | https://stackoverflow.com/a/36118384/1154965 */@keyframes blink{50%{opacity:0}to{opacity:1}} + +/*! MIT License | github.com/schnerring/hugo-theme-gruvbox */:root[data-theme=light]{--bg:var(--bg0);--bg0:#fbf1c7;--bg0_h:#f9f5d7;--bg0_s:#f2e5bc;--bg1:#ebdbb2;--bg2:#d5c4a1;--bg3:#bdae93;--bg4:#a89984;--fg:var(--fg1);--fg0:#282828;--fg1:#3c3836;--fg2:#504945;--fg3:#665c54;--fg4:#7c6f64;--gray1:var(--fg4);--gray2:#928374;--red1:#cc241d;--red2:#9d0006;--green1:#98971a;--green2:#797403;--yellow1:#d79921;--yellow2:#b57614;--blue1:#458588;--blue2:#076678;--purple1:#b16286;--purple2:#8f3f71;--aqua1:#689d6a;--aqua2:#427b58;--orange1:#d65d0e;--orange2:#af3a03}:root[data-theme=dark]{--bg:var(--bg0);--bg0:#282828;--bg0_h:#1d2021;--bg0_s:#32302f;--bg1:#3c3836;--bg2:#504945;--bg3:#665c54;--bg4:#7c6f64;--fg:var(--fg1);--fg0:#fbf1c7;--fg1:#ebdbb2;--fg2:#d5c4a1;--fg3:#bdae93;--fg4:#a89984;--gray1:var(--fg4);--gray2:#928374;--red1:#cc241d;--red2:#fb4934;--green1:#98971a;--green2:#b8bb26;--yellow1:#d79921;--yellow2:#fabd2f;--blue1:#458588;--blue2:#83a598;--purple1:#b16286;--purple2:#d3869b;--aqua1:#689d6a;--aqua2:#8ec07c;--orange1:#d65d0e;--orange2:#fe8019}:root{--primary:var(--blue1);--primary-alt:var(--blue2);--font-monospace:"Fira Code","Lucida Console",Monaco,monospace;--font-sans-serif:Verdana,Helvetica,sans-serif;--font-serif:"Roboto Slab",Georgia,serif}::-moz-selection{background:var(--bg4);color:var(--fg0)}::selection{background:var(--bg4);color:var(--fg0)}.search{display:flex;grid-area:search;margin:0 1rem}#search__text{background:var(--bg2);border:1px solid var(--bg2);border-radius:.2rem;caret-color:var(--fg);color:var(--fg);outline:none;padding:0 .5rem;width:100%}#search__text:hover{border-color:var(--bg3)}#search__text:focus{border-color:var(--bg4)}#search__text::-moz-placeholder{color:var(--fg3)}#search__text::placeholder{color:var(--fg3)}#search__text[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}#search__suggestions{background:var(--bg);border-radius:.2rem;box-shadow:0 .5rem 1rem var(--bg1);font-family:Roboto Slab,Georgia,serif;font-family:var(--font-serif);left:0;margin-top:2rem;position:absolute;width:95vw;z-index:1000}@media (min-width:768px){.search{position:relative}#search__suggestions{width:60vw}}.search__suggestions--hidden{display:none}.search__suggestion-item{border-bottom:1px dashed var(--bg2);display:grid;grid-template-columns:1fr 2fr}.search__suggestion-item:focus,.search__suggestion-item:focus-visible,.search__suggestion-item:hover{background:var(--bg1);cursor:pointer;outline:none}.search__suggestion-item:last-child{border:none}.search__suggestion-description,.search__suggestion-title{margin:1rem 0;padding:0 1rem}.search__suggestion-title{font-weight:700}.search__suggestion-description{border-left:1px solid var(--bg2)}.search__no-results{padding:.75rem} \ No newline at end of file diff --git a/resources/_gen/assets/other_cc26ecf2d7346e08055fecc1a84afc79.json b/resources/_gen/assets/other_cc26ecf2d7346e08055fecc1a84afc79.json new file mode 100644 index 00000000..75494130 --- /dev/null +++ b/resources/_gen/assets/other_cc26ecf2d7346e08055fecc1a84afc79.json @@ -0,0 +1 @@ +{"Target":".","MediaType":"application/octet-stream","Data":{}} \ No newline at end of file diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_box_3.png b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_box_3.png new file mode 100644 index 00000000..5373c34b Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..5ea140f1 Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_box_3.png b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_box_3.png new file mode 100644 index 00000000..05ee5597 Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f39a5534 Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_box_3.png b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_box_3.png new file mode 100644 index 00000000..1c62a854 Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..c66a5f9f Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/install-mailplus-server_hu44978467cf355ace52c86216e9adcb07_30909_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_box_3.png b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_box_3.png new file mode 100644 index 00000000..03ab2b69 Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..4ce13bd4 Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_box_3.png b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_box_3.png new file mode 100644 index 00000000..09b76aca Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..538df32a Binary files /dev/null and b/resources/_gen/images/post/backing-up-gmail-with-synology/mail-plus-incoming-mail_hu9ddd0265c16cd611df4e36648057a118_53092_433x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_box_3.png b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_box_3.png new file mode 100644 index 00000000..d01addcb Binary files /dev/null and b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..aadff9dd Binary files /dev/null and b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_box_3.png b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_box_3.png new file mode 100644 index 00000000..cb8e8661 Binary files /dev/null and b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..2a9c9261 Binary files /dev/null and b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_box_3.png b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_box_3.png new file mode 100644 index 00000000..e262f78f Binary files /dev/null and b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..81ee6417 Binary files /dev/null and b/resources/_gen/images/post/setting-up-gitea-actions-with-tailscale/gitea-runners_hub2705fca9eca2ad49032b5d26e38ba63_36278_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_box_3.png new file mode 100644 index 00000000..2d9fa4f3 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..dfe254af Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_box_3.png new file mode 100644 index 00000000..75f3d1d1 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..57242a9e Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_box_3.png new file mode 100644 index 00000000..28d24643 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..49d34094 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-port-pvid_hucba536e6a1c36d3eba5afa50576e38e1_34094_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_box_3.png new file mode 100644 index 00000000..147da493 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f6eec9f9 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_box_3.png new file mode 100644 index 00000000..7fe7e802 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..3247b7f4 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_box_3.png new file mode 100644 index 00000000..becd0d9f Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f85294b9 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-configuration_hu15e5056e9ef99b27d88357dc2a65692f_42578_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_box_3.png new file mode 100644 index 00000000..69ca855a Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..85f43eff Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_box_3.png new file mode 100644 index 00000000..94c74632 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..be088172 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_box_3.png new file mode 100644 index 00000000..afca5534 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..358db32c Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-10_hue1e5d029f0ad357e37b4f4dea2ed5f90_37319_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_box_3.png new file mode 100644 index 00000000..14342de1 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..acdb932d Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_box_3.png new file mode 100644 index 00000000..3bc3f3dc Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..568aaf9d Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_box_3.png new file mode 100644 index 00000000..1cce7e4b Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..fa67542b Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/netgear-vlan-membership-1_hue1e5d029f0ad357e37b4f4dea2ed5f90_36344_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_box_3.png new file mode 100644 index 00000000..be30375c Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..1b524eb7 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_box_3.png new file mode 100644 index 00000000..044410f4 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..5925df7f Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_box_3.png b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_box_3.png new file mode 100644 index 00000000..6029089f Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..9645bb15 Binary files /dev/null and b/resources/_gen/images/post/virtualizing-a-router-with-pfsense/pfsense-dashboard_hu7b4fdbe22d7ed98f90e451e0d2c7f8c0_92631_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_box_3.png b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_box_3.png new file mode 100644 index 00000000..3682cacc Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..f793d980 Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_box_3.png b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_box_3.png new file mode 100644 index 00000000..e50e46f3 Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..76f01642 Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_box_3.png b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_box_3.png new file mode 100644 index 00000000..f1e813c6 Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..d2cdafbf Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/computerphile_huab6e3127a0b06a834b4e3cd718370398_957247_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_box_3.png b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_box_3.png new file mode 100644 index 00000000..a2b4db08 Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..48af65a9 Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_box_3.png b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_box_3.png new file mode 100644 index 00000000..fdcb6cca Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..39e8d85b Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_box_3.png b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_box_3.png new file mode 100644 index 00000000..d999a497 Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..d024bbfb Binary files /dev/null and b/resources/_gen/images/post/watching-youtube-in-private/requestly-rules_hucd7a47e92b94540e7a76322ee330fb89_88020_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_box_3.png new file mode 100644 index 00000000..c4bd8e24 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..6cb24f63 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_box_3.png new file mode 100644 index 00000000..d64e5545 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..84d6a1a2 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_box_3.png new file mode 100644 index 00000000..331ad27f Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..35c55c76 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/netdata_hu78bc2e52079d7a1d3cf726e171d4b7dc_70867_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_box_3.png new file mode 100644 index 00000000..789280b7 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..3c2deefe Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_box_3.png new file mode 100644 index 00000000..735594a3 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..221bcc64 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_box_3.png new file mode 100644 index 00000000..4e6011ee Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..b524a6ae Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/proxmox_hu301314f34acbd231910aa3e526d496c0_160705_700x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_box_3.png new file mode 100644 index 00000000..856fda81 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..367b2845 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_300x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_box_3.png new file mode 100644 index 00000000..bdf1fdf9 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..b6fc8f43 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_500x0_resize_q75_h2_box_3.webp differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_box_3.png b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_box_3.png new file mode 100644 index 00000000..6ce19142 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_box_3.png differ diff --git a/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_q75_h2_box_3.webp b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_q75_h2_box_3.webp new file mode 100644 index 00000000..a0f8a0c9 Binary files /dev/null and b/resources/_gen/images/post/what-to-do-with-a-homelab/uptime-kuma_hue98ab284e327523b28029e370b7b9d34_120263_700x0_resize_q75_h2_box_3.webp differ diff --git a/themes/archie/.github/FUNDING.yml b/themes/archie/.github/FUNDING.yml deleted file mode 100644 index 8466ce7a..00000000 --- a/themes/archie/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -# These are supported funding model platforms - -custom: https://www.buymeacoffee.com/athulca diff --git a/themes/archie/LICENSE b/themes/archie/LICENSE deleted file mode 100644 index 646ad351..00000000 --- a/themes/archie/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2020 ATHUL CYRIAC AJAY - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/themes/archie/README.md b/themes/archie/README.md deleted file mode 100644 index 9da1ad96..00000000 --- a/themes/archie/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# Archie - Hugo theme -Archie is a minimal and clean theme for hugo with a markdown-ish UI. - -Forked from [Ezhil Theme](https://github.com/vividvilla/ezhil) - -## Demo - -[Check the Demo](https://athul.github.io/archie/) hosted on GitHub Pages :smile: . You can find the source code to that in the `site` branch of this repository - -![](/images/theme.png) -![](/images/archie-dark.png) -## Feature -- Google Analytics Script -- Callouts -- Tags -- Auto Dark Mode(based on system theme) -- Dark/Light Mode toggle -- tl:dr; frontamatter -- Cache busting for CSS files - -## Installation -In your Hugo website directory, create a new folder named theme and clone the repo -```bash -$ mkdir themes -$ cd themes -$ git clone https://github.com/athul/archie.git -``` -Edit the `config.toml` file with `theme="archie"` -For more information read the official [setup guide](https://gohugo.io/installation/) of Hugo. - -## Writing Posts -Create a new `.md` file in the *content/posts* folder -```yml ---- -title: Title of the post -description: -date: -tldr: (optional) -draft: true/false (optional) -tags: [tag names] (optional) ---- -``` - -## Credits -Forked from [Ezhil Theme](https://github.com/vividvilla/ezhil) and Licensed under MIT License -Inspired by design of blog.jse.li - ----- - -## Config Options - -### Custom CSS -Custom CSS files can be included though the `customcss` config parameter. - -Note: CSS files should be placed under the `assets` directory e.g. `assets/css/first.css`. - -```toml -[params] - customcss = ["css/first.css", "css/second.css"] -``` - - -## Config of the Demo Site - -```toml -baseURL = "https://athul.github.io/archie/" -languageCode = "en-us" -title = "Archie" -theme="archie" -copyright = "© Athul" -# Code Highlight -pygmentsstyle = "monokai" -pygmentscodefences = true -pygmentscodefencesguesssyntax = true - -paginate=3 # articles per page - -[params] - mode="auto" # color-mode → light,dark,toggle or auto - useCDN=false # don't use CDNs for fonts and icons, instead serve them locally. - subtitle = "Minimal and Clean [blog theme for Hugo](https://github.com/athul/archie)" - mathjax = true # enable MathJax support - katex = true # enable KaTeX support - -# Social Tags - -[[params.social]] -name = "GitHub" -icon = "github" -url = "https://github.com/athul/archie" - -[[params.social]] -name = "Twitter" -icon = "twitter" -url = "https://twitter.com/athulcajay/" - -[[params.social]] -name = "GitLab" -icon = "gitlab" -url = "https://gitlab.com/athul/" - -# Main menu Items - -[[menu.main]] -name = "Home" -url = "/" -weight = 1 - -[[menu.main]] -name = "All posts" -url = "/posts" -weight = 2 - -[[menu.main]] -name = "About" -url = "/about" -weight = 3 - -[[menu.main]] -name = "Tags" -url = "/tags" -weight = 4 -``` ---- - -If you liked my work please consider supporting me on [BuymeACoffee](https://www.buymeacoffee.com/athulca) - -Buy Me A Coffee diff --git a/themes/archie/archetypes/default.md b/themes/archie/archetypes/default.md deleted file mode 100644 index ac36e062..00000000 --- a/themes/archie/archetypes/default.md +++ /dev/null @@ -1,2 +0,0 @@ -+++ -+++ diff --git a/themes/archie/assets/css/copy-code-button.css b/themes/archie/assets/css/copy-code-button.css deleted file mode 100644 index 1981ba95..00000000 --- a/themes/archie/assets/css/copy-code-button.css +++ /dev/null @@ -1,103 +0,0 @@ -.highlight-wrapper { - display: block; -} - -/* Start: Turn off individual column border, margin, and padding when line numbers are showing */ -.highlight-wrapper .lntd pre { - padding: 0; -} - -.chroma .lntd pre { - border: 0px solid #ccc; -} - -.chroma .lntd:first-child { - padding: 7px 7px 7px 10px; - margin: 0; -} - -.chroma .lntd:last-child { - padding: 7px 10px 7px 7px; - margin: 0; -} -/* End: Turn off individual column border, margin, and padding when line numbers are showing */ - -.highlight { - position: relative; - z-index: 0; - padding: 0; - margin: 40px 0 10px 0; - border-radius: 4px; -} - -.highlight > .chroma { - position: static; - z-index: 1; - border-top-left-radius: 0px; - border-top-right-radius: 0px; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - padding: 10px; -} - -.copy-code-button { - position: absolute; - z-index: 2; - right: 0; - top: -29px; - font-size: 13px; - font-weight: 700; - line-height: 14px; - letter-spacing: 0.5px; - width: 65px; - color: #ffffff; - background-color: #000000; - border: 1.25px solid #232326; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-right-radius: 0px; - border-bottom-left-radius: 0px; - white-space: nowrap; - padding: 6px 6px 7px 6px; - margin: 0 0 0 1px; - cursor: pointer; - opacity: 0.6; -} - -.copy-code-button:hover, -.copy-code-button:focus, -.copy-code-button:active, -.copy-code-button:active:hover { - color: #222225; - background-color: #b3b3b3; - opacity: 0.8; -} - -.copyable-text-area { - position: absolute; - height: 0; - z-index: -1; - opacity: 0.01; -} -.chroma [data-lang]:before { - position: absolute; - z-index: 0; - top: -29px; - left: 0; - content: attr(data-lang); - font-size: 13px; - font-weight: 700; - color: white; - background-color: black; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - padding: 6px 6px 7px 6px; - line-height: 14px; - opacity: 0.6; - position: absolute; - letter-spacing: 0.5px; - border: 1.25px solid #232326; - margin: 0 0 0 1px; -} diff --git a/themes/archie/assets/css/dark.css b/themes/archie/assets/css/dark.css deleted file mode 100644 index 6b651fde..00000000 --- a/themes/archie/assets/css/dark.css +++ /dev/null @@ -1,153 +0,0 @@ -body { - color: white; - background-color: #202124; -} - -::-moz-selection { - background: blue; - color: #fff; - text-shadow: none; -} - -::selection { - background: rgb(212, 240, 32); - color: #000000; - text-shadow: none; -} - -hr { - border-top: 3px dotted blue; -} -code { - background-color: rgb(184, 189, 190); - color: black; - text-decoration: bold; - padding: 0em 0.1em; -} -pre { - background-color: #272822; - line-height: 1.4; - overflow-x: auto; - padding: 1em; -} -blockquote { - border-color: #ddd; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - color: #ddd; -} -h1::before { - color: var(--darkMaincolor); -} -h2::before { - color: var(--darkMaincolor); -} -h3::before { - color: var(--darkMaincolor); -} -h4::before { - color: var(--darkMaincolor); -} -h5::before { - color: var(--darkMaincolor); -} -h6::before { - color: var(--darkMaincolor); -} - -a { - border-bottom: 3px solid var(--darkMaincolor); - color: inherit; -} -a:hover { - background-color: var(--darkMaincolor); - color: black; -} - -.site-description a { - color: #ddd; -} -.site-description a:hover { - color: black; -} - -.tags a { - border-bottom: 3px solid var(--darkMaincolor); -} -.tags a:hover { - background-color: var(--darkMaincolor); - color: black; -} - -.site-title a { - color: white; - text-decoration: none !important; -} - -.header nav, -.footer { - border-color: #333; -} - -.highlight { - background-color: #333; -} -.soc:hover { - color: black; -} -.draft-label { - color: var(--darkMaincolor); - background-color: blue; -} -.highlight pre code[class="language-javaScript"]::before, -.highlight pre code[class="language-js"]::before { - content: "js"; - background: #f7df1e; - color: black; -} -.highlight pre code[class*="language-yml"]::before, -.highlight pre code[class*="language-yaml"]::before { - content: "yaml"; - background: #f71e6a; - color: white; -} -.highlight pre code[class*="language-shell"]::before, -.highlight pre code[class*="language-bash"]::before, -.highlight pre code[class*="language-sh"]::before { - content: "shell"; - background: rgb(118, 137, 118); - color: white; -} -.highlight pre code[class*="language-json"]::before { - content: "json"; - background: dodgerblue; - color: #000000; -} -.highlight pre code[class*="language-python"]::before, -.highlight pre code[class*="language-py"]::before { - content: "py"; - background: blue; - color: yellow; -} -.highlight pre code[class*="language-css"]::before { - content: "css"; - background: cyan; - color: black; -} -.highlight pre code[class*="language-go"]::before { - content: "Go"; - background: cyan; - color: royalblue; -} -.highlight pre code[class*="language-md"]::before, -.highlight pre code[class*="language-md"]::before { - content: "Markdown"; - background: royalblue; - color: whitesmoke; -} diff --git a/themes/archie/assets/css/fonts.css b/themes/archie/assets/css/fonts.css deleted file mode 100644 index 9b88deea..00000000 --- a/themes/archie/assets/css/fonts.css +++ /dev/null @@ -1,57 +0,0 @@ -/* fira-sans-regular - latin */ -@font-face { - font-display: swap; - font-family: "Fira Sans"; - font-style: normal; - font-weight: 400; - src: url("../fonts/fira-sans-v10-latin-regular.eot"); /* IE9 Compat Modes */ - src: local("Fira Sans Regular"), local("FiraSans-Regular"), - url("../fonts/fira-sans-v10-latin-regular.eot?#iefix") - format("embedded-opentype"), - /* IE6-IE8 */ url("../fonts/fira-sans-v10-latin-regular.woff2") - format("woff2"), - /* Super Modern Browsers */ url("../fonts/fira-sans-v10-latin-regular.woff") - format("woff"), - /* Modern Browsers */ url("../fonts/fira-sans-v10-latin-regular.ttf") - format("truetype"), - /* Safari, Android, iOS */ - url("../fonts/fira-sans-v10-latin-regular.svg#FiraSans") format("svg"); /* Legacy iOS */ -} -/* roboto-mono-regular - latin */ -@font-face { - font-display: swap; - font-family: "Roboto Mono"; - font-style: normal; - font-weight: 400; - src: url("../fonts/roboto-mono-v12-latin-regular.eot"); /* IE9 Compat Modes */ - src: url("../fonts/roboto-mono-v12-latin-regular.eot?#iefix") - format("embedded-opentype"), - /* IE6-IE8 */ url("../fonts/roboto-mono-v12-latin-regular.woff2") - format("woff2"), - /* Super Modern Browsers */ - url("../fonts/roboto-mono-v12-latin-regular.woff") format("woff"), - /* Modern Browsers */ url("../fonts/roboto-mono-v12-latin-regular.ttf") - format("truetype"), - /* Safari, Android, iOS */ - url("../fonts/roboto-mono-v12-latin-regular.svg#RobotoMono") format("svg"); /* Legacy iOS */ -} -/* ibm-plex-mono-500italic - latin */ -@font-face { - font-display: swap; - font-family: "IBM Plex Mono"; - font-style: italic; - font-weight: 500; - src: url("../fonts/ibm-plex-mono-v6-latin-500italic.eot"); /* IE9 Compat Modes */ - src: local("IBM Plex Mono Medium Italic"), local("IBMPlexMono-MediumItalic"), - url("../fonts/ibm-plex-mono-v6-latin-500italic.eot?#iefix") - format("embedded-opentype"), - /* IE6-IE8 */ url("../fonts/ibm-plex-mono-v6-latin-500italic.woff2") - format("woff2"), - /* Super Modern Browsers */ - url("../fonts/ibm-plex-mono-v6-latin-500italic.woff") format("woff"), - /* Modern Browsers */ url("../fonts/ibm-plex-mono-v6-latin-500italic.ttf") - format("truetype"), - /* Safari, Android, iOS */ - url("../fonts/ibm-plex-mono-v6-latin-500italic.svg#IBMPlexMono") - format("svg"); /* Legacy iOS */ -} diff --git a/themes/archie/assets/css/main.css b/themes/archie/assets/css/main.css deleted file mode 100644 index ad5b32c6..00000000 --- a/themes/archie/assets/css/main.css +++ /dev/null @@ -1,349 +0,0 @@ -/* Markdown */ -:root { - --maincolor: #a15bc2; - --bordercl: #a15bc2; - --callouctcolor: dodgerblue; - --hovercolor: #a15bc2; - --darkMaincolor: #a15bc2; -} -html { - color: #232333; - font-family: "Roboto Mono", monospace; - font-size: 18px; - line-height: 1.6em; -} -body { - display: block; - background-color: #f8f8f8; - margin: 8px; -} -* { - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -::selection { - background: #eef35c; - color: #000000; -} - -p { - font-family: "Roboto Light", sans-serif; - line-height: 1.5; -} - -hr { - border: 0; - border-top: 3px dotted var(--bordercl); - margin: 1em 0; -} - -blockquote { - border-left: 3px solid var(--bordercl); - color: #737373; - margin: 0; - padding-left: 1em; -} - -a { - border-bottom: 3px solid var(--maincolor); - color: inherit; - text-decoration: none; -} -a:hover { - background-color: var(--hovercolor); - color: #fff; -} - -ul { - list-style: none; - padding-left: 2ch; -} -ul li { - text-indent: -2ch; -} -ul > li::before { - content: "* "; - font-weight: bold; -} - -/* Images */ -img { - max-width: 100%; -} - -figure { - box-sizing: border-box; - display: inline-block; - margin: 0; - max-width: 100%; -} - -figure img { - max-height: 500px; -} - -@media screen and (min-width: 600px) { - figure { - padding: 0 40px; - } -} - -figure h4 { - font-size: 1rem; - margin: 0; - margin-bottom: 1em; -} -figure h4::before { - content: "↳ "; -} - -/* Code blocks */ -code { - background-color: #f1f1f1; - padding: 0em 0.1em; -} - -pre { - background-color: #ececec; - line-height: 1.4; - overflow-x: auto; - padding: 1em; -} - -.highlight pre ::selection { - background: var(--maincolor); - color: inherit; -} - -pre code { - background-color: transparent; - color: inherit; - font-size: 100%; - padding: 0; -} - -/* Containers */ -.content { - margin-bottom: 4em; - margin-left: auto; - margin-right: auto; - max-width: 800px; - padding: 0 1ch; - word-wrap: break-word; -} - -/* Header */ -header { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - margin: 1em 0; - line-height: 2.5em; -} - -header .main { - font-size: 1.5rem; -} -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: 1.2rem; - margin-top: 2em; -} - -h1::before { - color: var(--maincolor); -} -h2::before { - color: var(--maincolor); -} -h3::before { - color: var(--maincolor); -} -h4::before { - color: var(--maincolor); -} -h5::before { - color: var(--maincolor); -} -h6::before { - color: var(--maincolor); -} - -.meta { - color: #999; - letter-spacing: -0.5px; -} - -/* Footer */ -footer { - display: flex; - align-items: center; - border-top: 0.4rem dotted var(--bordercl); - padding: 2rem 0rem; - margin-top: 2rem; -} -.soc { - display: flex; - align-items: center; - border-bottom: none; -} -.border { - margin-left: 0.5rem; - margin-right: 0.5rem; - border: 1px solid; -} -.footer-info { - padding: var(--footer-padding); -} - -/* Common */ -.title h1 { - margin-bottom: 0; -} - -time { - color: grey; -} - -/* Posts */ -article .title { - margin-bottom: 1em; -} - -/* Callout */ -.callout { - background-color: var(--callouctcolor); - color: #fff; - padding: 1em; -} - -.callout p { - font-family: "IBM Plex Mono", monospace; - margin: 0; -} - -.callout a { - border-bottom: 3px solid #fff; -} - -.callout a:hover { - background-color: #fff; - color: var(--callouctcolor); -} - -.site-description { - display: flex; - justify-content: space-between; -} -.tags li::before { - content: "- "; -} -.tags a { - border-bottom: 3px solid var(--maincolor); -} -.tags a:hover { - color: white; - background-color: var(--hovercolor); -} -svg { - max-height: 15px; -} -.soc:hover { - color: white; -} -.draft-label { - color: var(--bordercl); - text-decoration: none; - padding: 2px 4px; - border-radius: 4px; - margin-left: 6px; - background-color: #f9f2f4; -} -.highlight { - position: relative; - -webkit-overflow-scrolling: touch; -} -.highlight pre code[class*="language-"] { - -webkit-overflow-scrolling: touch; -} -.highlight pre code[class*="language-"]::before { - background: black; - border-radius: 0 0 0.25rem 0.25rem; - color: white; - font-size: 12px; - letter-spacing: 0.025rem; - padding: 0.1rem 0.5rem; - position: absolute; - right: 1rem; - text-align: right; - text-transform: uppercase; - top: 0; -} - -.highlight pre code[class="language-javaScript"]::before, -.highlight pre code[class="language-js"]::before { - content: "js"; - background: #f7df1e; - color: black; -} -.highlight pre code[class*="language-yml"]::before, -.highlight pre code[class*="language-yaml"]::before { - content: "yaml"; - background: #f71e6a; - color: white; -} -.highlight pre code[class*="language-shell"]::before, -.highlight pre code[class*="language-bash"]::before, -.highlight pre code[class*="language-sh"]::before { - content: "shell"; - background: green; - color: white; -} -.highlight pre code[class*="language-json"]::before { - content: "json"; - background: dodgerblue; - color: #000000; -} -.highlight pre code[class*="language-python"]::before, -.highlight pre code[class*="language-py"]::before { - content: "py"; - background: blue; - color: yellow; -} -.highlight pre code[class*="language-css"]::before { - content: "css"; - background: cyan; - color: black; -} -.highlight pre code[class*="language-go"]::before { - content: "Go"; - background: cyan; - color: royalblue; -} -.highlight pre code[class*="language-md"]::before, -.highlight pre code[class*="language-md"]::before { - content: "Markdown"; - background: royalblue; - color: whitesmoke; -} - -/* table */ -table { - border-spacing: 0; - border-collapse: collapse; -} - -table th { - padding: 6px 13px; - border: 1px solid #dfe2e5; - font-size: large; -} - -table td { - padding: 6px 13px; - border: 1px solid #dfe2e5; -} diff --git a/themes/archie/exampleSite/archetypes/default.md b/themes/archie/exampleSite/archetypes/default.md deleted file mode 100644 index 26f317f3..00000000 --- a/themes/archie/exampleSite/archetypes/default.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "{{ replace .Name "-" " " | title }}" -date: {{ .Date }} -draft: true ---- diff --git a/themes/archie/exampleSite/config.toml b/themes/archie/exampleSite/config.toml deleted file mode 100644 index af5063e1..00000000 --- a/themes/archie/exampleSite/config.toml +++ /dev/null @@ -1,46 +0,0 @@ -baseURL = "https://example.com" -languageCode = "en-us" -title = "Archie" -theme="archie" -copyright = "© Athul" -pygmentsstyle = "monokai" -pygmentscodefences = true -pygmentscodefencesguesssyntax = true -[params] - mode="auto" - useCDN=false - subtitle = "Minimal and Clean [blog theme for Hugo](https://github.com/athul/archie)" - -[[params.social]] -name = "GitHub" -icon = "github" -url = "https://github.com/athul/archie" - -[[params.social]] -name = "Twitter" -icon = "twitter" -url = "https://github.com/athulcajay/" - -[[params.social]] -name = "GitLab" -icon = "gitlab" -url = "https://gitlab.com/athul/" -[[menu.main]] -name = "Home" -url = "/" -weight = 1 - -[[menu.main]] -name = "All posts" -url = "/posts" -weight = 2 - -[[menu.main]] -name = "About" -url = "/about" -weight = 3 - -[[menu.main]] -name = "Tags" -url = "/tags" -weight = 4 diff --git a/themes/archie/exampleSite/content/_index.md b/themes/archie/exampleSite/content/_index.md deleted file mode 100644 index 6abc75e1..00000000 --- a/themes/archie/exampleSite/content/_index.md +++ /dev/null @@ -1,4 +0,0 @@ -+++ -author = "Hugo Authors" -+++ - diff --git a/themes/archie/exampleSite/content/about.md b/themes/archie/exampleSite/content/about.md deleted file mode 100644 index a4128062..00000000 --- a/themes/archie/exampleSite/content/about.md +++ /dev/null @@ -1,28 +0,0 @@ -+++ -title = "About" -description = "Hugo, the world’s fastest framework for building websites" -date = "2019-02-28" -aliases = ["about-us","about-hugo","contact"] -author = "Hugo Authors" -+++ - -Written in Go, Hugo is an open source static site generator available under the [Apache Licence 2.0.](https://github.com/gohugoio/hugo/blob/master/LICENSE) Hugo supports TOML, YAML and JSON data file types, Markdown and HTML content files and uses shortcodes to add rich content. Other notable features are taxonomies, multilingual mode, image processing, custom output formats, HTML/CSS/JS minification and support for Sass SCSS workflows. - -Hugo makes use of a variety of open source projects including: - -* https://github.com/yuin/goldmark -* https://github.com/alecthomas/chroma -* https://github.com/muesli/smartcrop -* https://github.com/spf13/cobra -* https://github.com/spf13/viper - -Hugo is ideal for blogs, corporate websites, creative portfolios, online magazines, single page applications or even a website with thousands of pages. - -Hugo is for people who want to hand code their own website without worrying about setting up complicated runtimes, dependencies and databases. - -Websites built with Hugo are extremelly fast, secure and can be deployed anywhere including, AWS, GitHub Pages, Heroku, Netlify and any other hosting provider. - -Learn more and contribute on [GitHub](https://github.com/gohugoio). - - - diff --git a/themes/archie/exampleSite/content/archives.md b/themes/archie/exampleSite/content/archives.md deleted file mode 100644 index 98a1ee9d..00000000 --- a/themes/archie/exampleSite/content/archives.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -date: 2019-05-28 -type: section -layout: "archives" ---- \ No newline at end of file diff --git a/themes/archie/exampleSite/content/homepage/about.md b/themes/archie/exampleSite/content/homepage/about.md deleted file mode 100644 index c2ba6802..00000000 --- a/themes/archie/exampleSite/content/homepage/about.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: 'Our Difference' -button: 'About us' -weight: 2 ---- - -Lorem ipsum dolor sit amet, et essent mediocritatem quo, choro volumus oporteat an mei. ipsum dolor sit amet, et essent mediocritatem quo, \ No newline at end of file diff --git a/themes/archie/exampleSite/content/homepage/index.md b/themes/archie/exampleSite/content/homepage/index.md deleted file mode 100644 index 01ffa31a..00000000 --- a/themes/archie/exampleSite/content/homepage/index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -headless : true ---- diff --git a/themes/archie/exampleSite/content/homepage/work.md b/themes/archie/exampleSite/content/homepage/work.md deleted file mode 100644 index f2fee737..00000000 --- a/themes/archie/exampleSite/content/homepage/work.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: 'We Help Business Grow' -button: 'Our Work' -weight: 1 ---- - -Lorem ipsum dolor sit amet, et essent mediocritatem quo, choro volumus oporteat an mei. Numquam dolores mel eu, mea docendi omittantur et, mea ea duis erat. Elit melius cu ius. Per ex novum tantas putant, ei his nullam aliquam apeirian. Aeterno quaestio constituto sea an, no eum intellegat assueverit. \ No newline at end of file diff --git a/themes/archie/exampleSite/content/posts/post-1.md b/themes/archie/exampleSite/content/posts/post-1.md deleted file mode 100644 index 293bdc3f..00000000 --- a/themes/archie/exampleSite/content/posts/post-1.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: "Primer: When You Have Too Much to Do" -date: 2020-04-01T02:01:58+05:30 -description: "You have a to-do list that scrolls on for days. You are managing multiple projects, getting lots of email and messages on different messaging systems, managing finances and personal health habits and so much more." -tags: [Primer, todo] ---- - -You have a to-do list that scrolls on for days. You are managing multiple projects, getting lots of email and messages on different messaging systems, managing finances and personal health habits and so much more. - -It all keeps piling up, and it can feel overwhelming. - -How do you keep up with it all? How do you find focus and peace and get stuff accomplished when you have too much on your plate? - -In this primer, I’ll look at some key strategies and tactics for taking on an overloaded life with an open heart, lots of energy, and a smile on your face. - -## The First Step: Triage - -Whether you’re just starting your day, or you’re in the middle of the chaos and just need to find some sanity … the first step is to get into triage mode. - -Triage, as you probably know, is sorting through the chaos to prioritize: what needs to be done now, what needs to be done today, what needs to be done this week, and what can wait? You’re looking at urgency, but also what’s meaningful and important. - -Here’s what you might do: - -* Pick out the things that need to be done today. Start a Short List for things you’re going to do today. That might be important tasks for big projects, urgent tasks that could result in damage if you don’t act, smaller admin tasks that you really should take care of today, and responding to important messages. I would recommend being ruthless and cutting out as much as you can, having just 5 things on your plate if that’s at all possible. Not everything needs to be done today, and not every email needs to be responded to. -* Push some things to tomorrow and the rest of the week. If you have deadlines that can be pushed back (or renegotiated), do that. Spread the work out over the week, even into next week. What needs to be done tomorrow? What can wait a day or two longer? -* Eliminate what you can. That might mean just not replying to some messages that aren’t that important and don’t really require a reply. It might mean telling some people that you can’t take on this project after all, or that you need to get out of the commitment that you said you’d do. Yes, this is uncomfortable. For now, just put them on a list called, “To Not Do,” and plan to figure out how to get out of them later. - -OK, you have some breathing room and a manageable list now! Let’s shrink that down even further and just pick one thing. - -## Next: Focus on One Thing - -With a lot on your plate, it’s hard to pick one thing to focus on. But that’s exactly what I’m going to ask you to do. - -Pick one thing, and give it your focus. Yes, there are a lot of other things you can focus on. Yes, they’re stressing you out and making it hard to focus. But think about it this way: if you allow it all to be in your head all the time, that will always be your mode of being. You’ll always be thinking about everything, stressing out about it all, with a frazzled mind … unless you start shifting. - -The shift: - -* Pick something to focus on. Look at the triaged list from the first section … if you have 5-6 things on this Short List, you can assess whether there’s any super urgent, time-sensitive things you need to take care of. If there are, pick one of them. If not, pick the most important one — probably the one you have been putting off doing. -* Clear everything else away. Just for a little bit. Close all browser tabs, turn off notifications, close open applications, put your phone away. -* Put that one task before you, and allow yourself to be with it completely. Pour yourself into it. Think of it as a practice, of letting go (of everything else), of focus, of radical simplicity. - -When you’re done (or after 15-20 minutes have gone by at least), you can switch to something else. But don’t allow yourself to switch until then. - -By closing off all exits, by choosing one thing, by giving yourself completely to that thing … you’re now in a different mode that isn’t so stressful or spread thin. You’ve started a shift that will lead to focus and sanity. - -## Third: Schedule Time to Simplify - -Remember the To Not Do list above? Schedule some time this week to start reducing your projects, saying no to people, getting out of commitments, crossing stuff off your task list … so that you can have some sanity back. - -There are lots of little things that you’ve said “yes” to that you probably shouldn’t have. That’s why you’re overloaded. Protect your more important work, and your time off, and your peace of mind, by saying “no” to things that aren’t as important. - -Schedule the time to simplify — you don’t have to do it today, but sometime soon — and you can then not have to worry about the things on your To Not Do list until then. - -## Fourth: Practice Mindful Focus - -Go through the rest of the day with an attitude of “mindful focus.” That means that you are doing one thing at a time, being as present as you can, switching as little as you can. - -Think of it as a settling of the mind. A new mode of being. A mindfulness practice (which means you won’t be perfect at it). - -As you practice mindful focus, you’ll learn to practice doing things with an open heart, with curiosity and gratitude, and even joy. Try these one at a time as you get to do each task on your Short List. - -You’ll find that you’re not so overloaded, but that each task is just perfect for that moment. And that’s a completely new relationship with the work that you do, and a new relationship with life. diff --git a/themes/archie/exampleSite/content/posts/post-2.md b/themes/archie/exampleSite/content/posts/post-2.md deleted file mode 100644 index 54f4fde6..00000000 --- a/themes/archie/exampleSite/content/posts/post-2.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "Fearlessness: How to Stop Running from Space" -date: 2018-03-18T12:13:30+05:30 -tags: [Space] ---- - -We spend our days filling in every available space, cramming in more tasks, responding to messages, checking social media and online sites, watching videos. - -We are afraid of empty space in our lives. - -The result is often a continual busyness, constant distraction and avoidance, lack of focus, lack of satisfaction with our lives. - -We run from silence. We run from the spaces between tasks and appointments. We run from solitude and stillness. We try to fill every second with activity, with something useful, as if silence and space are not valuable. - -But what are we afraid of? - -And who would we be if we didn’t have that fear? - -We’re afraid of space and stillness and silence because it highlights the uncertainty, instability, groundlessness, insecurity, shakiness that lie underneath every second of our lives. We’re afraid of having to face this instability and uncertainty, of having to feel the fear of it. - -Without the fear of all of the uncertainty that is highlighted by space … we become free. - -I know in my life, when I allow myself to have stillness, silence, solitude, simplicity and space … it leaves room to face whatever is coming up for me. It gives me room to fully feel any feelings that I’ve been avoiding. It allows me to be more honest with myself, instead of using distractions and busyness to cover up what I don’t want to see. - -And in the end, I develop trust that the space is not something to be feared, but rather something to be treasured. A gift, filled with learning and not knowing and shakiness and beauty. - -You might try allowing more space to be in your day, without filling it: - -* Take some time between tasks for stillness. -* Sit out in nature, in silence, without technology. -* When you notice yourself reaching for your phone, pause. See if you can just be still, just savor some space. -* When you feel uncertainty or instability in your life (hint: it’s always there), let yourself feel it. Be present with it, without needing to run or avoid. -* When you feel fear, be open-hearted with it and allow yourself fully feel it, being friendly with it. Your relationship with fear will change if you become friendly with it. -* Do less, and trust that things won’t fall apart. Or if they do fall apart, you can be present with that instability. -* When you’re in line, driving, eating, walking, exercising … see if you can do those things in silence, without technology, without needing to do something “useful.” Find the value in these spaces. -* Notice who you are without the fear of space. - -Savor these spaces, their deliciousness. Savor the groundlessness, as something filled with freedom if we learn not to fear it. Be present with the fear and uncertainty, as good friends not as enemies. - -Let your heart be open raw tender and vulnerable, and your mind embracing the spaciousness of the vast blue sky of open awareness. diff --git a/themes/archie/exampleSite/content/posts/post-3.md b/themes/archie/exampleSite/content/posts/post-3.md deleted file mode 100644 index 2eb633f1..00000000 --- a/themes/archie/exampleSite/content/posts/post-3.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: "How I Learned to Stop Procrastinating, & Love Letting Go" -date: 2018-03-18T12:13:32+05:30 -description: "The art of letting go." -tags: [Procrastinating] ---- - -The end of procrastination is the art of letting go. - -I’ve been a lifelong procrastinator, at least until recent years. I would put things off until deadline, because I knew I could come through. I came through on tests after cramming last minute, I turned articles in at the deadline after waiting until the last hour, I got things done. - -Until I didn’t. It turns out procrastinating caused me to miss deadlines, over and over. It stressed me out. My work was less-than-desirable when I did it last minute. Slowly, I started to realize that procrastination wasn’t doing me any favors. In fact, it was causing me a lot of grief. - -But I couldn’t quit. I tried a lot of things. I tried time boxing and goal setting and accountability and the Pomodoro Technique and Getting Things Done. All are great methods, but they only last so long. Nothing really worked over the long term. - -That’s because I wasn’t getting to the root problem. - -I hadn’t figured out the skill that would save me from the procrastination. - -Until I learned about letting go. - -Letting go first came to me when I was quitting smoking. I had to let go of the “need” to smoke, the use of my crutch of cigarettes to deal with stress and problems. - -Then I learned I needed to let go of other false needs that were causing me problems: sugar, junk food, meat, shopping, beer, possessions. I’m not saying I can never do these things again once I let go of these needs, but I let go of the idea that they’re really necessary. I let go of an unhealthy attachment to them. - -Then I learned that distractions and the false need to check my email and news and other things online … were causing me problems. They were causing my procrastination. - -So I learned to let go of those too. - -Here’s the process I used to let go of the distractions and false needs that cause procrastination: - -I paid attention to the pain they cause me, later, instead of only the temporary comfort/pleasure they gave me right away. -I thought about the person I want to be, the life I want to live. I set my intentions to do the good work I think I should do. -I watched my urges to check things, to go to the comfort of distractions. I saw that I wanted to escape discomfort of something hard, and go to the comfort of something familiar and easy. -I realized I didn’t need that comfort. I could be in discomfort and nothing bad would happen. In fact, the best things happen when I’m in discomfort. -And then I smile, and breathe, and let go. - -And one step at a time, become the person I want to be. diff --git a/themes/archie/exampleSite/content/posts/post-4.md b/themes/archie/exampleSite/content/posts/post-4.md deleted file mode 100644 index e6609a76..00000000 --- a/themes/archie/exampleSite/content/posts/post-4.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "Getting Started with Traveling Ultralight" -date: 2020-03-18T12:13:35+05:30 -description: "Start by getting a small backpack (less than 20 liters) and then just travel with what fits in that." ---- - -I’m on a trip at the moment, and a friend who generously let me sleep on his couch looked at my small travel backpack and commented on how little I travel with: “That’s impressive,” he said. - -I was a little surprised, because though I’ve gotten that comment before, it’s become normal for me to travel with just a small bag (10 lbs. or less, usually), and I have friends who travel with even less. But then I remembered that I’m far from normal in this way. - -I gave him a tip for getting started, and I recommend it for all of you, who want to travel light — or ultralight, as I call it, because for many people traveling light is taking a carry-on roller luggage. For me, having those roller bags is lugging too much, because you can run up stairs with it with ease, or carry it all over a city without worrying about stowing away your luggage somewhere first. It’s so much easier to travel ultralight. - -Here’s the tip I gave him to get started: start by getting a small backpack (less than 20 liters) and then just travel with what fits in that. - -That’s how to start. But you’ll probably want some guidance on what to put into the bag, and how to travel with so little. Here’s some guidance to get started: - -* I travel with a lightweight laptop (Macbook Air), a few clothes, my phone, earbuds and some charging cords, toiletries, and almost nothing else. A lightweight windbreaker for wind and light rain (Patagonia Houdini). An eye mask and ear plugs. A collapsible water bottle. My passport. That’s about it. No extra shoes. No books. No suit. No travel pillow. No extra camera other than my phone. I’m not sure what else everyone else brings, but none of that. -* I bring clothes that I can wash in the sink or shower and that will dry overnight. Lightweight stuff that I can layer. Often they’re workout-style clothes or things from companies like Outlier or Patagonia that travel well. I don’t bring enough underwear or socks for every day of the trip, because I wash them every couple of days. I only bring one or two extra T-shirts, generally wearing the same two shirts the whole trip, even if it’s a month long. No one has ever once cared what I wear when I’m traveling. -* I bring minimal toiletries: a small shaver for my head, razor, toothbrush, floss small tubes of toothpaste and shaving cream, deodorant, nail clippers, ibuprofen. -* For cold places, I have thermal underwear and a couple long-sleeve layers (generally all Patagonia capilene stuff), and a beanie. I don’t usually go to places where it’s snowing (I don’t know why, maybe snow isn’t my thing), so I don’t have clothes to deal with that weather. -* For warm places, I will bring flip flops and swim trunks, and leave most of the colder layers behind. - -That’s enough for a monthlong trip, which I’ve done multiple times with this kind of setup. For a shorter trip of a few days, I might bring even less. - -I really love traveling this way, and am more than willing to sacrifice bringing extra things for the luxury of traveling lightweight. - -By the way, you don’t need much more than this kind of setup even in everyday life. - -For more info on this, check out my Ultralight ebook, and my friend Tynan has a great book called Forever Nomad. - diff --git a/themes/archie/exampleSite/content/posts/post-5.md b/themes/archie/exampleSite/content/posts/post-5.md deleted file mode 100644 index 8623c198..00000000 --- a/themes/archie/exampleSite/content/posts/post-5.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: "Typography" -date: 2018-03-18T12:13:38+05:30 ---- - -Lid est laborum et dolorum fuga. Et harum quidem rerum facilis est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit quo minus id quod amets untra dolor amet sad. Sed ut perspser iciatis unde omnis iste natus error sit voluptatem accusantium doloremque laste. Dolores sadips ipsums sits. - -# Heading 1 - -Lid est laborum et dolorum fuga. Et harum quidem rerum facilis est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit quo minus id quod amets untra dolor amet sad. Sed ut perspser iciatis unde omnis iste natus error sit voluptatem accusantium doloremque laste. Dolores sadips ipsums sits. - -## Heading 2 - -Lid est laborum et dolorum fuga. Et harum quidem rerum facilis est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit quo minus id quod amets untra dolor amet sad. Sed ut perspser iciatis unde omnis iste natus error sit voluptatem accusantium doloremque laste. Dolores sadips ipsums sits. - -### Heading 3 - -Lid est laborum et dolorum fuga. Et harum quidem rerum facilis est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit quo minus id quod amets untra dolor amet sad. Sed ut perspser iciatis unde omnis iste natus error sit voluptatem accusantium doloremque laste. Dolores sadips ipsums sits. - -#### Heading 4 - -Lid est laborum et dolorum fuga. Et harum quidem rerum facilis est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit quo minus id quod amets untra dolor amet sad. Sed ut perspser iciatis unde omnis iste natus error sit voluptatem accusantium doloremque laste. Dolores sadips ipsums sits. - -##### Heading 5 - -Lid est laborum et dolorum fuga. Et harum quidem rerum facilis est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit quo minus id quod amets untra dolor amet sad. Sed ut perspser iciatis unde omnis iste natus error sit voluptatem accusantium doloremque laste. Dolores sadips ipsums sits. - -###### Heading 6 - -Lid est laborum et dolorum fuga. Et harum quidem rerum facilis est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit quo minus id quod amets untra dolor amet sad. Sed ut perspser iciatis unde omnis iste natus error sit voluptatem accusantium doloremque laste. Dolores sadips ipsums sits. - -## Typography - -Lid est laborum et dolorum fuga, This is [an example](http://example.com/ "Title") inline link. Et harum quidem rerum facilis, **This is bold** and *emphasis* cumque nihilse impedit quo minus id quod amets untra dolor amet sad. While this is `code block()` and following is a `pre` tag - - print 'this is pre tag' - -Following is the syntax highlighted code block - -```go -func getCookie(name string, r interface{}) (*http.Cookie, error) { - rd := r.(*http.Request) - cookie, err := rd.Cookie(name) - if err != nil { - return nil, err - } - return cookie, nil -} - -func setCookie(cookie *http.Cookie, w interface{}) error { - // Get write interface registered using `Acquire` method in handlers. - wr := w.(http.ResponseWriter) - http.SetCookie(wr, cookie) - return nil -} -``` - -This is blockquote, Will make it *better now* - -> 'I want to do with you what spring does with the cherry trees.' cited ~Pablo Neruda* - - -> Et harum quidem *rerum facilis* est et expeditasi distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihilse impedit - -Unordered list - -* Red -* Green -* Blue - -Ordered list - -1. Red -2. Green -3. Blue diff --git a/themes/archie/exampleSite/content/posts/post-6.md b/themes/archie/exampleSite/content/posts/post-6.md deleted file mode 100644 index 0a297644..00000000 --- a/themes/archie/exampleSite/content/posts/post-6.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "Hugo shortcodes" -date: 2018-03-18T12:13:36+05:30 -description: Here is a demo of all shortcodes available in Hugo. ---- - -## Images - -{{< figure src="https://images.unsplash.com/photo-1560032779-0a8809186efd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" title="Dave Herring" >}} - -{{< figure src="https://images.unsplash.com/photo-1560032779-0a8809186efd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80" title="Dave Herring" >}} - - -## Github Gist - -{{< gist spf13 7896402 >}} - -## Youtube video - -{{< youtube w7Ft2ymGmfc >}} - -## Tweet - -{{< tweet 877500564405444608 >}} - -## Vimeo - -{{< vimeo id="146022717" >}} - -## Instagram - -{{< instagram BWNjjyYFxVx >}} - -## Callouts - -{{< callout emoji="⚡️" text="I guess this works" >}} \ No newline at end of file diff --git a/themes/archie/exampleSite/content/posts/post-7.md b/themes/archie/exampleSite/content/posts/post-7.md deleted file mode 100644 index 48840401..00000000 --- a/themes/archie/exampleSite/content/posts/post-7.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "How to test dark mode?" -summary: "Here is how you can setup dark mode for Ink and test on various OS like iOS, Android, macOS and Windows 10." -date: 2018-03-18T12:13:38+05:30 -tldr: "Wubba lubba dub dub" ---- - -You can set dark mode as default by setting `params.mode` to `dark` in `config.toml` or set it to `auto` which will detect based on your OS and switch to dark mode. For more details [refer documentation](https://github.com/knadh/hugo-ink#configuration) - -Here is how you can switch based on your OS - -* [iOS](https://www.howtogeek.com/440078/how-to-enable-dark-mode-on-your-iphone-and-ipad/) -* [Android](https://9to5google.com/2018/12/17/android-dark-mode-theme-pie/) -* [macOS](https://support.apple.com/en-in/HT208976) -* [Windows 10](https://www.cnet.com/how-to/turn-on-the-dark-mode-in-windows-10/) diff --git a/themes/archie/exampleSite/content/posts/tg-gh.md b/themes/archie/exampleSite/content/posts/tg-gh.md deleted file mode 100644 index 44001481..00000000 --- a/themes/archie/exampleSite/content/posts/tg-gh.md +++ /dev/null @@ -1,382 +0,0 @@ ---- -title: Telegram Bot for GitHub Actions -date: "2020-04-01" -description: Make a Telegram bot with Node.js and use it with GitHub Actions for sending notifications to you about the repo. -tldr: Making GitHub Actions with Js Code ---- -## Telegram -[Telegram](https://telegram.org/) is a cloud-based mobile and desktop messaging app with a focus on security and speed. It is free to use and extensively hackable. It also has a good bot support system. The API is also easy to implement and has many wrappers for building bots with the API. - -## GitHub Actions -[GitHub Actions](https://github.com/features/actions) is a CI/CD runtime for your GitHub repository. You can run almost anything from scripts to docker containers. You can build, test and deploy your code with GitHub Actions. All these actions are called workflows and workflows differ in the job they're doing. These maybe test workflows, build ones or deployment ones. You can find all the actions on GitHub in the [marketplace](https://github.com/marketplace?type=actions) - -## Building the Bot -### Prerequisites -- Basic JavaScript Knowledge -- Basic GitHub Knowledge -- Telegram Account - -> There are templates for building actions. Here we're gonna start from scratch - -### Environment Setup -- **Node**, You can download node from their [website](https://nodejs.org/en/download/) -- NPM comes with node, so you don't have to worry about it. -- Initialize the Project -```shell -$ git init ## initialize a new git repository for version management ---- -$ npm init -``` -- **dotenv**, Dotenv can be downloaded via -```shell -$ npm i dotenv ---- -$ yarn add dotenv -``` -- **node-telegram-bot-api**, node-telegram-bot-api is a simple wrapper for building telegram bots. You can download it via -```shell -$ npm i node-telegram-bot-api ---- -$ yarn add node-telegram-bot-api -``` -- **@zeit/ncc**, NCC is a Simple CLI for compiling a Node.js module into a single file, together with all its dependencies, GCC-style. It's a dev dependency and can be downloaded -```shell -yarn add --dev @zeit/ncc ---- -npm i -D @zeit/ncc -``` - - -#### Folder Structure -The `dist` folder will be automatically created. `action.yml` will be made - -``` -. -├── dist -│ └── index.js -├── index.js -├── action.yml -├── README.md -└── package.json - -``` -- `index.js` is the file we're defining the bot -- `action.yml` is the file we'll define the action and it's behaviours - -## Making the Bot -We need to get an API bot token from telegram. For that Go to Telegram and Search for `Botfather`. It's a bot. -![](bfather.png) -Create a new bot with the `/newbot` command and get the API key. We'll need that, also talk to `jsondump` bot and get your chat id. The output may be like this, so -```json -{ - "update_id": 143943779, - "message": { - "message_id": 181575, - "from": { - "id": 123456 // this is what we need - "is_bot": false, - "first_name": "Tg Name", - "username": "TG Username", - "language_code": "en" - }, - "chat": { - "id": 123456, - "first_name": "Tg Name", - "username": "TG Username", - "type": "private" - }, - "date": 1584119424, - "text": "message" - } -} -``` -This will be needed for further use and We need to add it to the repo secrets which can be found in the repo settings. Be careful to add it as `token` and `chat` like as shown below -![](scr.png) - -### Writing the Action and Building the Bot -Fire up the terminal/cmd and make a new folder. Install the dependencies. Run the following command -```shell -$ touch index.js action.yml -``` -Open your favourite text editor within the folder or with the file. We'll define the bot in `index.js` - -```javaScript -require("dotenv").config -const Bot = require('node-telegram-bot-api'); -const { - INPUT_STATUS: ipstatus, - INPUT_TOKEN: tgtoken,//Telegram api token - INPUT_CHAT: chatid,// Telegram Chat ID - INPUT_IU_TITLE: ititle,// Issue title - INPUT_IU_NUM: inum,// Issue Number - INPUT_IU_ACTOR: iactor,// Issue made by - INPUT_IU_BODY: ibody,// Issue Body - INPUT_PR_NUM: pnum,// PR Number - INPUT_PR_STATE: prstate,// PR Opened, reponed or closed - INPUT_PR_TITLE: ptitle,// PR Title - INPUT_PR_BODY: pbody,// Body of the PR - GITHUB_EVENT_NAME: ghevent,// Name of the trigger event - GITHUB_REPOSITORY: repo,// Repository the trigger was made from - GITHUB_ACTOR: ghactor,// User who triggered the action - GITHUB_SHA: sha,// Commit ID - GITHUB_WORKFLOW: ghwrkflw// Workflow Name -} = process.env; - -const bot = new Bot(tgtoken) -``` -First, we're defining the dotenv for config and initializing Telegram Bot. Here we're defining the alias variables for the *environment variables*. You might notice an `INPUT_` for almost every environment variable, this is because GitHub Actions pass the env variable with an INPUT prefix. Other env variables are action's default environment variables. Then we initialized the bot with the API token. - -GitHub actions could be triggered with Issues, Pull Request or Pushes. You can find the trigger events [here](https://help.github.com/en/actions/reference/events-that-trigger-workflows). Here we're gonna get a message from the bot when an *Issue* or *Pull Request* or a *Push* event has happened. - -```js -const evresp = (gevent) => { - switch (gevent) { - - case "issues": - return ` -❗️❗️❗️❗️❗️❗️ - -Issue ${prstate} - -Issue Title and Number : ${ititle} | #${inum} - -Commented or Created By : \`${iactor}\` - -Issue Body : *${ibody}* - -[Link to Issue](https://github.com/${repo}/issues/${inum}) -[Link to Repo ](https://github.com/${repo}/) -[Build log here](https://github.com/${repo}/commit/${sha}/checks)` - case "pull_request": - return ` -🔃🔀🔃🔀🔃🔀 -PR ${prstate} - -PR Number: ${pnum} - -PR Title: ${ptitle} - -PR Body: *${pbody}* - -PR By: ${ghactor} - -[Link to Issue](https://github.com/${repo}/pull/${pnum}) -[Link to Repo ](https://github.com/${repo}/) -[Build log here](https://github.com/${repo}/commit/${sha}/checks)` - default: - return ` -⬆️⇅⬆️⇅ - -ID: ${ghwrkflw} - -Action was a *${ipstatus}!* - -\`Repository: ${repo}\` - -On: *${ghevent}* - -By: *${ghactor}* - -Tag: ${process.env.GITHUB_REF} - -[Link to Repo ](https://github.com/${repo}/) - ` - } -} -``` -In these lines of code, we're just initializing a switch statement for the responses. We're also declaring an anonymous function to use the switch responses via a function later. We're using all the defined variables in the switch. You can check the [trigger Events](https://help.github.com/en/actions/reference/events-that-trigger-workflows) to get how the event is triggered and what keyword should be used. - -Now for the last part of the Js file, we just take the response from the switch and assign it to a constant. Then we use the `sendMessage` function of the `node-telegram-bot-api` to send the message to the bot with the chatid and the output as the arguments. -```js -const output = evresp(ghevent) -``` -bot.sendMessage(chatid,output,{parse_mode : "Markdown"}) -## Compiling and Minifying the Js code -Since we have installed `@zeit/ncc` and this is used for the making the whole program with all the APIs to a single file and we need to use NCC for that. We just need to run -```shell -yarn run ncc build index.js -C -m -o dist -``` -or you might wanna add the following to you `package.json` file, and run `npm run test` to compile and minify the code. -```json -"scripts": { - "test": "ncc build index.js -C -m -o dist" - }, -``` -This will create a `dist` folder with and `index.js` file which contains the compiled code. - -## Making it a valid action -For making this Js file a valid action, we need to add an `action.yml` file. The action.yml for this action is like this -```yml -name: 'Action Name' -description: 'Action Descreption' -author: '' -inputs: - chat: - description: 'Chat to send: chat id or @channel_name' - required: true - token: - description: 'Telegram Bot token' - required: true - status: - description: 'Job status' - required: true - iu_title: - description: 'Issue Title' - default: ${{ github.event.issue.title }} - iu_num: - description: 'Issue Number' - default: ${{ github.event.issue.number }} - iu_actor: - description: 'Issue Triggerer' - default: ${{ github.event.issue.user.login }} - iu_com: - description: 'Issue Comment' - default: ${{github.event.comment.body}} - pr_state: - description: 'State of the PR' - default: ${{ github.event.action }} - pr_num: - description: 'PR Number' - default: ${{ github.event.number }} - pr_title: - description: 'Title of the PR' - default: ${{ github.event.pull_request.title }} - pr_body: - description: 'Body/Contents of the PR' - default: ${{ github.event.pull_request.body }} -runs: - using: "node12" - main: "dist/index.js" -branding: - icon: 'repeat' - color: 'green' -``` -Here we're defining the Input variables to be loaded for the action in GitHub's runtime environemt. All these `default` data are taken from the response of the webhooks which are send by GitHub when a trigger event is occured. You can find out more in the [Action Documentation Here](https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context). - -```yml -runs: - using: "node12" - main: "dist/index.js" -``` -Here we are defining that this is a node action and should run in an environment with node, and the file which should be run, here the `index.js` file in the `dist` folder. That should do it. Create a new commit and push it to a repo. **Create a new tag** and this action will appear in the [marketplace](https://github.com/marketplace?type=actions). - -### Defining a workflow to test your action -GitHub Action workflows are defined using the `.yml` syntax. Here is an example of a sample workflow for this action - -```yml -name: - -on: - push: - pull_request: - types: [opened, closed] - issues: - types: [opened, closed, reopened] -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: - uses: /@master - if: always() - with: - chat: ${{ secrets.chat }} - token: ${{ secrets.token }} - status: ${{ job.status }} -``` - - -The Complete code for the bot is -```js -//Initializing dotenv and the bot -require("dotenv").config -const Bot = require('node-telegram-bot-api'); -// aliasing the environment variables -const { - INPUT_STATUS: ipstatus, - INPUT_TOKEN: tgtoken, //Telegram api token - INPUT_CHAT: chatid,// Telegram Chat ID - INPUT_IU_TITLE: ititle,// Issue title - INPUT_IU_NUM: inum,// Issue Number - INPUT_IU_ACTOR: iactor, // Issue made by - INPUT_IU_BODY: ibody, // Issue Body - INPUT_PR_NUM: pnum, // PR Number - INPUT_PR_STATE: prstate, // PR Opened, reponed or closed - INPUT_PR_TITLE: ptitle, // PR Title - INPUT_PR_BODY: pbody, // Body of the PR - GITHUB_EVENT_NAME: ghevent, // Name of the trigger event - GITHUB_REPOSITORY: repo, // Repository the trigger was made from - GITHUB_ACTOR: ghactor, // User who triggered the action - GITHUB_SHA: sha, // Commit ID - GITHUB_WORKFLOW: ghwrkflw // Workflow Name -} = process.env; - -const bot = new Bot(tgtoken) -// Function to return the response for the specific trigger -const evresp = (gevent) => { - switch (gevent) { -//Switch statement for issues - case "issues": - return ` -❗️❗️❗️❗️❗️❗️ - -Issue ${prstate} - -Issue Title and Number : ${ititle} | #${inum} - -Commented or Created By : \`${iactor}\` - -Issue Body : *${ibody}* - -[Link to Issue](https://github.com/${repo}/issues/${inum}) -[Link to Repo ](https://github.com/${repo}/) -[Build log here](https://github.com/${repo}/commit/${sha}/checks)` -// Switch statement for Pull Requests - case "pull_request": - return ` -🔃🔀🔃🔀🔃🔀 -PR ${prstate} - -PR Number: ${pnum} - -PR Title: ${ptitle} - -PR Body: *${pbody}* - -PR By: ${ghactor} - -[Link to Issue](https://github.com/${repo}/pull/${pnum}) -[Link to Repo ](https://github.com/${repo}/) -[Build log here](https://github.com/${repo}/commit/${sha}/checks)` - default: -// switch statement for Pushes - return ` -⬆️⇅⬆️⇅ - -ID: ${ghwrkflw} - -Action was a *${ipstatus}!* - -\`Repository: ${repo}\` - -On: *${ghevent}* - -By: *${ghactor}* - -Tag: ${process.env.GITHUB_REF} - -[Link to Repo ](https://github.com/${repo}/) - ` - } -} -// assigning the output to a variable -const output = evresp(ghevent) -// sending the message -bot.sendMessage(chatid,output,{parse_mode : "Markdown"}) -``` - - ------- - -You can try out many different items using actions and this is just a sample action to get you started. Maybe sending Cat GIFs if the build succeded on the pull request or sending a welcome message to a first time contributor. You imagination is the limit😄 and **Never Stop being ⚡️** \ No newline at end of file diff --git a/themes/archie/images/archie-dark.png b/themes/archie/images/archie-dark.png deleted file mode 100644 index 2bff9edf..00000000 Binary files a/themes/archie/images/archie-dark.png and /dev/null differ diff --git a/themes/archie/images/screenshot.png b/themes/archie/images/screenshot.png deleted file mode 100644 index 1a262e75..00000000 Binary files a/themes/archie/images/screenshot.png and /dev/null differ diff --git a/themes/archie/images/theme.png b/themes/archie/images/theme.png deleted file mode 100644 index c195540d..00000000 Binary files a/themes/archie/images/theme.png and /dev/null differ diff --git a/themes/archie/images/tn.png b/themes/archie/images/tn.png deleted file mode 100644 index 628ac6cb..00000000 Binary files a/themes/archie/images/tn.png and /dev/null differ diff --git a/themes/archie/layouts/404.html b/themes/archie/layouts/404.html deleted file mode 100644 index 1866d9f7..00000000 --- a/themes/archie/layouts/404.html +++ /dev/null @@ -1,16 +0,0 @@ - - - {{ partial "header.html" . }} - -
- {{ partial "head.html" . }} - -
-
- 404 - Page Not Found -
- - {{ partial "footer.html" . }} -
- - diff --git a/themes/archie/layouts/_default/baseof.html b/themes/archie/layouts/_default/baseof.html deleted file mode 100644 index 8a980bee..00000000 --- a/themes/archie/layouts/_default/baseof.html +++ /dev/null @@ -1,12 +0,0 @@ - - - {{- partial "header.html" . -}} - -
- {{- partial "head.html" . -}} - {{- block "main" . }}{{- end }} - {{ partial "comments.html" . }} - {{- partial "footer.html" . -}} -
- - diff --git a/themes/archie/layouts/_default/list.html b/themes/archie/layouts/_default/list.html deleted file mode 100644 index 41a4c6fa..00000000 --- a/themes/archie/layouts/_default/list.html +++ /dev/null @@ -1,17 +0,0 @@ -{{ define "main" }} -{{ if isset .Data "Term" }} -

Entries tagged - "{{ .Data.Term }}"

-{{ else }} -

All articles

-{{ end }} - -
    - {{- range .Data.Pages -}} - {{- if (not (in (.Site.Params.excludedTypes | default (slice "page")) .Type)) -}} -
  • - {{.Title}} {{ dateFormat "Jan 2, 2006" .Date }}{{ if .Draft }} DRAFT {{ end }} -
  • - {{- end -}} - {{- end -}} -
-{{ end }} diff --git a/themes/archie/layouts/_default/single.html b/themes/archie/layouts/_default/single.html deleted file mode 100644 index 2d2e12e7..00000000 --- a/themes/archie/layouts/_default/single.html +++ /dev/null @@ -1,47 +0,0 @@ -{{ define "main" }} -
-
-
-

{{ .Title }}

- {{ if not .Params.hide_date }} -
Posted on {{ dateFormat "Jan 2, 2006" .Date }}{{ if .Draft }} DRAFT {{ end }}
- {{ end }} -
- {{ if isset .Params "tldr" }} -
- tl;dr: - {{ .Params.tldr }} -
{{ end }} - -
- {{- with .Content -}} - {{ . | replaceRE "()" `${1}#${3}`| safeHTML }} - {{- end -}} -
- - - - - - -
-
-{{ end }} diff --git a/themes/archie/layouts/_default/term.html b/themes/archie/layouts/_default/term.html deleted file mode 100644 index 41a4c6fa..00000000 --- a/themes/archie/layouts/_default/term.html +++ /dev/null @@ -1,17 +0,0 @@ -{{ define "main" }} -{{ if isset .Data "Term" }} -

Entries tagged - "{{ .Data.Term }}"

-{{ else }} -

All articles

-{{ end }} - -
    - {{- range .Data.Pages -}} - {{- if (not (in (.Site.Params.excludedTypes | default (slice "page")) .Type)) -}} -
  • - {{.Title}} {{ dateFormat "Jan 2, 2006" .Date }}{{ if .Draft }} DRAFT {{ end }} -
  • - {{- end -}} - {{- end -}} -
-{{ end }} diff --git a/themes/archie/layouts/_default/terms.html b/themes/archie/layouts/_default/terms.html deleted file mode 100644 index fea9c2f7..00000000 --- a/themes/archie/layouts/_default/terms.html +++ /dev/null @@ -1,20 +0,0 @@ -{{ define "main" }} -

All tags

- -{{ $biggest := 1 }} -{{ $smallest := 1 }} -{{ $max := 3 }} -{{ $min := 1 }} -{{ $size := $min }} - -{{ $data := .Data }} -
-
    - {{ range $key, $value := .Data.Terms.ByCount }} - {{ $size := (add (mul (div $value.Count $biggest) (sub $max $min)) $min) }} - {{ $size := (cond (eq $biggest $smallest) $min $size) }} -
  • {{ $value.Name }}
  • - {{ end }} -
-
-{{ end }} diff --git a/themes/archie/layouts/index.html b/themes/archie/layouts/index.html deleted file mode 100644 index 84fd0a8f..00000000 --- a/themes/archie/layouts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - {{ partial "header.html" . }} - -
- {{ partial "head.html" . }} - -
-
- {{- if isset .Site.Params "subtitle" -}} -

{{ .Site.Params.Subtitle | markdownify }}

- {{- end -}} -
- {{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }} - {{ $paginator := .Paginate (where $pages "Params.hidden" "ne" true) }} - {{ range $paginator.Pages }} -
-

{{.Title}}

- -
{{ template "partials/pagedescription.html" . }} -
- {{ end }} - {{ template "partials/paginator.html" . }} -
- {{ partial "footer.html" . }} -
- - - diff --git a/themes/archie/layouts/partials/footer.html b/themes/archie/layouts/partials/footer.html deleted file mode 100644 index e45d988c..00000000 --- a/themes/archie/layouts/partials/footer.html +++ /dev/null @@ -1,23 +0,0 @@ -
- -
- {{- range $index, $key := .Site.Params.Social -}} - - - {{- end -}} -
- - {{ if (findRE " - {{ end }} -
-{{ if not .Site.IsServer }} {{ template "_internal/google_analytics.html" . }} -{{ end }} {{- if (isset .Site.Params "social") -}} - -{{- end -}} diff --git a/themes/archie/layouts/partials/head.html b/themes/archie/layouts/partials/head.html deleted file mode 100644 index b070feed..00000000 --- a/themes/archie/layouts/partials/head.html +++ /dev/null @@ -1,23 +0,0 @@ -
- - - - - - {{ end }} - {{ if (findRE " -{{ end }} - -
diff --git a/themes/archie/layouts/partials/header.html b/themes/archie/layouts/partials/header.html deleted file mode 100644 index 7d990d04..00000000 --- a/themes/archie/layouts/partials/header.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - {{- $title := ( .Title ) -}} - {{- $siteTitle := ( .Site.Title ) -}} - {{- if .IsHome -}} - {{ $siteTitle }} | Home - {{- else -}} - {{ $title }} - {{ $siteTitle }} - {{- end -}} - - {{- if isset .Site.Params "favicon" -}} - - {{- end -}} - - - - - {{ with .OutputFormats.Get "rss" -}} - {{ printf `` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }} - {{ end -}} - - {{- template "_internal/opengraph.html" . -}} - {{- template "_internal/twitter_cards.html" . -}} - {{ if and (isset .Site.Params "social") (.Site.Params.useCDN | default false) -}} - - {{- else if or (isset .Site.Params "social") (eq .Site.Params.mode "toggle") -}} - - {{ end }} - {{ if .Site.Params.useCDN | default false -}} - - - - {{- else -}} - {{ $fontstyle := resources.Get "css/fonts.css" | fingerprint }} - - {{ end }} - - {{ $style := resources.Get "css/main.css" | fingerprint }} - - - {{- if or (eq .Site.Params.mode "auto") (eq .Site.Params.mode "dark") (eq .Site.Params.mode "toggle") -}} - {{ $darkstyle := resources.Get "css/dark.css" | fingerprint }} - - {{ end }} - - - {{ with .Site.Params.mathjax }} - - - - - {{ end }} - - - {{ with .Site.Params.katex }} - - - - - - - {{ end }} - - - {{- if isset .Site.Params "customcss" }} - {{ range .Site.Params.customCSS }} - {{ $customstyle := resources.Get . | fingerprint }} - - {{ end }} - {{- end -}} - {{- range .Site.Params.customJS }} - {{- if or (hasPrefix . "http://") (hasPrefix . "https://") }} - - {{- else if (hasPrefix . " - {{- end }} - {{- end }} - diff --git a/themes/archie/layouts/partials/pagedescription.html b/themes/archie/layouts/partials/pagedescription.html deleted file mode 100644 index d69bb9ab..00000000 --- a/themes/archie/layouts/partials/pagedescription.html +++ /dev/null @@ -1,7 +0,0 @@ -
- {{ if isset .Params "description" }} - {{ .Description }} - {{ else }} - {{ .Summary }}… - {{ end }} -
\ No newline at end of file diff --git a/themes/archie/layouts/partials/paginator.html b/themes/archie/layouts/partials/paginator.html deleted file mode 100644 index 5acc06d2..00000000 --- a/themes/archie/layouts/partials/paginator.html +++ /dev/null @@ -1,15 +0,0 @@ -{{ $pag := $.Paginator }} -{{ if gt $pag.TotalPages 1 }} -
    - - {{ if $pag.HasPrev }} - - {{ end }} - - - {{ if $pag.HasNext }} - - {{ end }} - -
-{{ end }} diff --git a/themes/archie/layouts/shortcodes/callout.html b/themes/archie/layouts/shortcodes/callout.html deleted file mode 100644 index 5557aad6..00000000 --- a/themes/archie/layouts/shortcodes/callout.html +++ /dev/null @@ -1,6 +0,0 @@ - -
-
- 💡 {{ .Get "text" }} -
-
\ No newline at end of file diff --git a/themes/archie/static/fonts/fira-sans-v10-latin-regular.eot b/themes/archie/static/fonts/fira-sans-v10-latin-regular.eot deleted file mode 100644 index 7abf4c2f..00000000 Binary files a/themes/archie/static/fonts/fira-sans-v10-latin-regular.eot and /dev/null differ diff --git a/themes/archie/static/fonts/fira-sans-v10-latin-regular.svg b/themes/archie/static/fonts/fira-sans-v10-latin-regular.svg deleted file mode 100644 index 1e520978..00000000 --- a/themes/archie/static/fonts/fira-sans-v10-latin-regular.svg +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/themes/archie/static/fonts/fira-sans-v10-latin-regular.ttf b/themes/archie/static/fonts/fira-sans-v10-latin-regular.ttf deleted file mode 100644 index 572e442e..00000000 Binary files a/themes/archie/static/fonts/fira-sans-v10-latin-regular.ttf and /dev/null differ diff --git a/themes/archie/static/fonts/fira-sans-v10-latin-regular.woff b/themes/archie/static/fonts/fira-sans-v10-latin-regular.woff deleted file mode 100644 index d99ba57a..00000000 Binary files a/themes/archie/static/fonts/fira-sans-v10-latin-regular.woff and /dev/null differ diff --git a/themes/archie/static/fonts/fira-sans-v10-latin-regular.woff2 b/themes/archie/static/fonts/fira-sans-v10-latin-regular.woff2 deleted file mode 100644 index 9bb57603..00000000 Binary files a/themes/archie/static/fonts/fira-sans-v10-latin-regular.woff2 and /dev/null differ diff --git a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.eot b/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.eot deleted file mode 100644 index 62b89b32..00000000 Binary files a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.eot and /dev/null differ diff --git a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.svg b/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.svg deleted file mode 100644 index 6423805a..00000000 --- a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.svg +++ /dev/null @@ -1,365 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.ttf b/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.ttf deleted file mode 100644 index e4d1ddf0..00000000 Binary files a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.ttf and /dev/null differ diff --git a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.woff b/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.woff deleted file mode 100644 index 4504b413..00000000 Binary files a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.woff and /dev/null differ diff --git a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.woff2 b/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.woff2 deleted file mode 100644 index 489745d1..00000000 Binary files a/themes/archie/static/fonts/ibm-plex-mono-v6-latin-500italic.woff2 and /dev/null differ diff --git a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.eot b/themes/archie/static/fonts/roboto-mono-v12-latin-regular.eot deleted file mode 100644 index 8c56483c..00000000 Binary files a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.eot and /dev/null differ diff --git a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.svg b/themes/archie/static/fonts/roboto-mono-v12-latin-regular.svg deleted file mode 100644 index 18643286..00000000 --- a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.svg +++ /dev/null @@ -1,405 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.ttf b/themes/archie/static/fonts/roboto-mono-v12-latin-regular.ttf deleted file mode 100644 index d5dee83e..00000000 Binary files a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.ttf and /dev/null differ diff --git a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.woff b/themes/archie/static/fonts/roboto-mono-v12-latin-regular.woff deleted file mode 100644 index f319fbfa..00000000 Binary files a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.woff and /dev/null differ diff --git a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.woff2 b/themes/archie/static/fonts/roboto-mono-v12-latin-regular.woff2 deleted file mode 100644 index ed384d22..00000000 Binary files a/themes/archie/static/fonts/roboto-mono-v12-latin-regular.woff2 and /dev/null differ diff --git a/themes/archie/static/js/copy-code-button.js b/themes/archie/static/js/copy-code-button.js deleted file mode 100644 index 8ba74296..00000000 --- a/themes/archie/static/js/copy-code-button.js +++ /dev/null @@ -1,59 +0,0 @@ -function createCopyButton(highlightDiv) { - const button = document.createElement("button"); - button.className = "copy-code-button"; - button.type = "button"; - button.innerText = "Copy"; - button.addEventListener("click", () => - copyCodeToClipboard(button, highlightDiv) - ); - highlightDiv.insertBefore(button, highlightDiv.firstChild); - - const wrapper = document.createElement("div"); - wrapper.className = "highlight-wrapper"; - highlightDiv.parentNode.insertBefore(wrapper, highlightDiv); - wrapper.appendChild(highlightDiv); -} - -document - .querySelectorAll(".highlight") - .forEach((highlightDiv) => createCopyButton(highlightDiv)); - -async function copyCodeToClipboard(button, highlightDiv) { - const codeToCopy = highlightDiv - .querySelector("pre > code ") - .innerText.replace(/\n\n/g, "\n") // Fix the double spacing - .replace(/\n$/, ""); // Clean up last empty line - try { - var result = await navigator.permissions.query({ name: "clipboard-write" }); - if (result.state == "granted" || result.state == "prompt") { - await navigator.clipboard.writeText(codeToCopy); - } else { - copyCodeBlockExecCommand(codeToCopy, highlightDiv); - } - } catch (_) { - copyCodeBlockExecCommand(codeToCopy, highlightDiv); - } finally { - button.blur(); - button.innerText = "Copied!"; - setTimeout(function () { - button.innerText = "Copy"; - }, 2000); - } -} - -function copyCodeBlockExecCommand(codeToCopy, highlightDiv) { - const textArea = document.createElement("textArea"); - textArea.contentEditable = "true"; - textArea.readOnly = "false"; - textArea.className = "copyable-text-area"; - textArea.value = codeToCopy; - highlightDiv.insertBefore(textArea, highlightDiv.firstChild); - const range = document.createRange(); - range.selectNodeContents(textArea); - const sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - textArea.setSelectionRange(0, 999999); - document.execCommand("copy"); - highlightDiv.removeChild(textArea); -} diff --git a/themes/archie/static/js/feather.min.js b/themes/archie/static/js/feather.min.js deleted file mode 100644 index d229492e..00000000 --- a/themes/archie/static/js/feather.min.js +++ /dev/null @@ -1,13 +0,0 @@ -!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.feather=n():e.feather=n()}("undefined"!=typeof self?self:this,function(){return function(e){var n={};function i(l){if(n[l])return n[l].exports;var t=n[l]={i:l,l:!1,exports:{}};return e[l].call(t.exports,t,t.exports,i),t.l=!0,t.exports}return i.m=e,i.c=n,i.d=function(e,n,l){i.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:l})},i.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},i.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(n,"a",n),n},i.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},i.p="",i(i.s=61)}([function(e,n,i){var l=i(20)("wks"),t=i(11),r=i(1).Symbol,o="function"==typeof r;(e.exports=function(e){return l[e]||(l[e]=o&&r[e]||(o?r:t)("Symbol."+e))}).store=l},function(e,n){var i=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=i)},function(e,n){var i=e.exports={version:"2.5.6"};"number"==typeof __e&&(__e=i)},function(e,n){var i={}.hasOwnProperty;e.exports=function(e,n){return i.call(e,n)}},function(e,n,i){e.exports=!i(27)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,n,i){var l=i(13);e.exports=function(e){if(!l(e))throw TypeError(e+" is not an object!");return e}},function(e,n,i){var l=i(5),t=i(56),r=i(55),o=Object.defineProperty;n.f=i(4)?Object.defineProperty:function(e,n,i){if(l(e),n=r(n,!0),l(i),t)try{return o(e,n,i)}catch(e){}if("get"in i||"set"in i)throw TypeError("Accessors not supported!");return"value"in i&&(e[n]=i.value),e}},function(e,n,i){var l=i(6),t=i(12);e.exports=i(4)?function(e,n,i){return l.f(e,n,t(1,i))}:function(e,n,i){return e[n]=i,e}},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l=o(i(35)),t=o(i(33)),r=o(i(32));function o(e){return e&&e.__esModule?e:{default:e}}n.default=Object.keys(t.default).map(function(e){return new l.default(e,t.default[e],r.default[e])}).reduce(function(e,n){return e[n.name]=n,e},{})},function(e,n,i){var l=i(20)("keys"),t=i(11);e.exports=function(e){return l[e]||(l[e]=t(e))}},function(e,n){e.exports={}},function(e,n){var i=0,l=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++i+l).toString(36))}},function(e,n){e.exports=function(e,n){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:n}}},function(e,n){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,n){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,n){var i=Math.ceil,l=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?l:i)(e)}},function(e,n,i){var l; -/*! - Copyright (c) 2016 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames -*/ -/*! - Copyright (c) 2016 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames -*/ -!function(){"use strict";var i=function(){function e(){}function n(e,n){for(var i=n.length,l=0;l0?t(l(e),9007199254740991):0}},function(e,n){var i={}.toString;e.exports=function(e){return i.call(e).slice(8,-1)}},function(e,n,i){var l=i(48),t=i(14);e.exports=function(e){return l(t(e))}},function(e,n,i){var l=i(54);e.exports=function(e,n,i){if(l(e),void 0===n)return e;switch(i){case 1:return function(i){return e.call(n,i)};case 2:return function(i,l){return e.call(n,i,l)};case 3:return function(i,l,t){return e.call(n,i,l,t)}}return function(){return e.apply(n,arguments)}}},function(e,n,i){var l=i(1),t=i(7),r=i(3),o=i(11)("src"),a=Function.toString,c=(""+a).split("toString");i(2).inspectSource=function(e){return a.call(e)},(e.exports=function(e,n,i,a){var y="function"==typeof i;y&&(r(i,"name")||t(i,"name",n)),e[n]!==i&&(y&&(r(i,o)||t(i,o,e[n]?""+e[n]:c.join(String(n)))),e===l?e[n]=i:a?e[n]?e[n]=i:t(e,n,i):(delete e[n],t(e,n,i)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[o]||a.call(this)})},function(e,n,i){var l=i(13),t=i(1).document,r=l(t)&&l(t.createElement);e.exports=function(e){return r?t.createElement(e):{}}},function(e,n){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,n,i){var l=i(1),t=i(2),r=i(7),o=i(25),a=i(24),c=function(e,n,i){var y,p,h,x,s=e&c.F,u=e&c.G,d=e&c.S,f=e&c.P,v=e&c.B,g=u?l:d?l[n]||(l[n]={}):(l[n]||{}).prototype,m=u?t:t[n]||(t[n]={}),M=m.prototype||(m.prototype={});for(y in u&&(i=n),i)h=((p=!s&&g&&void 0!==g[y])?g:i)[y],x=v&&p?a(h,l):f&&"function"==typeof h?a(Function.call,h):h,g&&o(g,y,h,e&c.U),m[y]!=h&&r(m,y,x),f&&M[y]!=h&&(M[y]=h)};l.core=t,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,n){e.exports=!1},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l=Object.assign||function(e){for(var n=1;n0&&void 0!==arguments[0]?arguments[0]:{};if("undefined"==typeof document)throw new Error("`feather.replace()` only works in a browser environment.");var n=document.querySelectorAll("[data-feather]");Array.from(n).forEach(function(n){return function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=function(e){return Array.from(e.attributes).reduce(function(e,n){return e[n.name]=n.value,e},{})}(e),o=i["data-feather"];delete i["data-feather"];var a=r.default[o].toSvg(l({},n,i,{class:(0,t.default)(n.class,i.class)})),c=(new DOMParser).parseFromString(a,"image/svg+xml").querySelector("svg");e.parentNode.replaceChild(c,e)}(n,e)})}},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l,t=i(8),r=(l=t)&&l.__esModule?l:{default:l};n.default=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(console.warn("feather.toSvg() is deprecated. Please use feather.icons[name].toSvg() instead."),!e)throw new Error("The required `key` (icon name) parameter is missing.");if(!r.default[e])throw new Error("No icon matching '"+e+"'. See the complete list of icons at https://feathericons.com");return r.default[e].toSvg(n)}},function(e){e.exports={activity:["pulse","health","action","motion"],airplay:["stream","cast","mirroring"],"alert-circle":["warning"],"alert-octagon":["warning"],"alert-triangle":["warning"],"at-sign":["mention"],award:["achievement","badge"],aperture:["camera","photo"],bell:["alarm","notification"],"bell-off":["alarm","notification","silent"],bluetooth:["wireless"],"book-open":["read"],book:["read","dictionary","booklet","magazine"],bookmark:["read","clip","marker","tag"],briefcase:["work","bag","baggage","folder"],clipboard:["copy"],clock:["time","watch","alarm"],"cloud-drizzle":["weather","shower"],"cloud-lightning":["weather","bolt"],"cloud-rain":["weather"],"cloud-snow":["weather","blizzard"],cloud:["weather"],codepen:["logo"],codesandbox:["logo"],coffee:["drink","cup","mug","tea","cafe","hot","beverage"],command:["keyboard","cmd"],compass:["navigation","safari","travel"],copy:["clone","duplicate"],"corner-down-left":["arrow"],"corner-down-right":["arrow"],"corner-left-down":["arrow"],"corner-left-up":["arrow"],"corner-right-down":["arrow"],"corner-right-up":["arrow"],"corner-up-left":["arrow"],"corner-up-right":["arrow"],"credit-card":["purchase","payment","cc"],crop:["photo","image"],crosshair:["aim","target"],database:["storage"],delete:["remove"],disc:["album","cd","dvd","music"],"dollar-sign":["currency","money","payment"],droplet:["water"],edit:["pencil","change"],"edit-2":["pencil","change"],"edit-3":["pencil","change"],eye:["view","watch"],"eye-off":["view","watch"],"external-link":["outbound"],facebook:["logo"],"fast-forward":["music"],figma:["logo","design","tool"],film:["movie","video"],"folder-minus":["directory"],"folder-plus":["directory"],folder:["directory"],frown:["emoji","face","bad","sad","emotion"],gift:["present","box","birthday","party"],"git-branch":["code","version control"],"git-commit":["code","version control"],"git-merge":["code","version control"],"git-pull-request":["code","version control"],github:["logo","version control"],gitlab:["logo","version control"],global:["world","browser","language","translate"],"hard-drive":["computer","server"],hash:["hashtag","number","pound"],headphones:["music","audio"],heart:["like","love"],"help-circle":["question mark"],hexagon:["shape","node.js","logo"],home:["house"],image:["picture"],inbox:["email"],instagram:["logo","camera"],key:["password","login","authentication"],"life-bouy":["help","life ring","support"],linkedin:["logo"],lock:["security","password"],"log-in":["sign in","arrow"],"log-out":["sign out","arrow"],mail:["email"],"map-pin":["location","navigation","travel","marker"],map:["location","navigation","travel"],maximize:["fullscreen"],"maximize-2":["fullscreen","arrows"],meh:["emoji","face","neutral","emotion"],menu:["bars","navigation","hamburger"],"message-circle":["comment","chat"],"message-square":["comment","chat"],"mic-off":["record"],mic:["record"],minimize:["exit fullscreen"],"minimize-2":["exit fullscreen","arrows"],monitor:["tv"],moon:["dark","night"],"more-horizontal":["ellipsis"],"more-vertical":["ellipsis"],"mouse-pointer":["arrow","cursor"],move:["arrows"],navigation:["location","travel"],"navigation-2":["location","travel"],octagon:["stop"],package:["box"],paperclip:["attachment"],pause:["music","stop"],"pause-circle":["music","stop"],"pen-tool":["vector","drawing"],play:["music","start"],"play-circle":["music","start"],plus:["add","new"],"plus-circle":["add","new"],"plus-square":["add","new"],pocket:["logo","save"],power:["on","off"],radio:["signal"],rewind:["music"],rss:["feed","subscribe"],save:["floppy disk"],search:["find","magnifier","magnifying glass"],send:["message","mail","paper airplane"],settings:["cog","edit","gear","preferences"],shield:["security"],"shield-off":["security"],"shopping-bag":["ecommerce","cart","purchase","store"],"shopping-cart":["ecommerce","cart","purchase","store"],shuffle:["music"],"skip-back":["music"],"skip-forward":["music"],slash:["ban","no"],sliders:["settings","controls"],smile:["emoji","face","happy","good","emotion"],speaker:["music"],star:["bookmark","favorite","like"],sun:["brightness","weather","light"],sunrise:["weather"],sunset:["weather"],tag:["label"],target:["bullseye"],terminal:["code","command line"],"thumbs-down":["dislike","bad"],"thumbs-up":["like","good"],"toggle-left":["on","off","switch"],"toggle-right":["on","off","switch"],trash:["garbage","delete","remove"],"trash-2":["garbage","delete","remove"],triangle:["delta"],truck:["delivery","van","shipping"],twitter:["logo"],umbrella:["rain","weather"],"video-off":["camera","movie","film"],video:["camera","movie","film"],voicemail:["phone"],volume:["music","sound","mute"],"volume-1":["music","sound"],"volume-2":["music","sound"],"volume-x":["music","sound","mute"],watch:["clock","time"],wind:["weather","air"],"x-circle":["cancel","close","delete","remove","times"],"x-octagon":["delete","stop","alert","warning","times"],"x-square":["cancel","close","delete","remove","times"],x:["cancel","close","delete","remove","times"],youtube:["logo","video","play"],"zap-off":["flash","camera","lightning"],zap:["flash","camera","lightning"]}},function(e){e.exports={activity:'',airplay:'',"alert-circle":'',"alert-octagon":'',"alert-triangle":'',"align-center":'',"align-justify":'',"align-left":'',"align-right":'',anchor:'',aperture:'',archive:'',"arrow-down-circle":'',"arrow-down-left":'',"arrow-down-right":'',"arrow-down":'',"arrow-left-circle":'',"arrow-left":'',"arrow-right-circle":'',"arrow-right":'',"arrow-up-circle":'',"arrow-up-left":'',"arrow-up-right":'',"arrow-up":'',"at-sign":'',award:'',"bar-chart-2":'',"bar-chart":'',"battery-charging":'',battery:'',"bell-off":'',bell:'',bluetooth:'',bold:'',"book-open":'',book:'',bookmark:'',box:'',briefcase:'',calendar:'',"camera-off":'',camera:'',cast:'',"check-circle":'',"check-square":'',check:'',"chevron-down":'',"chevron-left":'',"chevron-right":'',"chevron-up":'',"chevrons-down":'',"chevrons-left":'',"chevrons-right":'',"chevrons-up":'',chrome:'',circle:'',clipboard:'',clock:'',"cloud-drizzle":'',"cloud-lightning":'',"cloud-off":'',"cloud-rain":'',"cloud-snow":'',cloud:'',code:'',codepen:'',codesandbox:'',coffee:'',columns:'',command:'',compass:'',copy:'',"corner-down-left":'',"corner-down-right":'',"corner-left-down":'',"corner-left-up":'',"corner-right-down":'',"corner-right-up":'',"corner-up-left":'',"corner-up-right":'',cpu:'',"credit-card":'',crop:'',crosshair:'',database:'',delete:'',disc:'',"dollar-sign":'',"download-cloud":'',download:'',droplet:'',"edit-2":'',"edit-3":'',edit:'',"external-link":'',"eye-off":'',eye:'',facebook:'',"fast-forward":'',feather:'',figma:'',"file-minus":'',"file-plus":'',"file-text":'',file:'',film:'',filter:'',flag:'',"folder-minus":'',"folder-plus":'',folder:'',frown:'',gift:'',"git-branch":'',"git-commit":'',"git-merge":'',"git-pull-request":'',github:'',gitlab:'',globe:'',grid:'',"hard-drive":'',hash:'',headphones:'',heart:'',"help-circle":'',hexagon:'',home:'',image:'',inbox:'',info:'',instagram:'',italic:'',key:'',layers:'',layout:'',"life-buoy":'',"link-2":'',link:'',linkedin:'',list:'',loader:'',lock:'',"log-in":'',"log-out":'',mail:'',"map-pin":'',map:'',"maximize-2":'',maximize:'',meh:'',menu:'',"message-circle":'',"message-square":'',"mic-off":'',mic:'',"minimize-2":'',minimize:'',"minus-circle":'',"minus-square":'',minus:'',monitor:'',moon:'',"more-horizontal":'',"more-vertical":'',"mouse-pointer":'',move:'',music:'',"navigation-2":'',navigation:'',octagon:'',package:'',paperclip:'',"pause-circle":'',pause:'',"pen-tool":'',percent:'',"phone-call":'',"phone-forwarded":'',"phone-incoming":'',"phone-missed":'',"phone-off":'',"phone-outgoing":'',phone:'',"pie-chart":'',"play-circle":'',play:'',"plus-circle":'',"plus-square":'',plus:'',pocket:'',power:'',printer:'',radio:'',"refresh-ccw":'',"refresh-cw":'',repeat:'',rewind:'',"rotate-ccw":'',"rotate-cw":'',rss:'',save:'',scissors:'',search:'',send:'',server:'',settings:'',"share-2":'',share:'',"shield-off":'',shield:'',"shopping-bag":'',"shopping-cart":'',shuffle:'',sidebar:'',"skip-back":'',"skip-forward":'',slack:'',slash:'',sliders:'',smartphone:'',smile:'',speaker:'',square:'',star:'',"stop-circle":'',sun:'',sunrise:'',sunset:'',tablet:'',tag:'',target:'',terminal:'',thermometer:'',"thumbs-down":'',"thumbs-up":'',"toggle-left":'',"toggle-right":'',"trash-2":'',trash:'',trello:'',"trending-down":'',"trending-up":'',triangle:'',truck:'',tv:'',twitter:'',type:'',umbrella:'',underline:'',unlock:'',"upload-cloud":'',upload:'',"user-check":'',"user-minus":'',"user-plus":'',"user-x":'',user:'',users:'',"video-off":'',video:'',voicemail:'',"volume-1":'',"volume-2":'',"volume-x":'',volume:'',watch:'',"wifi-off":'',wifi:'',wind:'',"x-circle":'',"x-octagon":'',"x-square":'',x:'',youtube:'',"zap-off":'',zap:'',"zoom-in":'',"zoom-out":''}},function(e){e.exports={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"}},function(e,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var l=Object.assign||function(e){for(var n=1;n2&&void 0!==arguments[2]?arguments[2]:[];!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=n,this.contents=i,this.tags=t,this.attrs=l({},o.default,{class:"feather feather-"+n})}return t(e,[{key:"toSvg",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return""+this.contents+""}},{key:"toString",value:function(){return this.contents}}]),e}();n.default=c},function(e,n,i){"use strict";var l=o(i(8)),t=o(i(31)),r=o(i(30));function o(e){return e&&e.__esModule?e:{default:e}}e.exports={icons:l.default,toSvg:t.default,replace:r.default}},function(e,n,i){var l=i(0)("iterator"),t=!1;try{var r=[7][l]();r.return=function(){t=!0},Array.from(r,function(){throw 2})}catch(e){}e.exports=function(e,n){if(!n&&!t)return!1;var i=!1;try{var r=[7],o=r[l]();o.next=function(){return{done:i=!0}},r[l]=function(){return o},e(r)}catch(e){}return i}},function(e,n,i){var l=i(22),t=i(0)("toStringTag"),r="Arguments"==l(function(){return arguments}());e.exports=function(e){var n,i,o;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(i=function(e,n){try{return e[n]}catch(e){}}(n=Object(e),t))?i:r?l(n):"Object"==(o=l(n))&&"function"==typeof n.callee?"Arguments":o}},function(e,n,i){var l=i(38),t=i(0)("iterator"),r=i(10);e.exports=i(2).getIteratorMethod=function(e){if(void 0!=e)return e[t]||e["@@iterator"]||r[l(e)]}},function(e,n,i){"use strict";var l=i(6),t=i(12);e.exports=function(e,n,i){n in e?l.f(e,n,t(0,i)):e[n]=i}},function(e,n,i){var l=i(10),t=i(0)("iterator"),r=Array.prototype;e.exports=function(e){return void 0!==e&&(l.Array===e||r[t]===e)}},function(e,n,i){var l=i(5);e.exports=function(e,n,i,t){try{return t?n(l(i)[0],i[1]):n(i)}catch(n){var r=e.return;throw void 0!==r&&l(r.call(e)),n}}},function(e,n,i){"use strict";var l=i(24),t=i(28),r=i(17),o=i(42),a=i(41),c=i(21),y=i(40),p=i(39);t(t.S+t.F*!i(37)(function(e){Array.from(e)}),"Array",{from:function(e){var n,i,t,h,x=r(e),s="function"==typeof this?this:Array,u=arguments.length,d=u>1?arguments[1]:void 0,f=void 0!==d,v=0,g=p(x);if(f&&(d=l(d,u>2?arguments[2]:void 0,2)),void 0==g||s==Array&&a(g))for(i=new s(n=c(x.length));n>v;v++)y(i,v,f?d(x[v],v):x[v]);else for(h=g.call(x),i=new s;!(t=h.next()).done;v++)y(i,v,f?o(h,d,[t.value,v],!0):t.value);return i.length=v,i}})},function(e,n,i){var l=i(3),t=i(17),r=i(9)("IE_PROTO"),o=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=t(e),l(e,r)?e[r]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?o:null}},function(e,n,i){var l=i(1).document;e.exports=l&&l.documentElement},function(e,n,i){var l=i(15),t=Math.max,r=Math.min;e.exports=function(e,n){return(e=l(e))<0?t(e+n,0):r(e,n)}},function(e,n,i){var l=i(23),t=i(21),r=i(46);e.exports=function(e){return function(n,i,o){var a,c=l(n),y=t(c.length),p=r(o,y);if(e&&i!=i){for(;y>p;)if((a=c[p++])!=a)return!0}else for(;y>p;p++)if((e||p in c)&&c[p]===i)return e||p||0;return!e&&-1}}},function(e,n,i){var l=i(22);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==l(e)?e.split(""):Object(e)}},function(e,n,i){var l=i(3),t=i(23),r=i(47)(!1),o=i(9)("IE_PROTO");e.exports=function(e,n){var i,a=t(e),c=0,y=[];for(i in a)i!=o&&l(a,i)&&y.push(i);for(;n.length>c;)l(a,i=n[c++])&&(~r(y,i)||y.push(i));return y}},function(e,n,i){var l=i(49),t=i(19);e.exports=Object.keys||function(e){return l(e,t)}},function(e,n,i){var l=i(6),t=i(5),r=i(50);e.exports=i(4)?Object.defineProperties:function(e,n){t(e);for(var i,o=r(n),a=o.length,c=0;a>c;)l.f(e,i=o[c++],n[i]);return e}},function(e,n,i){var l=i(5),t=i(51),r=i(19),o=i(9)("IE_PROTO"),a=function(){},c=function(){var e,n=i(26)("iframe"),l=r.length;for(n.style.display="none",i(45).appendChild(n),n.src="javascript:",(e=n.contentWindow.document).open(),e.write("