├── .dockerignore ├── _posts.zip ├── netlify.toml ├── .env.production ├── static ├── favicon.ico ├── apple-icon.png ├── og │ ├── default.png │ └── csharp-14-extension-members.png ├── kevin_rockon.jpg ├── kevin_rockon.png ├── robots.txt ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png ├── ms-icon-70x70.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── android-icon-144x144.png ├── android-icon-192x192.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── apple-icon-precomposed.png ├── images │ └── hangfire-thumbnail.png ├── MVP_Badge_Horizontal_Secondary_White_RGB.png ├── pdfs │ ├── spas-with-vuejs-aspnetcore_20200820.pdf │ ├── BetterObjectMappingInDotNetWithDapper_20200514.pdf │ ├── BuildingCustomVueJSServicesandPlugins_20200720.pdf │ └── 21stCenturyBackgroundServicesWithAzureLogicAppsAndAzureFunctions.pdf └── README.md ├── blog ├── images │ ├── background.jpg │ ├── blog_bg_1.jpg │ ├── blog_bg_2.jpg │ ├── blog_bg_3.jpg │ ├── blog_bg_4.jpg │ ├── twitchlib.png │ ├── mojave-night.jpg │ ├── crazy-fast-001.png │ ├── crazy-fast-002.png │ ├── hangfire-udemy.png │ ├── logging_preview.png │ ├── 2024-12-10-queue.jpg │ ├── 2024-12-10-queue2.jpg │ ├── hangfire-thumbnail.png │ ├── ndc-london-tactics.jpg │ ├── twitch-badge-offline.png │ ├── 2024-12-10-ep2-pricing.png │ ├── 2024-12-10-ep2-scaled.png │ ├── 2024-12-10-kevinjames.gif │ ├── 20240625-devfest-crowd.jpg │ ├── 2023-06-19-hangfire-retry.png │ ├── 2024-12-10-bandit-hammer.gif │ ├── 2024-12-10-exclusive-club.gif │ ├── 20240625-devfest-lunch1.jpeg │ ├── 20240625-devfest-poster.png │ ├── 20240625-devfest-speaker.jpg │ ├── 20240625-devfest-theater.jpg │ ├── signalr-mastery-thumbnail.png │ ├── windowservices-inaction.gif │ ├── 20170601_174425048_iOS-min.jpg │ ├── 20170602_173432593_iOS-min.jpg │ ├── 2024-12-10-exclusive-club.webp │ ├── i-love-static-web-apps-001.png │ ├── i-love-static-web-apps-002.png │ ├── i-love-static-web-apps-003.png │ ├── i-love-static-web-apps-004.png │ ├── i-love-static-web-apps-005.png │ ├── i-love-static-web-apps-006.png │ ├── i-love-static-web-apps-007.png │ ├── windowservices-serviceview.png │ ├── windowservices-watchfolder.png │ ├── 2023-06-19-hangfire-dashboard.png │ ├── 2023-06-19-hangfire-failures.png │ ├── 2023-06-19-hangfire-recurring.png │ ├── 2024-12-10-consumption-pricing.png │ ├── 20240625-devfest-breakfast1.jpeg │ ├── azure-static-app-routing-001.png │ ├── whatisdapper_data_to_objects.png │ ├── 2021-12-08-upgrade-assistant-sample.png │ ├── 20240625-devfest-kevin-linda-alex.jpg │ └── 20241031-azure-functions-host-error.jpg ├── .vscode │ └── settings.json ├── 20201117-installing-net-5-for-beginners.md ├── 20150828-enable-signalr-logging-with-one-simple-line.md ├── 20200414-talking-remote-tools-for-developers-with-bret-fisher.md ├── 20200719-building-vue-services-and-plugins.md ├── 20091117-enhancing-your-applications-for-windows-7.md ├── 20200506-the-dev-talk-show-recap-and-resources.md ├── 20090421-wildcard-search-with-linq.md ├── 20140902-one-simple-rule-for-successful-consulting.md ├── 20091201-learn-about-windows-7-task-dialogs.md ├── 20181213-quick-introduction-to-signalr-streaming.md ├── 20160715-powershell-how-to-recursively-delete-files-based-of-file-extension.md ├── 20200816-single-page-architectures-with-vuejs-and-aspnet-core.md ├── 20200512-21st-century-background-services-resources-and-replays.md ├── 20100329-if-you-reach-just-one-person.md ├── 20200513-better-object-mapping-with-dapper-resources.md ├── 20130514-specifying-visual-studio-version-in-npm-installs.md ├── 20201013-how-to-upgrade-net-cli-templates.md ├── 20121112-my-default-gitignore-file.md ├── 20100105-console-games-why-do-we-have-to-press-start.md ├── 20250610-tech-communities-ai-in-development-and-roller-coasters-fervent-four-podcast.md ├── 20200515-how-do-you-call-a-stored-procedure-with-dapper.md ├── 20210223-converting-epoch-time-into-datetime-with-azure-logic-apps.md ├── 20210110-how-to-debug-cssjavascript-mouse-or-hover-events.md ├── 20161108-exploring-c-70-out-variables.md ├── 20200407-how-to-run-visual-studio-code-on-mac-osx.md ├── 20141013-mongodb-setting-ttl-on-documents.md ├── 20150514-no-matter-what-you-do-add-value.md ├── 20121102-preloading-multiple-audio-tags-in-internet-explorer-9.md ├── 20150723-paying-attention.md ├── 20150306-managing-your-user-group-calendar-roulette.md ├── 20160324-the-10-rule-to-presentations.md ├── 20151013-managing-your-user-group-food.md ├── 20090206-a-diet-programmers-can-relate-to.md ├── 20100119-are-we-too-dependent-on-the-internet.md ├── 20091016-my-attempt-at-linq-pagination.md ├── 20110214-building-better-connectionstrings-with-connectionstringbuilder.md ├── 20100126-leaving-it-better-than-you-found-it.md ├── 20150803-banks-atms-and-horrible-user-experiences.md ├── 20180501-i-removed-email-from-my-phone.md ├── 20200816-stockholm-clients.md ├── 20121231-nodejs-using-require-to-load-your-own-files.md ├── 20100302-colossal-failures.md ├── 20210409-streaming-an-mp4-to-twitch-and-youtube-with-ffmpeg.md ├── 20170503-about-blog-posts.md ├── 20120215-maintaining-signalr-connectionids-across-page-instances.md ├── 20160704-open-source-mentality-of-choosing-your-tech-stack.md ├── 20150126-managing-your-user-group-sponsor-relationships.md ├── 20090304-definition-of-a-computer-scientist.md ├── 20200810-how-to-redirect-with-azure-static-web-apps.md ├── 20210303-signalr-abortcontroller-is-undefined-on-older-browsers.md ├── 20210112-launched-today-signalr-mastery.md └── 20250825-framework-16-laptop-review.md ├── .gitignore ├── docs ├── images │ └── signalr-mastery-thumbnail.png ├── Training.md ├── SignalR-Mastery.md ├── Consulting.md ├── Coasters.md └── Courses.md ├── renovate.json ├── .claude └── settings.local.json ├── src ├── components │ ├── README.md │ ├── SearchFocus.vue │ ├── PaginationPosts.vue │ └── ThemeSwitcher.vue ├── layouts │ └── README.md ├── pages │ ├── README.md │ ├── 404.vue │ ├── Contact.vue │ └── Articles.vue ├── templates │ ├── README.md │ ├── Redirect.vue │ ├── Documentation.vue │ ├── Tag.vue │ └── Post.vue ├── browserconfig.xml ├── manifest.json ├── main.js ├── css │ └── main.css └── index.html ├── README.md ├── previewify_sample.html ├── .vscode └── settings.json ├── Dockerfile ├── Dockerfile.build ├── .github ├── workflows │ ├── schedule.yml │ ├── deploy.yml │ ├── azure-static-web-apps-yellow-forest-0e8e9d20f.yml │ ├── claude.yml │ └── claude-code-review.yml └── agents │ └── coaster-expert.md ├── license ├── package.json ├── scripts └── create-post.js ├── _README.md ├── gridsome.server.js ├── tailwind.config.js ├── CLAUDE.md └── gridsome.config.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | blog -------------------------------------------------------------------------------- /_posts.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/_posts.zip -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "dist" 3 | command = "gridsome build" 4 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | GRIDSOME_FUNCTIONS_URL=https://consultwithgriff-functions.azurewebsites.net/api/ -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/favicon.ico -------------------------------------------------------------------------------- /static/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon.png -------------------------------------------------------------------------------- /static/og/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/og/default.png -------------------------------------------------------------------------------- /static/kevin_rockon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/kevin_rockon.jpg -------------------------------------------------------------------------------- /static/kevin_rockon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/kevin_rockon.png -------------------------------------------------------------------------------- /static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | Sitemap: https://consultwithgriff.com/sitemap.xml 5 | -------------------------------------------------------------------------------- /blog/images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/background.jpg -------------------------------------------------------------------------------- /blog/images/blog_bg_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/blog_bg_1.jpg -------------------------------------------------------------------------------- /blog/images/blog_bg_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/blog_bg_2.jpg -------------------------------------------------------------------------------- /blog/images/blog_bg_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/blog_bg_3.jpg -------------------------------------------------------------------------------- /blog/images/blog_bg_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/blog_bg_4.jpg -------------------------------------------------------------------------------- /blog/images/twitchlib.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/twitchlib.png -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/favicon-96x96.png -------------------------------------------------------------------------------- /static/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/ms-icon-144x144.png -------------------------------------------------------------------------------- /static/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/ms-icon-150x150.png -------------------------------------------------------------------------------- /static/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/ms-icon-310x310.png -------------------------------------------------------------------------------- /static/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/ms-icon-70x70.png -------------------------------------------------------------------------------- /blog/images/mojave-night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/mojave-night.jpg -------------------------------------------------------------------------------- /static/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-57x57.png -------------------------------------------------------------------------------- /static/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-60x60.png -------------------------------------------------------------------------------- /static/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-72x72.png -------------------------------------------------------------------------------- /static/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-76x76.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .cache 3 | .DS_Store 4 | src/.temp 5 | node_modules 6 | dist 7 | .env 8 | .env.* 9 | static/rss.xml -------------------------------------------------------------------------------- /blog/images/crazy-fast-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/crazy-fast-001.png -------------------------------------------------------------------------------- /blog/images/crazy-fast-002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/crazy-fast-002.png -------------------------------------------------------------------------------- /blog/images/hangfire-udemy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/hangfire-udemy.png -------------------------------------------------------------------------------- /blog/images/logging_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/logging_preview.png -------------------------------------------------------------------------------- /static/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/android-icon-144x144.png -------------------------------------------------------------------------------- /static/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/android-icon-192x192.png -------------------------------------------------------------------------------- /static/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/android-icon-36x36.png -------------------------------------------------------------------------------- /static/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/android-icon-48x48.png -------------------------------------------------------------------------------- /static/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/android-icon-72x72.png -------------------------------------------------------------------------------- /static/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/android-icon-96x96.png -------------------------------------------------------------------------------- /static/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-114x114.png -------------------------------------------------------------------------------- /static/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-120x120.png -------------------------------------------------------------------------------- /static/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-144x144.png -------------------------------------------------------------------------------- /static/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-152x152.png -------------------------------------------------------------------------------- /static/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-180x180.png -------------------------------------------------------------------------------- /blog/images/2024-12-10-queue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-queue.jpg -------------------------------------------------------------------------------- /blog/images/2024-12-10-queue2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-queue2.jpg -------------------------------------------------------------------------------- /static/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/apple-icon-precomposed.png -------------------------------------------------------------------------------- /blog/images/hangfire-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/hangfire-thumbnail.png -------------------------------------------------------------------------------- /blog/images/ndc-london-tactics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/ndc-london-tactics.jpg -------------------------------------------------------------------------------- /blog/images/twitch-badge-offline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/twitch-badge-offline.png -------------------------------------------------------------------------------- /static/images/hangfire-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/images/hangfire-thumbnail.png -------------------------------------------------------------------------------- /blog/images/2024-12-10-ep2-pricing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-ep2-pricing.png -------------------------------------------------------------------------------- /blog/images/2024-12-10-ep2-scaled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-ep2-scaled.png -------------------------------------------------------------------------------- /blog/images/2024-12-10-kevinjames.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-kevinjames.gif -------------------------------------------------------------------------------- /blog/images/20240625-devfest-crowd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20240625-devfest-crowd.jpg -------------------------------------------------------------------------------- /blog/images/2023-06-19-hangfire-retry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2023-06-19-hangfire-retry.png -------------------------------------------------------------------------------- /blog/images/2024-12-10-bandit-hammer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-bandit-hammer.gif -------------------------------------------------------------------------------- /blog/images/2024-12-10-exclusive-club.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-exclusive-club.gif -------------------------------------------------------------------------------- /blog/images/20240625-devfest-lunch1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20240625-devfest-lunch1.jpeg -------------------------------------------------------------------------------- /blog/images/20240625-devfest-poster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20240625-devfest-poster.png -------------------------------------------------------------------------------- /blog/images/20240625-devfest-speaker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20240625-devfest-speaker.jpg -------------------------------------------------------------------------------- /blog/images/20240625-devfest-theater.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20240625-devfest-theater.jpg -------------------------------------------------------------------------------- /blog/images/signalr-mastery-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/signalr-mastery-thumbnail.png -------------------------------------------------------------------------------- /blog/images/windowservices-inaction.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/windowservices-inaction.gif -------------------------------------------------------------------------------- /docs/images/signalr-mastery-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/docs/images/signalr-mastery-thumbnail.png -------------------------------------------------------------------------------- /static/og/csharp-14-extension-members.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/og/csharp-14-extension-members.png -------------------------------------------------------------------------------- /blog/images/20170601_174425048_iOS-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20170601_174425048_iOS-min.jpg -------------------------------------------------------------------------------- /blog/images/20170602_173432593_iOS-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20170602_173432593_iOS-min.jpg -------------------------------------------------------------------------------- /blog/images/2024-12-10-exclusive-club.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-exclusive-club.webp -------------------------------------------------------------------------------- /blog/images/i-love-static-web-apps-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/i-love-static-web-apps-001.png -------------------------------------------------------------------------------- /blog/images/i-love-static-web-apps-002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/i-love-static-web-apps-002.png -------------------------------------------------------------------------------- /blog/images/i-love-static-web-apps-003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/i-love-static-web-apps-003.png -------------------------------------------------------------------------------- /blog/images/i-love-static-web-apps-004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/i-love-static-web-apps-004.png -------------------------------------------------------------------------------- /blog/images/i-love-static-web-apps-005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/i-love-static-web-apps-005.png -------------------------------------------------------------------------------- /blog/images/i-love-static-web-apps-006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/i-love-static-web-apps-006.png -------------------------------------------------------------------------------- /blog/images/i-love-static-web-apps-007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/i-love-static-web-apps-007.png -------------------------------------------------------------------------------- /blog/images/windowservices-serviceview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/windowservices-serviceview.png -------------------------------------------------------------------------------- /blog/images/windowservices-watchfolder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/windowservices-watchfolder.png -------------------------------------------------------------------------------- /blog/images/2023-06-19-hangfire-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2023-06-19-hangfire-dashboard.png -------------------------------------------------------------------------------- /blog/images/2023-06-19-hangfire-failures.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2023-06-19-hangfire-failures.png -------------------------------------------------------------------------------- /blog/images/2023-06-19-hangfire-recurring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2023-06-19-hangfire-recurring.png -------------------------------------------------------------------------------- /blog/images/2024-12-10-consumption-pricing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2024-12-10-consumption-pricing.png -------------------------------------------------------------------------------- /blog/images/20240625-devfest-breakfast1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20240625-devfest-breakfast1.jpeg -------------------------------------------------------------------------------- /blog/images/azure-static-app-routing-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/azure-static-app-routing-001.png -------------------------------------------------------------------------------- /blog/images/whatisdapper_data_to_objects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/whatisdapper_data_to_objects.png -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /blog/images/2021-12-08-upgrade-assistant-sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/2021-12-08-upgrade-assistant-sample.png -------------------------------------------------------------------------------- /blog/images/20240625-devfest-kevin-linda-alex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20240625-devfest-kevin-linda-alex.jpg -------------------------------------------------------------------------------- /blog/images/20241031-azure-functions-host-error.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/blog/images/20241031-azure-functions-host-error.jpg -------------------------------------------------------------------------------- /static/MVP_Badge_Horizontal_Secondary_White_RGB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/MVP_Badge_Horizontal_Secondary_White_RGB.png -------------------------------------------------------------------------------- /static/pdfs/spas-with-vuejs-aspnetcore_20200820.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/pdfs/spas-with-vuejs-aspnetcore_20200820.pdf -------------------------------------------------------------------------------- /.claude/settings.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": { 3 | "allow": [ 4 | "Bash(yarn run build:*)" 5 | ], 6 | "deny": [], 7 | "ask": [] 8 | } 9 | } -------------------------------------------------------------------------------- /static/pdfs/BetterObjectMappingInDotNetWithDapper_20200514.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/pdfs/BetterObjectMappingInDotNetWithDapper_20200514.pdf -------------------------------------------------------------------------------- /static/pdfs/BuildingCustomVueJSServicesandPlugins_20200720.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/pdfs/BuildingCustomVueJSServicesandPlugins_20200720.pdf -------------------------------------------------------------------------------- /blog/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownlint.config": { 3 | "MD028": false, 4 | "MD025": { 5 | "front_matter_title": "" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/components/README.md: -------------------------------------------------------------------------------- 1 | Add components that will be imported to Pages and Layouts to this folder. 2 | Learn more about components here: https://gridsome.org/docs/components 3 | 4 | You can delete this file. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ConsultWithGriff.com 2 | 3 | ![Deploy Master to Azure Blob Storage](https://github.com/1kevgriff/kevgriffin.v4/workflows/Deploy%20Master%20to%20Azure%20Blob%20Storage/badge.svg) 4 | 5 | Hello World! 6 | -------------------------------------------------------------------------------- /static/pdfs/21stCenturyBackgroundServicesWithAzureLogicAppsAndAzureFunctions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1kevgriff/kevgriffin.v4/master/static/pdfs/21stCenturyBackgroundServicesWithAzureLogicAppsAndAzureFunctions.pdf -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | Add static files here. Files in this directory will be copied directly to `dist` folder during build. For example, /static/robots.txt will be located at https://yoursite.com/robots.txt. 2 | 3 | This file should be deleted. -------------------------------------------------------------------------------- /src/layouts/README.md: -------------------------------------------------------------------------------- 1 | Layout components are used to wrap pages and templates. Layouts should contain components like headers, footers or sidebars that will be used across the site. 2 | 3 | Learn more about Layouts: https://gridsome.org/docs/layouts 4 | 5 | You can delete this file. -------------------------------------------------------------------------------- /src/pages/README.md: -------------------------------------------------------------------------------- 1 | Pages are usually used for normal pages or for listing items from a GraphQL collection. 2 | Add .vue files here to create pages. For example **About.vue** will be **site.com/about**. 3 | Learn more about pages: https://gridsome.org/docs/pages 4 | 5 | You can delete this file. -------------------------------------------------------------------------------- /src/templates/README.md: -------------------------------------------------------------------------------- 1 | Templates for **GraphQL collections** should be added here. 2 | To create a template for a collection called `WordPressPost` 3 | create a file named `WordPressPost.vue` in this folder. 4 | 5 | Learn more: https://gridsome.org/docs/templates 6 | 7 | You can delete this file. -------------------------------------------------------------------------------- /src/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /previewify_sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownlint.config": { 3 | "MD028": false, 4 | "MD025": { 5 | "front_matter_title": "" 6 | } 7 | }, 8 | "yaml.schemas": { 9 | "file:///c%3A/Users/kevin/.vscode/extensions/docsmsft.docs-yaml-1.0.0/dist/toc.schema.json": "/toc\\.yml/i", 10 | "https://json.schemastore.org/github-workflow.json": "file:///d%3A/repos/kevgriffin.v4/.github/workflows/deploy.yml" 11 | } 12 | } -------------------------------------------------------------------------------- /src/pages/404.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | 20 | -------------------------------------------------------------------------------- /docs/Training.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Training 3 | date: 2017-05-03 12:50:43 4 | permalink: training 5 | categories: 6 | - Misc 7 | excerpt: "Looking to learn something new?" 8 | --- 9 | 10 | ## Upcoming Training Engagements 11 | There are no public training engagements currently scheduled. 12 | 13 | ## Private Training? 14 | Shoot me an [email](mailto:connect@consultwithgriff.com) with a little information about your needs, and I'll respond with availability and a rate sheet. 15 | -------------------------------------------------------------------------------- /src/components/SearchFocus.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official Node.js 18 image with build tools 2 | FROM node:18-bullseye 3 | 4 | # Set the working directory in the container 5 | WORKDIR /usr/src/app 6 | 7 | # Copy package.json and package-lock.json to the working directory 8 | COPY package*.json ./ 9 | 10 | # Install the dependencies 11 | RUN npm install 12 | 13 | # Copy the rest of the application code to the working directory, excluding node_modules 14 | COPY . ./ 15 | 16 | # Expose the port the app runs on 17 | EXPOSE 8080 18 | 19 | # Command to run the application 20 | CMD ["npm", "run", "develop"] 21 | 22 | # Map the local "blog" directory to the container's "blog" directory at runtime 23 | VOLUME ["/usr/src/app/blog"] 24 | -------------------------------------------------------------------------------- /src/templates/Redirect.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /Dockerfile.build: -------------------------------------------------------------------------------- 1 | # Use Node 14 which has better compatibility with Gridsome 0.7.x 2 | FROM node:14-buster 3 | 4 | # Set working directory 5 | WORKDIR /app 6 | 7 | # Copy package files (only package.json now) 8 | COPY package.json ./ 9 | 10 | # Install dependencies fresh 11 | RUN npm install 12 | 13 | # Copy all source files 14 | COPY . . 15 | 16 | # Build the Gridsome site 17 | RUN npm run build 18 | 19 | # Use nginx to serve the static files 20 | FROM nginx:alpine 21 | 22 | # Copy built files from build stage 23 | COPY --from=0 /app/dist /usr/share/nginx/html 24 | 25 | # Copy nginx configuration if you have one (optional) 26 | # COPY nginx.conf /etc/nginx/nginx.conf 27 | 28 | EXPOSE 80 29 | 30 | CMD ["nginx", "-g", "daemon off;"] -------------------------------------------------------------------------------- /.github/workflows/schedule.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Schedule Future Posts 4 | 5 | on: 6 | pull_request: 7 | types: 8 | - opened 9 | - edited 10 | - synchronize 11 | schedule: 12 | - cron: "*/30 * * * *" 13 | jobs: 14 | merge_schedule: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: gr2m/merge-schedule-action@v1.x 18 | with: 19 | # Merge method to use. Possible values are merge, squash or 20 | # rebase. Default is merge. 21 | merge_method: squash 22 | # Time zone to use. Default is UTC. 23 | time_zone: "America/New_York" 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /blog/20201117-installing-net-5-for-beginners.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Installing .NET 5 for Beginners" 3 | date: 2020-11-18T00:00:00Z 4 | permalink: installing-dotnet-5-for-beginners 5 | description: "A beginner-friendly video tutorial walking through the process of installing .NET 5 SDK and creating your first Hello World application." 6 | summary: "Are you new to .NET, and you're looking at how to get started? This video is just for you!" 7 | tags: 8 | - .NET 5 9 | - Beginners 10 | - Installation 11 | - Tutorial 12 | - Hello World 13 | - Getting Started 14 | categories: 15 | - .NET 16 | --- 17 | 18 | `youtube:https://www.youtube.com/watch?v=karSxhTb_38` 19 | 20 | .NET 5 is the new hotness on street, and if you're new to .NET you might be wondering HOW do you get started? In this video, I'll walk you through downloading the .NET 5 SDK and scaffolding out your own `Hello World` example! 21 | 22 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /src/templates/Documentation.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | query Documentation ($id: ID!) { 17 | documentation(id: $id) { 18 | title 19 | excerpt 20 | path 21 | } 22 | } 23 | 24 | 25 | 35 | 36 | -------------------------------------------------------------------------------- /blog/20200513-better-object-mapping-with-dapper-resources.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Better Object Mapping with Dapper Resources" 3 | date: 2020-05-14T00:30:00Z 4 | permalink: dapper 5 | description: "Thanks for Better Object Mapping with Dapper!" 6 | summary: "Thanks for Better Object Mapping with Dapper!" 7 | tags: 8 | - Dapper 9 | - ORM 10 | - Object Mapping 11 | - .NET 12 | categories: 13 | - Misc 14 | excerpt: "Thanks for Better Object Mapping with Dapper!" 15 | --- 16 | 17 | Thanks for my talk on **Better Object Mapping with Dapper**. Please check out the resources below, and join my mailing list for future updates! 18 | 19 | ## Some questions, answered 20 | 21 | [How do you work with multiple result sets with Dapper?](/dapper-stored-procedures) 22 | How do you call a stored procedure with Dapper? (Coming soon) 23 | Retrieving Output Parameters Using Dapper (Coming soon) 24 | 25 | 26 | Do you have questions about Dapper? Drop me a message on [Twitter](https://twitter.com/1kevgriff) and I'll add it to my list! 27 | 28 | ## Slides 29 | 30 | [Download Slides](/pdfs/BetterObjectMappingInDotNetWithDapper_20200514.pdf) 31 | 32 | ## Links to Resources 33 | 34 | [Twitter](https://twitter.com/1kevgriff) 35 | [My Twitch Channel](https://www.twitch.tv/1kevgriff) 36 | [Dapper GitHub Repo](https://github.com/DapperLib/Dapper) 37 | 38 | -------------------------------------------------------------------------------- /blog/20130514-specifying-visual-studio-version-in-npm-installs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Specifying Visual Studio Version in NPM Installs" 3 | date: 2013-05-14T06:34:08Z 4 | permalink: specifying-visual-studio-version-in-npm-installs 5 | description: "How to specify Visual Studio versions with NPM installs to avoid build tool compatibility issues." 6 | summary: "How to specify Visual Studio versions with NPM installs" 7 | tags: 8 | - NPM 9 | - Visual Studio 10 | - Node.js 11 | - Build Tools 12 | categories: 13 | - Development 14 | --- 15 | 16 | Sometimes when you install a NPM package, you'll run into an issue like this: 17 | 18 |
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.Cpp.Platform.targets(35,5): error MSB8020: The builds tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found. To build using the v100 build tools, either click the Project menu or right-click the solution, and then select "Update VC++ Projects...". Install Visual Studio 2010 to build using the Visual Studio 2010 build tools.
19 | Normally you'll get this if you're only running VS2012 and it wants VS2010/VS2008.  You can ask NPM to use Visual Studio 2012 instead by using with "--msvs_version=2012" command. 20 | 21 | Example: 22 | 23 |
npm install socket.io --msvs_version=2012
24 | Tada.  This should work almost every time. 25 | -------------------------------------------------------------------------------- /blog/20201013-how-to-upgrade-net-cli-templates.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to Upgrade .NET CLI Templates" 3 | date: 2020-10-14T00:00:00Z 4 | permalink: how-to-upgrade-dotnet-cli-templates 5 | description: "Learn how to check for and apply updates to your .NET CLI templates using simple dotnet commands introduced in .NET Core 3.0." 6 | summary: "How do you update the .NET CLI templates? Turns out there is a command just for you!" 7 | tags: 8 | - .NET CLI 9 | - Templates 10 | - dotnet 11 | - .NET Core 12 | - Updates 13 | - Command Line 14 | categories: 15 | - .NET 16 | --- 17 | 18 | I saw an awesome tweet on Twitter today: 19 | 20 | https://twitter.com/buhakmeh/status/1316360387886014464 21 | 22 | Turns out, if you've upgraded to .NET Core 3.0, there is a special command just for this! Head over to the [.NET Core Docs](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new?WT.mc_id=DOP-MVP-4029061) and look for these two options at the bottom: 23 | 24 | ### Checking for Updates 25 | 26 | ```powershell 27 | dotnet new --update-check 28 | ``` 29 | 30 | > Checks if there are updates available for the template packs that are currently installed. Available since .NET Core 3.0 SDK. 31 | 32 | ### Applying Updates 33 | 34 | ```powershell 35 | dotnet new --update-apply 36 | ``` 37 | 38 | > Checks if there are updates available for the template packs that are currently installed and installs them. Available since .NET Core 3.0 SDK. 39 | 40 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // This is the main.js file. Import global CSS and scripts here. 2 | // The Client API can be used here. Learn more: gridsome.org/docs/client-api 3 | 4 | import DefaultLayout from '~/layouts/Default.vue' 5 | import VueScrollTo from 'vue-scrollto'; 6 | import VueFuse from 'vue-fuse'; 7 | import VueDisqus from 'vue-disqus'; 8 | 9 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; 10 | import { config, library } from '@fortawesome/fontawesome-svg-core'; 11 | import { faSearch, faStar } from '@fortawesome/free-solid-svg-icons' 12 | import '@fortawesome/fontawesome-svg-core/styles.css'; 13 | 14 | config.autoAddCss = false; 15 | library.add(faSearch, faStar); 16 | 17 | export default function (Vue, { router, head, isClient }) { 18 | // Set default layout as a global component 19 | Vue.component('Layout', DefaultLayout); 20 | Vue.component('font-awesome', FontAwesomeIcon); 21 | 22 | Vue.use(VueScrollTo, { 23 | duration: 500, 24 | easing: "ease", 25 | }); 26 | 27 | Vue.use(VueFuse); 28 | Vue.use(VueDisqus); 29 | 30 | head.meta.push({ 31 | name: 'keywords', 32 | content: 'Gridsome,Vue,Tailwind,Tailwind CSS,JavaScript,HTML,CSS,Vue.js,VueJS,.NET,ASP.NET,ASP.NET Core,.NET Core,Microsoft Azure,Azure' 33 | }); 34 | 35 | head.meta.push({ 36 | name: 'author', 37 | content: 'Kevin W. Griffin' 38 | }); 39 | 40 | head.link.push({ 41 | rel: 'stylesheet', 42 | href: 'https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap' 43 | }); 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /blog/20121112-my-default-gitignore-file.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "My Default .gitignore File" 3 | date: 2012-11-12T10:37:23Z 4 | permalink: base-gitignore 5 | description: "A comprehensive .gitignore file template for Visual Studio projects and common development artifacts." 6 | summary: "A comprehensive .gitignore file template for Visual Studio projects and common development artifacts." 7 | tags: 8 | - Git 9 | - Visual Studio 10 | - Development 11 | - Version Control 12 | categories: 13 | - Development 14 | --- 15 | 16 | Every time I create a new Git repo, I always have to go look for a previous copy of my .gitignore file.  I thought it would be a great idea to just post it up for all to find, in case they were looking for it.  This particular file is built around Visual Studio projects. 17 | 18 | ```markdown 19 | # Ignore file for Visual Studio 20 | 21 | # use glob syntax 22 | syntax: glob 23 | 24 | # Ignore Config files with keys and passwords 25 | #ServiceConfiguration*.cscfg 26 | #Web*.config 27 | #App*.config 28 | 29 | # Ignore Visual Studio files 30 | *.obj 31 | #*.exe 32 | #*.pdb 33 | *.user 34 | *.aps 35 | *.pch 36 | *.vspscc 37 | *.vshost.* 38 | *_i.c 39 | *_p.c 40 | *.ncb 41 | *.suo 42 | *.tlb 43 | *.tlh 44 | *.bak 45 | *.cache 46 | *.ilk 47 | *.log 48 | *.lib 49 | *.sbr 50 | *.scc 51 | *.orig 52 | UpgradeLog*.* 53 | UpgradeReport*.* 54 | [Bb]in 55 | [Dd]ebug*/ 56 | obj/ 57 | [Rr]elease*/ 58 | _ReSharper*/ 59 | [Tt]est[Rr]esult* 60 | [Bb]uild[Ll]og.* 61 | *.[Pp]ublish.xml 62 | glob:*.vs10x 63 | *.ReSharper 64 | [Pp]ublish 65 | [Rr]eleaseFiles 66 | [Cc]sx/ 67 | [Bb]ackup1/ 68 | [Pp]ackages/ 69 | 70 | # Mac Files 71 | .DS_Store 72 | *.DS_Store 73 | ._* 74 | ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kevgriffin.v4", 3 | "private": true, 4 | "scripts": { 5 | "build": "NODE_OPTIONS=--openssl-legacy-provider gridsome build", 6 | "develop": "NODE_OPTIONS=--openssl-legacy-provider gridsome develop", 7 | "explore": "gridsome explore", 8 | "docker:build": "docker build -t kevgriffin.v4:latest .", 9 | "docker:develop": "docker run -p 8080:8080 -v ${PWD}/blog:/usr/src/app/blog kevgriffin.v4:latest", 10 | "create-post": "node scripts/create-post.js" 11 | }, 12 | "dependencies": { 13 | "@gridsome/plugin-google-analytics": "^0.1.2", 14 | "@gridsome/plugin-sitemap": "^0.4.0", 15 | "@gridsome/source-filesystem": "^0.6.2", 16 | "@gridsome/transformer-remark": "^0.6.4", 17 | "@gridsome/vue-remark": "^0.2.6", 18 | "@noxify/gridsome-plugin-remark-embed": "^1.3.1", 19 | "autoprefixer": "^10.0.0", 20 | "axios": "^1.0.0", 21 | "gridsome": "^0.7.23", 22 | "gridsome-plugin-gtag": "^0.1.10", 23 | "gridsome-plugin-remark-shiki": "^0.6.0", 24 | "gridsome-plugin-remark-twitter": "^0.2.1", 25 | "gridsome-plugin-remark-youtube": "^1.0.1", 26 | "gridsome-plugin-rss": "^1.2.0", 27 | "lodash.pick": "^4.4.0", 28 | "postcss": "^8.0.0", 29 | "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17", 30 | "vue-disqus": "^4.0.1", 31 | "vue-fuse": "^2.2.1", 32 | "vue-scrollto": "^2.20.0", 33 | "vue-twitter": "^0.1.0" 34 | }, 35 | "devDependencies": { 36 | "@fortawesome/fontawesome-svg-core": "^6.0.0", 37 | "@fortawesome/free-brands-svg-icons": "^6.0.0", 38 | "@fortawesome/free-solid-svg-icons": "^6.0.0", 39 | "@fortawesome/vue-fontawesome": "^2.0.6" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /blog/20100105-console-games-why-do-we-have-to-press-start.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Console Games: Why do we have to press start?" 3 | date: 2010-01-05T06:00:00Z 4 | permalink: console-games-why-do-we-have-to-press-start 5 | description: "Ever wondered why console games make you press start before reaching the main menu? There's actually a good UX reason for this design pattern." 6 | summary: "Ever wondered why console games make you press start before reaching the main menu?" 7 | tags: 8 | - Gaming 9 | - UX Design 10 | - Console Games 11 | - User Experience 12 | categories: 13 | - "Development - Game Development" 14 | --- 15 | 16 | Interesting question came up on Twitter the other day: 17 | 18 | “Press Start” screens? Why can’t I just go straight to the main menu? 19 | 20 | If you’re a gamer, especially on consoles, you’ve seen this screen more often than you’d care to. It’s a little annoyance. However, there is a very good reason for having this screen in place. 21 | 22 | Imagine you’re running four controller on your Xbox, and all four of them are turned on. Then you put in a single player game, and it comes up to that annoying “Press Start” screen. Which controller do you use to press start with? The answer is easy: any of them! 23 | 24 | The “Press Start” screen is designed to determine which controller the game should poll for input. During this screen, the game is polling all connected controllers for input. If any of them register a “start” button push, the game makes that controller the “default” controller. The use-case for this scenario is that the player should be able to use any connected controller to play the game, and not be forced to use controller #1. This is considered a best practice. 25 | 26 | _The More You Know…_ 27 | -------------------------------------------------------------------------------- /blog/20250610-tech-communities-ai-in-development-and-roller-coasters-fervent-four-podcast.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Tech Communities, AI in Development and Roller Coasters | Fervent Four Podcast" 3 | date: 2025-06-10T10:00:00Z 4 | permalink: fervent-four-podcast-tech-communities 5 | description: "Last week I had the pleasure of being on the Fervent Four podcast with Zack Miller and Tim Ryan. We talked about vibing coding and how AI needs to be handled the same way using offshore talent is handled. We discussed roller coasters (because of course) and the origin of my Shedquarters! And talked a lot also about the software development community in the Norfolk / Virginia Beach area." 6 | summary: "Last week I had the pleasure of being on the Fervent Four podcast with Zack Miller and Tim Ryan. We talked about vibing coding and how AI needs to be handled the same way using offshore talent is handled. We discussed roller coasters (because of course) and the origin of my Shedquarters! And talked a lot also about the software development community in the Norfolk / Virginia Beach area." 7 | tags: 8 | - Podcast 9 | categories: 10 | - Podcast 11 | --- 12 | 13 | Last week I had the pleasure of being on the Fervent Four podcast with [Zack Miller](https://www.linkedin.com/in/zackmillersays/) and [Tim Ryan](https://www.linkedin.com/in/ryantnt/). We talked about vibing coding and how AI needs to be handled the same way using offshore talent is handled. We discussed roller coasters (because of course) and the origin of my Shedquarters! And talked a lot also about the software development community in the Norfolk / Virginia Beach area. 14 | 15 | I'd love for you to watch and let me know what you think! 16 | 17 | `youtube:https://www.youtube.com/watch?v=87UXRC47ur0` -------------------------------------------------------------------------------- /scripts/create-post.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const readline = require('readline'); 4 | 5 | const rl = readline.createInterface({ 6 | input: process.stdin, 7 | output: process.stdout 8 | }); 9 | 10 | const BLOG_DIR = path.join(process.cwd(), 'blog'); 11 | 12 | // Ensure blog directory exists 13 | if (!fs.existsSync(BLOG_DIR)) { 14 | fs.mkdirSync(BLOG_DIR, { recursive: true }); 15 | } 16 | 17 | // Get current date in YYYY-MM-DD format 18 | const today = new Date().toISOString().split('T')[0]; 19 | 20 | // Ask for post title 21 | rl.question('Enter the title of your blog post: ', (title) => { 22 | // Convert title to kebab-case for filename 23 | const slug = title 24 | .toLowerCase() 25 | .replace(/[^a-z0-9]+/g, '-') 26 | .replace(/(^-|-$)/g, ''); 27 | 28 | const filename = `${today}-${slug}.md`; 29 | const filepath = path.join(BLOG_DIR, filename); 30 | 31 | // Check if file already exists 32 | if (fs.existsSync(filepath)) { 33 | console.error(`\nError: A file named "${filename}" already exists.`); 34 | console.error('Please choose a different title or delete the existing file.'); 35 | rl.close(); 36 | return; 37 | } 38 | 39 | // Create frontmatter and initial content 40 | const content = `--- 41 | title: "${title}" 42 | date: "${today}" 43 | description: "" 44 | tags: [] 45 | --- 46 | 47 | # ${title} 48 | 49 | `; 50 | 51 | // Write the file with error handling 52 | try { 53 | fs.writeFileSync(filepath, content); 54 | console.log(`\nCreated new blog post: ${filename}`); 55 | console.log(`Location: ${filepath}`); 56 | } catch (error) { 57 | console.error('\nError creating blog post:'); 58 | console.error(error.message); 59 | } 60 | rl.close(); 61 | }); -------------------------------------------------------------------------------- /blog/20200515-how-do-you-call-a-stored-procedure-with-dapper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How do you call a stored procedure with Dapper?" 3 | date: 2020-05-15T08:30:00Z 4 | permalink: dapper-stored-procedures 5 | description: "Learn how to use Dapper with stored procedures in .NET applications, including both query and non-query scenarios." 6 | summary: "Are you interested in using Dapper, but your database uses Stored Procedures? No problem!" 7 | tags: 8 | - .NET 9 | categories: 10 | - .NET 11 | excerpt: "Are you interested in using Dapper, but your database uses Stored Procedures? No problem!" 12 | --- 13 | 14 | During one of my latest renditions of [Better Object Relational Mapping with Dapper](), the question arose about using stored procedures. 15 | 16 | How do you call a stored procedure with Dapper? 17 | 18 | ```csharp 19 | using (var connection = new SqlConnection(CONNECTION_STRING)) 20 | { 21 | var storedProcedureName = "getAllUsers"; 22 | 23 | var results = await connection 24 | .QueryAsync(storedProcedureName, 25 | commandType: CommandType.StoredProcedure); 26 | } 27 | ``` 28 | 29 | Looking at the code above, calling a stored procedure is similar to calling any other query with Dapper. 30 | 31 | 32 | But what if your Stored Procedure doesn't return a result? No problem. `ExecuteAsync` works just as well. 33 | 34 | ```csharp 35 | using (var connection = new SqlConnection(CONNECTION_STRING)) 36 | { 37 | var storedProcedureName = "deleteAllUsers"; 38 | 39 | await connection.ExecuteAsync(storedProcedureName, 40 | commandType: CommandType.StoredProcedure); 41 | } 42 | ``` 43 | 44 | And there you go! Using stored procedures with Dapper can be a great way to take advantage of the strengths of the database while reducing complexity of your code. 45 | 46 | -------------------------------------------------------------------------------- /blog/20210223-converting-epoch-time-into-datetime-with-azure-logic-apps.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Converting Epoch Time into DateTime with Azure Logic Apps" 3 | date: 2021-02-24T00:00:00Z 4 | permalink: azure-logic-apps-epoch-time 5 | description: "Learn how to convert Epoch time to readable DateTime format in Azure Logic Apps when working with APIs like Stripe that use Unix timestamps." 6 | summary: "Some APIs use Epoch time to designate a DateTime object. In Azure Logic Apps, how do you convert this into something useful?" 7 | tags: 8 | - Azure Logic Apps 9 | - Epoch Time 10 | - DateTime Conversion 11 | - Stripe 12 | categories: 13 | - Azure 14 | - Web Development 15 | excerpt: "Recently, I've been building a handful of Azure Logic Apps that work with Stripe webhooks and I've need to convert Epoch DATETIME into a more useful format." 16 | --- 17 | 18 | Recently, I've been building a handful of Azure Logic Apps that work with Stripe webhooks. 19 | 20 | Stripe will commonly use Epoch time for it's dates. 21 | 22 | But Epoch time is pretty useless for anything that is human-facing, and it's not necessarily the default for a lot of Microsoft solutions. 23 | 24 | I needed a way in Azure Logic Apps to easily convert an Epoch Date into a readable format. 25 | 26 | ## What is Epoch Time? 27 | 28 | [Epoch Time](https://en.wikipedia.org/wiki/Epoch_(computing)) is the number of seconds that have surpassed since Midnight, January 1st, 1970. This is also commonly known as `Unix Epoch`. 29 | 30 | ## Converting 31 | 32 | Converting the time is pretty straight-forward, Epoch time is just the number of seconds since 1970-01-01 and Azure Logic Apps has a handy `addToTime` method we can use. 33 | 34 | ```javascript 35 | addToTime('1970-01-01T00:00:00Z', [EPOCH TIME HERE], 'second') 36 | ``` 37 | 38 | And ta-da! Your Epoch Time is now in a much easier to use format! 39 | 40 | 41 | -------------------------------------------------------------------------------- /blog/20210110-how-to-debug-cssjavascript-mouse-or-hover-events.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to Debug CSS/JavaScript Mouse or Hover Events" 3 | date: 2021-01-11T00:00:00Z 4 | permalink: debug-javascript-css-hover-mouseover-events 5 | description: "How do you debug or style elements that only exist in the DOM during hover or mouse-over events?" 6 | summary: "How do you debug or style elements that only exist in the DOM during hover or mouse-over events?" 7 | tags: 8 | - CSS 9 | - JavaScript 10 | - Debugging 11 | - DOM 12 | - DevTools 13 | categories: 14 | - JavaScript 15 | - CSS 16 | - Web Development 17 | excerpt: "You're working on an issue the requires to debug or style an element on a page that ONLY appears in the course of a hover or mouse-over event. However, when the event is not occurring, the element you want to work with does not exist in the DOM." 18 | --- 19 | 20 | I am writing this post because I often forget about this particular tip. 21 | 22 | Scenario: 23 | > You're working on an issue the requires to debug or style an element on a page that ONLY appears in the course of a hover or mouse-over event. However, when the event is not occurring, the element you want to work with does not exist in the DOM. 24 | 25 | That's a problem, ain't it? 26 | 27 | Here's a great tip I picked up years ago, and I have never documented myself because it's not problem I run into daily. I wish I knew who to attribute this to you. 28 | 29 | To fix this problem, open your DevTools and write the following in the console. 30 | 31 | ```javascript 32 | setTimeout(() => {debugger;}, 5000) 33 | ``` 34 | 35 | Adjust the time accordingly, but you should have 5 seconds to cause the mouse-over or hover event to occur. The debugger will kick in, preventing future updates to the DOM until you continue. 36 | 37 | Yay! You can now inspect the proper elements and make your changes. 38 | 39 | -------------------------------------------------------------------------------- /blog/20161108-exploring-c-70-out-variables.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exploring C# 7.0: Out Variables" 3 | date: 2016-11-08T18:41:48Z 4 | permalink: exploring-csharp70-out-variables 5 | description: "New in C# 7.0 - out variables will save you some time! Learn how to declare variables inline with method calls." 6 | summary: "New in C# 7.0 - out variables will save you some time!" 7 | tags: 8 | - .NET 9 | - dotnet 10 | - C# 11 | - "C# 7.0" 12 | categories: 13 | - "Development - C#" 14 | --- 15 | 16 | Using the out keyword within C# is nothing new. If you declare a variable within a method called with **out**, you are instructing the compile that you are expecting the method to set the values of those at runtime. 17 | 18 | ```csharp 19 | class Program 20 | { 21 | static void Main(string[] args) 22 | { 23 | string firstName; 24 | string lastName; 25 | 26 | CreateName(out firstName, out lastName); 27 | Console.WriteLine($"Hello {firstName} {lastName}"); 28 | } 29 | 30 | private static void CreateName(out string firstName, out string lastName) 31 | { 32 | firstName = "Kevin"; 33 | lastName = "Griffin"; 34 | } 35 | } 36 | ``` 37 | 38 | Commonly the problem is that you have to declare the variable before the method call using out. In C# 7.0, there is the concept of out variables, which will save you a couple keystrokes by allowing you to declare the variable inline. 39 | 40 | The above example can be quickly refactored: 41 | 42 | ```csharp 43 | class Program 44 | { 45 | static void Main(string[] args) 46 | { 47 | // notice I'm declaring the type INSIDE THE CALL! 48 | CreateName(out string firstName, out string lastName); 49 | Console.WriteLine($"Hello {firstName} {lastName}"); 50 | } 51 | 52 | private static void CreateName(out string firstName, out string lastName) 53 | { 54 | firstName = "Kevin"; 55 | lastName = "Griffin"; 56 | } 57 | } 58 | ``` 59 | -------------------------------------------------------------------------------- /docs/SignalR-Mastery.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SignalR Mastery 3 | date: 2021-01-06 12:00:00 4 | permalink: signalr-mastery 5 | categories: 6 | - Courses 7 | excerpt: "Become a SignalR Master with this comprehensive course from Microsoft MVP, Kevin Griffin." 8 | --- 9 | 10 | ![SignalR Mastery](./images/signalr-mastery-thumbnail.png) 11 | 12 | [Get the course](https://www.udemy.com/course/signalr-mastery/learn/?referralCode=5F129296A976F8353B79) 13 | 14 | The web isn't static. As more and more people live and work on the internet, developers need to make an effort to build robust, adaptive applications that can keep up with the fast pace of business. 15 | 16 | In the 2000s, it was perfectly acceptable for a page to be static. Imagine you're working with a product inventory application. Are other people working against the same data? Can you be sure the current price of the product is valid? Did it change? How would you even know? Refresh the page to load updated data and see. 17 | 18 | What if the page could... update itself? In real-time? 19 | 20 | Once upon a time, this was a complicated solution to implement in a performant manner. Today, it's as simple as creating a WebSocket! 21 | 22 | How do you manage thousands or millions of WebSockets across multiple servers? Reliably? What if the environment cannot support a WebSocket connection? What do you fall back to? 23 | 24 | SignalR is a library for .NET which allows developers to add real-time capabilities to their applications. It provides a framework for managing connections from various clients, including web pages, mobile apps, desktop applications, and more. It handles all of the grunt work. 25 | 26 | In this course, we'll take a structured look at how SignalR works and how you can harness it within your .NET applications. 27 | 28 | [Get the course](https://www.udemy.com/course/signalr-mastery/learn/?referralCode=5F129296A976F8353B79) 29 | 30 | -------------------------------------------------------------------------------- /blog/20200407-how-to-run-visual-studio-code-on-mac-osx.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to run Visual Studio Code on Mac OSX" 3 | date: 2020-04-07T13:27:04Z 4 | permalink: how-to-run-visual-studio-code-from-mac-osx 5 | description: "Step-by-step guide to set up Visual Studio Code command line integration for both Terminal and Zsh on macOS." 6 | summary: "Using Visual Studio Code on OSX? Here's how to set up the command line for Zsh or Terminal." 7 | tags: 8 | - Visual Studio Code 9 | - macOS 10 | - Terminal 11 | - Zsh 12 | categories: 13 | - Development 14 | --- 15 | 16 | **EDIT:** [You can just do this from Visual Studio Code now.](https://code.visualstudio.com/docs/setup/mac) 17 | 18 | ## Terminal 19 | 20 | Currently, there isn't an automatic method for doing this, but with a little code in your `~/.bash_profile` file, you can configure it. 21 | 22 | ```bash 23 | code () { VSCODE_CWD="$PWD" open -n -b "com.microsoft.VSCode" --args $* ;} 24 | ``` 25 | 26 | Then from Terminal you can type: 27 | 28 | `code` -- opens Visual Studio Code 29 | `code .` -- opens current directory in Visual Studio Code 30 | `code somefile` -- opens somefile in Visual Studio Code 31 | 32 | 33 | ## Zsh 34 | 35 | Using [Visual Studio Code](https://code.visualstudio.com) on your Mac, but can't call it from Zsh? 36 | 37 | Currently, there isn't an automatic method for doing this, but with a little code in your `.zshrc` file, you can configure it. 38 | 39 | ```zsh 40 | function code { 41 | if [[ $# = 0 ]] 42 | then 43 | open -a "Visual Studio Code" 44 | else 45 | local argPath="$1" 46 | [[ $1 = /* ]] && argPath="$1" || argPath="$PWD/${1#./}" 47 | open -a "Visual Studio Code" "$argPath" 48 | fi 49 | } 50 | ``` 51 | Then from Terminal you can type: 52 | 53 | `code` -- opens Visual Studio Code 54 | `code .` -- opens current directory in Visual Studio Code 55 | `code somefile` -- opens somefile in Visual Studio Code 56 | -------------------------------------------------------------------------------- /blog/20141013-mongodb-setting-ttl-on-documents.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "MongoDB: Setting TTL on Documents" 3 | date: 2014-10-13T14:08:05Z 4 | permalink: mongodb-setting-ttl-on-documents 5 | description: "Learn how to automatically remove MongoDB documents after a specified time period using Time To Live (TTL) indexes." 6 | summary: "Learn how to automatically remove MongoDB documents after a specified time period using Time To Live (TTL) indexes." 7 | tags: 8 | - MongoDB 9 | - Database 10 | - TTL 11 | - NoSQL 12 | categories: 13 | - Development 14 | --- 15 | 16 | On some recent work I was doing with Winsitter, I needed an approach that would systematically remove documents after a specified period of time within MongoDB. 17 | 18 | Previously, I would have written cron jobs or helpers to clean up the old data. No longer! 19 | 20 | Come to discover, this feature [already exists](https://docs.mongodb.com/manual/tutorial/expire-data/) inside of MongoDB. It is called setting the TTL or Time to Live of a document. 21 | 22 | The process involves creating an index on the date object you'd like to watch. In the example below, I am providing a property on my document called `auditDate`. I want the document associated with that property to automatically remove itself after 5 days or *432000000* miliseconds. 23 | 24 | ```javascript 25 | dbConnection 26 | .collection("audit") 27 | .ensureIndex({ 28 | "auditDate": 1 29 | }, { 30 | expireAfterSeconds: 432000000 // 5 days 31 | }, function(indexErr) { 32 | if (indexErr) { 33 | console.log("error creating index"); 34 | console.log(indexErr); 35 | } 36 | }); 37 | ``` 38 | 39 | In the example, I'm using the MongoDB node.js library to ensure an index exists. If the index doesn't exist, MongoDB will create it. 40 | 41 | The `expireAfterSeconds` options tells MongoDB that after a specified amount of time, the document should automatically remove itself. 42 | 43 | This quick fix has saved me a ton of time, and I am hoping it saves a ton for you too! -------------------------------------------------------------------------------- /blog/20150514-no-matter-what-you-do-add-value.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "No matter what you do: add value" 3 | date: 2015-05-14T11:38:29Z 4 | permalink: no-matter-what-you-do-add-value 5 | description: "Always strive to add value in your interactions, whether with clients, colleagues, or potential business opportunities." 6 | summary: "Always strive to add value in your interactions, whether with clients, colleagues, or potential business opportunities." 7 | tags: 8 | - Consulting 9 | - Business 10 | - Mentoring 11 | - Professional Development 12 | categories: 13 | - Deep Thoughts 14 | --- 15 | 16 | Yesterday I had the pleasure of chatting with a gentleman about a potential mentoring gig. The way I like to approach these sort of talks is to determine high level goals. In this case, the client was looking for someone to be a set of expert eyes on a codebase. He is certainly a capable developer, but he's also aware enough to know when he has hit a roadblock. 17 | 18 | We were connected by the work and training I've done with SignalR and ASP.NET, which would prove especially useful in this situation. 19 | 20 | The client discussed the issues he was running into and the thoughts he had around solutions. Normally, this is where you will have the instinct to want to hold off providing guidance. You're the expert. This what people should be paying you for! 21 | 22 | > Always try to add some value. 23 | 24 | That's not how I reacted though. Instead, I spent 10 minute giving my potential-client two or three *free* tips and tricks on what he should explore. Sometimes the simplest tip is all a person needs to push forward. 25 | 26 | The underlying point is that no matter what you do, **always try to add some value**. If my tips bring him to an epiphany, then I have automatically reaffirmed that I am an expert. This could lead to mentoring and other potential work. It could lead to referrals. 27 | 28 | Approach all your interactions as a chance to provide value to someone. It will pay back dividends! -------------------------------------------------------------------------------- /blog/20121102-preloading-multiple-audio-tags-in-internet-explorer-9.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Preloading Multiple Audio Tags in Internet Explorer 9" 3 | date: 2012-11-02T06:00:59Z 4 | permalink: preloading-multiple-audio-tags-in-internet-explorer-9 5 | description: "Learn how to preload multiple audio files in Internet Explorer 9, including workarounds for IE's limitations with HTML5 audio preloading." 6 | summary: "Learn how to preload multiple audio files in Internet Explorer 9, including workarounds for IE's limitations with HTML5 audio preloading." 7 | tags: 8 | - HTML5 9 | - Audio 10 | - Internet Explorer 11 | - JavaScript 12 | categories: 13 | - Development 14 | --- 15 | 16 | I had a unique problem.  I have an app I'm working on where I needed to preload about 50 audio files for use during the page's lifetime.  If you're up on your HTML5-fu, this is a simple task: 17 | 18 | ```html 19 | 23 | ``` 24 | 25 | In Chrome, this works PERFECTLY (as it should). 26 | 27 | In Internet Explorer, several (if not all) files will fail to preload.  Here's how to figure it: 28 | 29 | ```javascript 30 | var audioElement = document.getElementById("myAudio"); 31 | console.log(audioElement.networkState); 32 | ``` 33 | 34 | Network state can have 3 options: NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE. 35 | 36 | You "want" it to be IDLE, because that means the file is loaded.  Typically, you'll get NO_SOURCE with Internet Explorer. 37 | 38 | What's a quick fix?  First, make sure there is no preload attribute, and then do this: 39 | 40 | ```javascript 41 | var audioElement = document.getElementById("myAudio"); 42 | audioElement.load(); // kicks off the load 43 | ``` 44 | 45 | This has worked for me in 100% of the tests I've done tonight.  Feel free to comment on other solutions.  I haven't tested in IE10 yet, so I cannot be certain of how it works. 46 | -------------------------------------------------------------------------------- /blog/20150723-paying-attention.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Paying Attention" 3 | date: 2015-07-23T06:43:54Z 4 | permalink: paying-attention 5 | description: "Don't assume. Pay attention. A lesson learned from a simple timezone mix-up during remote training." 6 | summary: "Don't assume. Pay attention." 7 | tags: 8 | - Communication 9 | - Remote Work 10 | - Lessons Learned 11 | - Professional 12 | categories: 13 | - Deep Thoughts 14 | --- 15 | 16 | Last week I did a training gig for a great group of folks out on the west coast. I worked from the comfort of my home office, and presented all the material remotely. 17 | 18 | The spec for training was pretty straightforward: start at 9am and end at 5pm for three days. The timezone was for Pacific Time, since the majority of the group resided in that timezone. 19 | 20 | This week, I did a training for the same company but with a different group of people. Monday morning I woke up bright and early to an email wondering why I was a no-show to the training. Of course, I was barely out of bed and hadn't had my coffee yet. I'm an east coaster, so 9am Pacific Time would've been noon local time. Training didn't start for a few hours. 21 | 22 | I quickly reviewed my spec, and I saw it plain as day: 9am to 5pm. What was I missing? 23 | 24 | Central European Time. Or better known as 3am to east coasters. YIKES! I was a no show. 25 | 26 | The moral of the story is that we need to start paying better attention. Too often do we get lost in the small details or we simply assume too much. For me, I assumed since the first training was Pacific Time Zone that the second one was Pacific Time Zone as well. Heck, I even checked the spec! But I only checked the times, and completely overlooked the different timezone. A 9 hour mistake. 27 | 28 | Luckily for me, the client was understanding and we pushed the training another day. 29 | 30 | Have you ever had a moment where your assumptions got the best of you? Minute details completely escaped you even though you were staring right at them? I'd love to hear about it! Leave me a comment and let us share the pain together. -------------------------------------------------------------------------------- /.github/workflows/azure-static-web-apps-yellow-forest-0e8e9d20f.yml: -------------------------------------------------------------------------------- 1 | name: Azure Static Web Apps CI/CD 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | types: [opened, synchronize, reopened, closed] 9 | branches: 10 | - master 11 | 12 | jobs: 13 | build_and_deploy_job: 14 | if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') 15 | runs-on: ubuntu-latest 16 | name: Build and Deploy Job 17 | steps: 18 | - name: Setup Node.js for use with actions 19 | uses: actions/setup-node@v4 20 | with: 21 | # Version Spec of the version to use. Examples: 10.x, 10.15.1, >=10.15.0, lts 22 | node-version: 20 23 | 24 | - uses: actions/checkout@v6 25 | 26 | - name: YARN install 27 | run: yarn install 28 | 29 | - name: Install Gridsome 30 | run: yarn global add @gridsome/cli 31 | 32 | - name: Gridsome Build 33 | run: yarn run build 34 | 35 | - name: Build And Deploy 36 | id: builddeploy 37 | uses: Azure/static-web-apps-deploy@v1 38 | env: 39 | DISABLE_NODEJS_BUILD: true 40 | with: 41 | azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_YELLOW_FOREST_0E8E9D20F }} 42 | repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) 43 | action: 'upload' 44 | ###### Repository/Build Configurations - These values can be configured to match you app requirements. ###### 45 | app_location: '/dist' # App source code path 46 | ###### End of Repository/Build Configurations ###### 47 | 48 | close_pull_request_job: 49 | if: github.event_name == 'pull_request' && github.event.action == 'closed' 50 | runs-on: ubuntu-latest 51 | name: Close Pull Request Job 52 | steps: 53 | - name: Close Pull Request 54 | id: closepullrequest 55 | uses: Azure/static-web-apps-deploy@v1 56 | with: 57 | azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_YELLOW_FOREST_0E8E9D20F }} 58 | action: 'close' 59 | -------------------------------------------------------------------------------- /docs/Consulting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Consulting 3 | date: 2017-05-03 12:50:43 4 | permalink: consulting 5 | categories: 6 | - Misc 7 | excerpt: "I'm available for hire! Let's chat" 8 | --- 9 | 10 | I am actively available to short term consulting engagements. 11 | What are some ways that we can engage with each other? 12 | 13 | ### ASP.NET Core Architecture and Implementation 14 | 15 | As a 16-time Microsoft MVP, my primary focus and enjoyment comes from designing and implementing solutions built on top of ASP.NET Core. I have worked with several clients to modernize their applicaitons on ASP.NET Core, as I feel it is one of the best solutions on the market for building and maintaining scalable, flexible, and performant web applications. 16 | 17 | ### Microsoft Azure Architecture and Implementation 18 | 19 | In the current age of cloud-based applications, it is important to choose a provider that will ensure your applications and services are running at top performance - all the time. For over ten years, I have supported clients on top of Microsoft Azure. I would love to work with your team to design or implement a strategy for adding Microsoft Azure to your technical stack. 20 | 21 | ### Web Development Architecture and Implementation 22 | 23 | In addition to the work I've done on building scalable ASP.NET Core applications, I have spent a good amount of time building and improving web applications. While I'm currently in love with Vue.JS, I'm well versed in other client side technologies such as React and Angular. Heck, if you want to go old-school, I loved me some jQuery back in the 2000's. 24 | 25 | ### Application Modernization 26 | 27 | If you stop and blink, technology is changing before your eyes! I have worked with several clients on modernization projects to bring their tech stacks forward to something that is maintainable for the next several years. 28 | 29 | ### Performance Optimization 30 | 31 | Another core aspect of the consulting work I've done is focused on performance. Sometimes it's easy to lose track of the bigger picture when developing application, and before you know it your servers are pegged and pages take minutes to load. 32 | 33 | ## Let's Connect! 34 | 35 | [Book a consultation](https://app.onecal.io/b/kevin-griffin/chat) to discuss your needs, or shoot me an [email](mailto:connect@consultwithgriff.com) with a little information about your needs, and I'll respond with availability and a rate sheet. 36 | -------------------------------------------------------------------------------- /blog/20150306-managing-your-user-group-calendar-roulette.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Managing Your User Group: Calendar Roulette" 3 | date: 2015-03-06T22:39:16Z 4 | permalink: calendar-roulette 5 | description: "Learn why consistency in scheduling is crucial for user group success and how to choose the right meeting day for maximum attendance." 6 | summary: "If you're running a community, pick a day and stick with it!" 7 | tags: 8 | - User Groups 9 | - Community Management 10 | - Scheduling 11 | - Leadership 12 | categories: 13 | - Community, User Groups, and Conferences 14 | --- 15 | 16 | One trait of successful user groups is don't play calendar roulette. Meaning: they chose a time or day each month to hold the group meeting. 17 | 18 | > We meet every 2nd Tuesday. 19 | 20 | or 21 | 22 | > We are the last Thursday of the month. 23 | 24 | Why is this important? 25 | ***You want your members to be able to determine meeting dates based off a quick glance of a calendar.*** 26 | Consistency is key. If your meetings are in different venues or different days of the month, you're chancing that someone will forget and not be in attendance. 27 | 28 | **What's a good night for meetings?** 29 | With the Hampton Roads .NET Users Group, I chose the 2nd Tuesday of the month. Why? Because I felt Tuesdays were a better for my schedule. Only once in a 5 year period did I change the meeting. 30 | 31 | My recommendation is to choose a Tuesday, Wednesday, or Thursday. Mondays are bad for folks because it's the first day back to work after a short weekend. Fridays are bad because, dude, it's the weekend. PARTY TIME. 32 | 33 | Be careful with Wednesdays as well. Many church functions occur on Wednesday nights, and that might be limiting a percentage of your population. 34 | 35 | **When is it okay to move the meeting?** 36 | Let's imagine you have a speaker coming into town that's "a big deal". But they're only able to meeting on Wednesday night, and your meetings are Tuesdays. MOVE THE MEETING. Make sure the change is well communicated, and that it's temporary. You might lose attendance that month, but people are adaptable. Just don't make it a habit. 37 | 38 | **Conclusion** 39 | Keep scheduling simple. Hampton Roads .NET members knew where to go and when to be there every month of the year. If you build a level of consistency, you're going to have people showing up out of habit, and that's a recipe for a successful group. 40 | 41 | 42 | -------------------------------------------------------------------------------- /blog/20160324-the-10-rule-to-presentations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "The 10% Rule to Presentations" 3 | date: 2016-03-24T09:18:59Z 4 | permalink: the-10-rule-to-presentations 5 | description: "A presentation strategy for technical speakers: aim to give your audience 10% of your knowledge on a subject to build foundations for learning." 6 | summary: "When mentoring new technical speakers, I like to cite what I call 'the 10% rule'." 7 | tags: 8 | - public speaking 9 | - presentations 10 | - technical speaking 11 | - mentoring 12 | categories: 13 | - Deep Thoughts 14 | --- 15 | 16 | When mentoring new technical speakers, I like to cite what I call "the 10% rule". 17 | 18 | Think about it like this: If you are presenting on a 100-level topics (for example, "Intro to Angular" or "Building Your First App with Elixir"), you can safely assume that your audience is one of three types people. 19 | 20 | **First**, they are an absolute newbie who is there because they heard about this technology but have practically no experience with it. 21 | 22 | **Second**, they have been to previous talks on the subject or have read a couple tutorials. They are not starting at "ground-zero", but they are darn close. 23 | 24 | **Third**, they are seasoned or beyond 100-level, and they are looking to see if you offer new perspective. 25 | 26 | The 10% rule applies to the first two groups. Your job as the presenter is to try to leave the audience with 10% of the knowledge you have on a subject. 27 | 28 | Ten percent sound like a lot, right? Doesn't have to be. For most developers, this is seeing how pieces lay together or how do you do something from scratch. 29 | 30 | Ten percent might simply be "what problem does the thing I'm showing you solve?" 31 | 32 | My first set of presentations were around jQuery (2007 era). My intro talks discussed manipulating the DOM and listening for events. I'd discuss the "hard" way, but then showed how easy jQuery made it. 33 | 34 | If you're adventuring into 200 or 300-level talks, the same 10% rule can apply. Imagine you want to do a talk on "new C# features". Your expectation is that the audience is familiar with C#. Your 10% is going to be a simple list of what is new, with basic explanations. 35 | 36 | If the attendee goes home and runs into a scenario where a new feature would be useful, you have provided them with the foundation to research more. 37 | 38 | The 10% rule is meant to build foundations for learning. Expose audiences to ideas and concepts, and guide them towards better self-learning. 39 | -------------------------------------------------------------------------------- /_README.md: -------------------------------------------------------------------------------- 1 | # Gridsome Portfolio Starter 2 | 3 | A simple portfolio starter theme for Gridsome 4 | 5 | ![screenshot](https://user-images.githubusercontent.com/4316355/55691365-a2403380-596b-11e9-93be-05b846ec7760.jpg) 6 | 7 | ## Demo URL 8 | 9 | [https://gridsome-portfolio-starter.netlify.com](https://gridsome-portfolio-starter.netlify.com) 10 | 11 | ## Features 12 | 13 | - Clean and minimal design 14 | - [Tailwind CSS v1](https://tailwindcss.com) (with PurgeCSS) 15 | - Scroll to sections using [vue-scrollto](https://github.com/rigor789/vue-scrollto) 16 | - Blog with markdown content for posts 17 | - Documentation type that shows how to use Vue components in Markdown (click Docs) 18 | - Theme Switcher with Dark Mode 19 | - Search posts with [Fuse.js](https://fusejs.io) and [vue-fuse](https://github.com/shayneo/vue-fuse) 20 | - Tags for posts 21 | - Basic pagination 22 | - Syntax highlighting with [Shiki](https://shiki.matsu.io) (using [this gridsome plugin](https://gridsome.org/plugins/gridsome-plugin-remark-shiki)) 23 | - 404 Page 24 | - RSS Feed 25 | - Sitemap in XML 26 | 27 | ## Installation 28 | 29 | 1. Install Gridsome CLI tool if you don't have it: `npm install --global @gridsome/cli` 30 | 1. Clone the repo: `git clone https://github.com/drehimself/gridsome-portfolio-starter.git` 31 | 1. `cd gridsome-portfolio-starter` 32 | 1. `npm install` 33 | 1. `gridsome develop` to start a local dev server at `http://localhost:8080` 34 | 35 | ## Notes 36 | 37 | - Based on my [personal portfolio website](https://andremadarang.com). I wanted to create an open source version with more features. 38 | - Check out a [screencast I did](https://www.youtube.com/watch?v=uHo6o1TNQeE) where I go through the process of building my website. 39 | - Illustrations from [unDraw](https://undraw.co) 40 | - Search is based on [Fuse.js](https://fusejs.io) and [vue-fuse](https://github.com/shayneo/vue-fuse). It only searches the title and summary of posts for now. Some tweaking may be necessary to get it to search to your liking. Check out the fuse documentation for search settings. A `search.json` index file is generated at build time. This happens in `gridsome.server.js`. 41 | - Check out these other Gridsome Starters where I got some ideas from: 42 | - [Gridsome Starter Blog](https://github.com/gridsome/gridsome-starter-blog) 43 | - [Gridsome Starter Bleda](https://github.com/cossssmin/gridsome-starter-bleda) 44 | - [Jigsaw Starter Blog](https://jigsaw.tighten.co/docs/starter-templates/) - I got a lot of design inspiration from this starter theme. 45 | -------------------------------------------------------------------------------- /gridsome.server.js: -------------------------------------------------------------------------------- 1 | // Server API makes it possible to hook into various parts of Gridsome 2 | // on server-side and add custom data to the GraphQL data layer. 3 | // Learn more: https://gridsome.org/docs/server-api 4 | 5 | // Changes here require a server restart. 6 | // To restart press CTRL + C in terminal and run `gridsome develop` 7 | 8 | const fs = require('fs'); 9 | const path = require('path'); 10 | const pick = require('lodash.pick'); 11 | const { pathPrefix } = require('./gridsome.config'); 12 | 13 | module.exports = function (api, options) { 14 | 15 | api.loadSource(store => { 16 | /* 17 | Clean the pathPrefix 18 | ==================== 19 | not used => '/' 20 | '' => '/' 21 | '/' => '/' 22 | '/path' => '/path' 23 | 'path' => '/path' 24 | 'path/' => '/path' 25 | '/path/' => '/path' 26 | */ 27 | const cleanedPathPrefix = `${pathPrefix ? ['', ...pathPrefix.split('/').filter(dir => dir.length)].join('/') : ''}` 28 | 29 | /* 30 | Query 31 | ===== 32 | 33 | { 34 | metaData{ 35 | pathPrefix 36 | } 37 | } 38 | 39 | 40 | Requests for static files should look like this: 41 | =============================================== 42 | Using static-queries: axios( this.$static.metaData.pathPrefix + "/fileName" ) 43 | Using page-queries, axios( this.$page.metaData.pathPrefix + "/fileName" ) 44 | */ 45 | store.addMetadata('pathPrefix', cleanedPathPrefix) 46 | }); 47 | 48 | api.beforeBuild(({ config, store }) => { 49 | 50 | // Generate an index file for Fuse to search Posts 51 | const { collection } = store.getContentType('Post'); 52 | 53 | const posts = collection.data.map(post => { 54 | return pick(post, ['title', 'path', 'summary']); 55 | }); 56 | 57 | const output = { 58 | dir: './static', 59 | name: 'search.json', 60 | ...options.output 61 | } 62 | 63 | const outputPath = path.resolve(process.cwd(), output.dir) 64 | const outputPathExists = fs.existsSync(outputPath) 65 | const fileName = output.name.endsWith('.json') 66 | ? output.name 67 | : `${output.name}.json` 68 | 69 | if (outputPathExists) { 70 | fs.writeFileSync(path.resolve(process.cwd(), output.dir, fileName), JSON.stringify(posts)) 71 | } else { 72 | fs.mkdirSync(outputPath) 73 | fs.writeFileSync(path.resolve(process.cwd(), output.dir, fileName), JSON.stringify(posts)) 74 | } 75 | }) 76 | } 77 | -------------------------------------------------------------------------------- /blog/20151013-managing-your-user-group-food.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Managing Your User Group: Food" 3 | date: 2015-10-13T18:45:40Z 4 | permalink: user-group-food 5 | description: "Creative alternatives to pizza and sandwiches for user group meetings that will make your sponsors memorable and attendees happy." 6 | summary: "If you run a community, add some variety to your food choices." 7 | tags: 8 | - User Groups 9 | - Community Management 10 | - Event Planning 11 | - Sponsorship 12 | categories: 13 | - Community, User Groups, and Conferences 14 | --- 15 | 16 | *Edit: Based off some comments, I've included options for non-lovers of meat. Also added other comments.* 17 | 18 | For a lot of user groups, food depends highly on the sponsor for the month. 19 | 20 | Let's keep this short and sweet: Sponsors. If your instinct is to order pizza for a user group meeting, your attendees already hate you. 21 | 22 | Think about it this way. A lot of people have an opportunity to sponsor a group. You want to be memorable. Pizza is not memorable. 23 | 24 | And you know what else? Sandwiches. This is the new pizza. If you think you're being clever and different by providing Jimmy Johns instead of pizza, your attendees hate you too. 25 | 26 | What could you do instead of pizza? What food would make your company memorable? Here are some ideas: 27 | 28 | **Chipotle** - When I spoke at Richmond .NET in October 2015, MaconIT brought Chiptole burritos. I'm talking about a *box of freakin burritos*. 29 | 30 | **Taco Bar** - Taco bars are fun, and they allow attendees to choose their own mexican adventure. 31 | 32 | **Chick-Fil-A** - Nugget tray. Enough said. 33 | 34 | **PF Changs** - How about some asian flair? Try a mini-buffet of PF Changs favorites. 35 | 36 | **BBQ Buffet** - Pulled pork, beans, coleslaw. Depending on the location, you can get a BBQ buffet for the same price as pizza for a group. 37 | 38 | **Veggie/Vegan Options** - I know, I know. The food above is all mostly of the animal protein category. Please don't forget people that don't eat meat. Salad choices and veggies go a long way. You'd be really surprised how many card-carrying meat eaters will dive into healthy choices. Not sure what Vegan's would eat? Ask one. They'd be more than happy to give you a couple dozen options. 39 | 40 | Don't get me wrong, pizza is awesome. Pizza in EXCESS is horrible (and to be fair, if you brought Chick-Fil-A every meeting -- that would probably get old too). Be good to your groups and don't buy pizza (or sandwiches). Look for creative alternatives. Attendees will love you. -------------------------------------------------------------------------------- /.github/workflows/claude.yml: -------------------------------------------------------------------------------- 1 | name: Claude Code 2 | 3 | on: 4 | issue_comment: 5 | types: [created] 6 | pull_request_review_comment: 7 | types: [created] 8 | issues: 9 | types: [opened, assigned] 10 | pull_request_review: 11 | types: [submitted] 12 | 13 | jobs: 14 | claude: 15 | if: | 16 | (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || 17 | (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || 18 | (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || 19 | (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) 20 | runs-on: ubuntu-latest 21 | permissions: 22 | contents: read 23 | pull-requests: read 24 | issues: read 25 | id-token: write 26 | actions: read # Required for Claude to read CI results on PRs 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v6 30 | with: 31 | fetch-depth: 1 32 | 33 | - name: Run Claude Code 34 | id: claude 35 | uses: anthropics/claude-code-action@beta 36 | with: 37 | claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} 38 | 39 | # This is an optional setting that allows Claude to read CI results on PRs 40 | additional_permissions: | 41 | actions: read 42 | 43 | # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1) 44 | # model: "claude-opus-4-1-20250805" 45 | 46 | # Optional: Customize the trigger phrase (default: @claude) 47 | # trigger_phrase: "/claude" 48 | 49 | # Optional: Trigger when specific user is assigned to an issue 50 | # assignee_trigger: "claude-bot" 51 | 52 | # Optional: Allow Claude to run specific commands 53 | # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)" 54 | 55 | # Optional: Add custom instructions for Claude to customize its behavior for your project 56 | # custom_instructions: | 57 | # Follow our coding standards 58 | # Ensure all new code has tests 59 | # Use TypeScript for new files 60 | 61 | # Optional: Custom environment variables for Claude 62 | # claude_env: | 63 | # NODE_ENV: test 64 | 65 | -------------------------------------------------------------------------------- /src/pages/Articles.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 43 | query Posts ($page: Int) { 44 | posts: allPost (sortBy: "date", order: DESC, perPage: 10, page: $page) @paginate { 45 | totalCount 46 | pageInfo { 47 | totalPages 48 | currentPage 49 | } 50 | edges { 51 | node { 52 | id 53 | title 54 | date (format: "MMMM D, Y") 55 | summary 56 | excerpt 57 | timeToRead 58 | path 59 | } 60 | } 61 | } 62 | } 63 | 64 | 65 | 92 | 93 | -------------------------------------------------------------------------------- /blog/20090206-a-diet-programmers-can-relate-to.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "A Diet Programmers Can Relate To" 3 | date: 2009-02-06T06:52:21Z 4 | permalink: a-diet-programmers-can-relate-to 5 | description: "I gave Weight Watchers a try, and it was pretty cool! Learn how the Weight Watchers point system works like a programming algorithm." 6 | summary: "I gave Weight Watchers a try, and it was pretty cool! Learn how the Weight Watchers point system works like a programming algorithm." 7 | tags: 8 | - Health 9 | - Programming 10 | - Weight Watchers 11 | - Personal Development 12 | categories: 13 | - Health 14 | --- 15 | 16 | Consider this: programmers are typically overweight.  It's our nature.  Ninety-five percent of our job is sitting behind a desk and hacking at a keyboard.  The most movement we get is walking to the bathroom, and going to our car to go to the drive thru. 17 | 18 | About a month ago, I was turned onto the Weight Watchers plan, and it immediately occurred to me that this is the perfect diet plan for developers.  Here is the gist of the plan:  You're allotted x number of points a day.  Points come from the foods and drinks you put into your body.  The number of points you're allowed is based on your gender, weight, height, and activity level. 19 | 20 | The points in a piece of food is determined by the number of calories, total fat, and fiber content of the food.  Anyone that pays to join Weight Watchers is given a calculator for determining the points.  In reality, it's just an equation.  Developers like equations.  We can understand equations.  Here is the equation for Weight Watchers Points: 21 | 22 | POINTS = (Calories / 50) + (Total Fat / 12) - (MIN(Fiber, 4) / 5) 23 | 24 | Ooooh.  That could easily be plugged into a script.  How does this fit into the real world?  My number of points allotted per day is 39.  There is a formula for figuring that out, but I've been unable to find it.  If/when I do, I'll post it here.  But for the record, I'm 6'1, 259 pounds and sit at a desk all day.  If you weigh more than I do, add 1 point per 10 pound increment (260 pounds is technically 40 points).  If you weight less, subtract 1 point per 10 pound increment.  If you are taller than me, add a point or two.  If you're shorter, subtract a point or two.  You should see what I mean. 25 | 26 | Say I go to Burger King, and buy a Whopper with cheese.  That weighs in at 19 pounds (the mayo kills it).  After eating a Whopper, I've already had half my number of points for the day.  Weight Watchers says that's cool, but be careful with your other 20 points.  You still eat what you want, just eat less of it and try to find better alternatives. 27 | 28 | So now you can do the Weight Watchers plan for free.  Use the points equation to do whatever you want.  Lose weight mathematically! -------------------------------------------------------------------------------- /blog/20100119-are-we-too-dependent-on-the-internet.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Are we too dependent on the Internet?" 3 | date: 2010-01-19T06:00:00Z 4 | permalink: are-we-too-dependent-on-the-internet 5 | description: "Exploring our dependency on the internet and how it affects our productivity and learning capabilities when we lose connectivity." 6 | summary: "Does the internet make us stronger, or is it making us weaker?" 7 | tags: 8 | - Deep Thoughts 9 | categories: 10 | - Deep Thoughts 11 | --- 12 | 13 | In my office, there lives a monster. This monster is called “The Internet Killer,” and he likes to poke his head out every now. When he does, our internet goes down for hours upon hours. During this time, I still have work too do, but I often find that my production level is limited by the lack of internet. 14 | 15 | **Are we too dependent on the Internet?** 16 | 17 | I’m in that weird generation where I have had access to the Internet for most of my life, but I can still remember not having it. I have used a card catalog. I have used an encyclopedia. I have had to retain knowledge for more than a few minutes. 18 | 19 | This was also around the time I started learning how to program. My first few BASIC applications were self taught from a help file. I didn’t have an Internet to go to whenever I ran into a problem. I was forced to either figure it out on my own, or travel to the library to reference whatever material (if they had any material at all). Having to work through these issues forced me to retain knowledge for an extended period of time. You never knew when you were going to have use what you had learned before. 20 | 21 | Fast forward to today. I’m working on a few features for a project, and we lose our internet. You might be saying, “Kevin, you should be able to code just fine without the internet.” And you are right, I should be able to. However, if you’re venturing into territory that you’re not familiar with, your work is either going to take two or three times as long as it would had you had access to reference materials. 22 | 23 | “Have you ever heard of books?” Yes, and I have plenty of them. Books are hard to reference. Books are awful for troubleshooting problems. Can you type an error string or code into a book? How long does it take to find a book that might have the information you’re looking for? Does it actually contain information that is useful, or just code snippets that is causing the error you have? 24 | 25 | Google (Bing, or whatever you use) is fast, accurate (for the most part), and easily accessible. The “whole world at your fingertips” is no joke. Within minutes, I have access to references, books, blogs, forums, etc. Your problem is never new, and the Internet is quick to provide answers. 26 | 27 | Does the internet make us stronger, or is it making us weaker? I’ll let you decide. 28 | -------------------------------------------------------------------------------- /src/templates/Tag.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 46 | query Tag ($id: ID!, $page: Int) { 47 | tag: tag (id: $id) { 48 | title 49 | path 50 | belongsTo (page: $page, perPage: 3) @paginate { 51 | totalCount 52 | pageInfo { 53 | totalPages 54 | currentPage 55 | } 56 | edges { 57 | node { 58 | ...on Post { 59 | title 60 | timeToRead 61 | date (format: "MMMM D, YYYY") 62 | path 63 | summary 64 | tags { 65 | title 66 | } 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | 75 | 101 | -------------------------------------------------------------------------------- /src/templates/Post.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 17 | query Post ($path: String!) { 18 | post: post (path: $path) { 19 | title 20 | date (format: "MMMM D, Y") 21 | path 22 | summary 23 | content 24 | excerpt 25 | timeToRead 26 | image 27 | tags { 28 | title 29 | path 30 | } 31 | } 32 | } 33 | 34 | 35 | 82 | 83 |