Commit 0267de2
Release v2.2.0 (#68)
* chore: sync develop with main after v2.1.0 release (#58)
* hotfix: enable Terraform deployment by making attestation non-blocking (#31)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile from Terraform backend (#32)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to Terraform backend for Spaces access (#33)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported Terraform volume block (#34)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported volume block from Terraform DigitalOcean App
DigitalOcean App Platform does not support volume mounts for services.
Removed the volume block to allow terraform validate to pass. SQLite database
will use ephemeral storage within the container.
* feature: add managed PostgreSQL for persistent storage (#35)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported volume block from Terraform DigitalOcean App
DigitalOcean App Platform does not support volume mounts for services.
Removed the volume block to allow terraform validate to pass. SQLite database
will use ephemeral storage within the container.
* feature: add managed PostgreSQL database for persistent storage
Replaced ephemeral SQLite with DigitalOcean Managed PostgreSQL:
- Added digitalocean_database_cluster resource (db-s-1vcpu-1gb, /month)
- Connected database to App Platform app
- Updated Prisma schema from SQLite to PostgreSQL provider
- Updated Terraform outputs to show database connection details
- DATABASE_URL will be automatically injected by App Platform
This provides non-ephemeral, managed, and reliable database storage.
* bugfix: pass github_api_token variable to Terraform plan (#36)
Terraform plan was hanging waiting for github_api_token variable input.
Added -var flag to pass the GH_API_TOKEN secret to the terraform plan command.
* bugfix: fix DigitalOcean App registry credentials format (#37)
* bugfix: pass github_api_token variable to Terraform plan
Terraform plan was hanging waiting for github_api_token variable input.
Added -var flag to pass the GH_API_TOKEN secret to the terraform plan command.
* bugfix: fix DigitalOcean App registry credentials format
Removed unused digitalocean_container_registry_docker_credentials resource
which was trying to access a non-existent DigitalOcean registry.
Fixed registry_credentials format from var.github_token to
username:token format required by DigitalOcean App Platform for GHCR.
* chore: trigger deployment with public GHCR package (#38)
* bugfix: use main tag for Docker image in Terraform (#39)
* chore: trigger deployment with public GHCR package
* bugfix: use main tag instead of latest for Docker image
The workflow creates the 'main' tag for pushes to main branch,
not 'latest' (which only gets created for the default branch).
Updated Terraform to reference the correct tag.
* bugfix: copy Prisma engines in Docker production stage (#41)
* chore: trigger deployment with public GHCR package
* bugfix: copy Prisma engines in Docker production stage
The Docker container was failing with PrismaClientInitializationError because
the query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
was not being copied to the production stage.
Now explicitly copying:
- node_modules/.prisma (contains query engine binaries)
- src/generated/prisma (contains Prisma Client)
This ensures Prisma can locate the query engine at runtime in Alpine Linux.
* bugfix: keep Prisma generated files in production Docker stage (#42)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* hotfix: resolve NG0401 and Auth0 SSR errors (#43)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output (#44)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output
Use live_url directly instead of prepending https:// to default_ingress which already contains the protocol
* bugfix: explicitly set DATABASE_URL environment variable (#45)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output
Use live_url directly instead of prepending https:// to default_ingress which already contains the protocol
* bugfix: explicitly set DATABASE_URL environment variable
Add explicit DATABASE_URL env var pointing to PostgreSQL cluster URI
as a SECRET type to ensure the database connection is properly configured
* bugfix: fix E2E tests for v2.0.0 (#46)
* chore: trigger deployment with public GHCR package
* bugfix: fix E2E tests for v2.0.0
- Re-enable E2E tests in GitHub workflow (Chromium only)
- Configure Playwright to only use Chromium project by default
- Fix accessibility test to check for h1 instead of removed #intro element
- Fix navigation tests to use .first() for duplicate links (nav + homepage CTAs)
- Fix auth test to handle Auth0 redirects properly
- All 20 E2E tests now passing
* feature: simplify navigation bar (#47)
* chore: trigger deployment with public GHCR package
* feature: simplify navigation bar
- Remove Admin link from navbar (accessible via login button)
- Reorder navigation links for better UX (Home > Resume > Projects > Articles > Github)
- Update login button to navigate to /admin page instead of triggering Auth0 directly
- Auth guard on /admin will trigger Auth0 login when needed
- Maintains clean, single-row navigation on desktop
* hotfix: remove deprecated Husky v10 lines from post-checkout hook (#51)
* Release v2.0.1 (#52)
* chore(deps): bump vite and @angular-devkit/build-angular (#30)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) to 7.1.11 and updates ancestor dependency [@angular-devkit/build-angular](https://github.com/angular/angular-cli). These dependencies need to be updated together.
Updates `vite` from 7.1.5 to 7.1.11
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.1.11/packages/vite)
Updates `@angular-devkit/build-angular` from 18.2.12 to 20.3.9
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.2.12...20.3.9)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 7.1.11
dependency-type: indirect
- dependency-name: "@angular-devkit/build-angular"
dependency-version: 20.3.9
dependency-type: direct:development
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* bugfix: update E2E tests for v2.0.0 redesign and re-enable in CI (#40)
Fixed E2E test failures after v2.0.0 homepage and navigation redesign:
- Updated accessibility.spec.ts to check for h1 instead of non-existent #intro
- Fixed navigation.spec.ts strict mode violations for Resume/Projects links
- Updated navigation test to check for auth-button component instead of login button
- Fixed auth.spec.ts admin redirect test to handle Auth0 redirects properly
- Re-enabled E2E tests in GitHub Actions workflow
All E2E tests now pass locally.
* docs: add Git Flow workflow cursor rule (#48)
Add comprehensive Cursor rule documenting the Git Flow branching strategy:
- Feature/bugfix branches must merge to develop
- Only release/hotfix branches merge to main
- Clear examples and workflow for each branch type
- Prevents future mistakes of merging directly to main
* chore: sync develop with main branch (#49)
* hotfix: enable Terraform deployment by making attestation non-blocking (#31)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile from Terraform backend (#32)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to Terraform backend for Spaces access (#33)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported Terraform volume block (#34)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported volume block from Terraform DigitalOcean App
DigitalOcean App Platform does not support volume mounts for services.
Removed the volume block to allow terraform validate to pass. SQLite database
will use ephemeral storage within the container.
* feature: add managed PostgreSQL for persistent storage (#35)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported volume block from Terraform DigitalOcean App
DigitalOcean App Platform does not support volume mounts for services.
Removed the volume block to allow terraform validate to pass. SQLite database
will use ephemeral storage within the container.
* feature: add managed PostgreSQL database for persistent storage
Replaced ephemeral SQLite with DigitalOcean Managed PostgreSQL:
- Added digitalocean_database_cluster resource (db-s-1vcpu-1gb, /month)
- Connected database to App Platform app
- Updated Prisma schema from SQLite to PostgreSQL provider
- Updated Terraform outputs to show database connection details
- DATABASE_URL will be automatically injected by App Platform
This provides non-ephemeral, managed, and reliable database storage.
* bugfix: pass github_api_token variable to Terraform plan (#36)
Terraform plan was hanging waiting for github_api_token variable input.
Added -var flag to pass the GH_API_TOKEN secret to the terraform plan command.
* bugfix: fix DigitalOcean App registry credentials format (#37)
* bugfix: pass github_api_token variable to Terraform plan
Terraform plan was hanging waiting for github_api_token variable input.
Added -var flag to pass the GH_API_TOKEN secret to the terraform plan command.
* bugfix: fix DigitalOcean App registry credentials format
Removed unused digitalocean_container_registry_docker_credentials resource
which was trying to access a non-existent DigitalOcean registry.
Fixed registry_credentials format from var.github_token to
username:token format required by DigitalOcean App Platform for GHCR.
* chore: trigger deployment with public GHCR package (#38)
* bugfix: use main tag for Docker image in Terraform (#39)
* chore: trigger deployment with public GHCR package
* bugfix: use main tag instead of latest for Docker image
The workflow creates the 'main' tag for pushes to main branch,
not 'latest' (which only gets created for the default branch).
Updated Terraform to reference the correct tag.
* bugfix: copy Prisma engines in Docker production stage (#41)
* chore: trigger deployment with public GHCR package
* bugfix: copy Prisma engines in Docker production stage
The Docker container was failing with PrismaClientInitializationError because
the query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
was not being copied to the production stage.
Now explicitly copying:
- node_modules/.prisma (contains query engine binaries)
- src/generated/prisma (contains Prisma Client)
This ensures Prisma can locate the query engine at runtime in Alpine Linux.
* bugfix: keep Prisma generated files in production Docker stage (#42)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* hotfix: resolve NG0401 and Auth0 SSR errors (#43)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output (#44)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output
Use live_url directly instead of prepending https:// to default_ingress which already contains the protocol
* bugfix: explicitly set DATABASE_URL environment variable (#45)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output
Use live_url directly instead of prepending https:// to default_ingress which already contains the protocol
* bugfix: explicitly set DATABASE_URL environment variable
Add explicit DATABASE_URL env var pointing to PostgreSQL cluster URI
as a SECRET type to ensure the database connection is properly configured
* bugfix: fix E2E tests for v2.0.0 (#46)
* chore: trigger deployment with public GHCR package
* bugfix: fix E2E tests for v2.0.0
- Re-enable E2E tests in GitHub workflow (Chromium only)
- Configure Playwright to only use Chromium project by default
- Fix accessibility test to check for h1 instead of removed #intro element
- Fix navigation tests to use .first() for duplicate links (nav + homepage CTAs)
- Fix auth test to handle Auth0 redirects properly
- All 20 E2E tests now passing
* feature: simplify navigation bar (#47)
* chore: trigger deployment with public GHCR package
* feature: simplify navigation bar
- Remove Admin link from navbar (accessible via login button)
- Reorder navigation links for better UX (Home > Resume > Projects > Articles > Github)
- Update login button to navigate to /admin page instead of triggering Auth0 directly
- Auth guard on /admin will trigger Auth0 login when needed
- Maintains clean, single-row navigation on desktop
* bugfix: sync branches and fix Husky deprecation warnings (#50)
* hotfix: enable Terraform deployment by making attestation non-blocking (#31)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile from Terraform backend (#32)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to Terraform backend for Spaces access (#33)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported Terraform volume block (#34)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported volume block from Terraform DigitalOcean App
DigitalOcean App Platform does not support volume mounts for services.
Removed the volume block to allow terraform validate to pass. SQLite database
will use ephemeral storage within the container.
* feature: add managed PostgreSQL for persistent storage (#35)
* chore: add cursor rule to forbid --no-verify flag
Created rule to prevent bypassing git hooks with --no-verify flag.
All commits and pushes must pass validation hooks to maintain code quality.
* bugfix: allow deployment to continue if attestation fails
Added continue-on-error to attestation step so Terraform deployment
can proceed even if artifact attestation fails. The Docker image
itself is successfully built and pushed, so deployment should not
be blocked by this optional security feature.
* bugfix: remove invalid use_lockfile argument from Terraform backend
The use_lockfile argument is not supported in Terraform S3 backend configuration.
Removed to allow terraform init to succeed in CI/CD deployment.
* bugfix: pass AWS credentials to all Terraform commands for backend access
Terraform backend (DigitalOcean Spaces) requires AWS credentials for S3-compatible
access. Added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
to terraform init, plan, and apply steps.
* bugfix: remove unsupported volume block from Terraform DigitalOcean App
DigitalOcean App Platform does not support volume mounts for services.
Removed the volume block to allow terraform validate to pass. SQLite database
will use ephemeral storage within the container.
* feature: add managed PostgreSQL database for persistent storage
Replaced ephemeral SQLite with DigitalOcean Managed PostgreSQL:
- Added digitalocean_database_cluster resource (db-s-1vcpu-1gb, /month)
- Connected database to App Platform app
- Updated Prisma schema from SQLite to PostgreSQL provider
- Updated Terraform outputs to show database connection details
- DATABASE_URL will be automatically injected by App Platform
This provides non-ephemeral, managed, and reliable database storage.
* bugfix: pass github_api_token variable to Terraform plan (#36)
Terraform plan was hanging waiting for github_api_token variable input.
Added -var flag to pass the GH_API_TOKEN secret to the terraform plan command.
* bugfix: fix DigitalOcean App registry credentials format (#37)
* bugfix: pass github_api_token variable to Terraform plan
Terraform plan was hanging waiting for github_api_token variable input.
Added -var flag to pass the GH_API_TOKEN secret to the terraform plan command.
* bugfix: fix DigitalOcean App registry credentials format
Removed unused digitalocean_container_registry_docker_credentials resource
which was trying to access a non-existent DigitalOcean registry.
Fixed registry_credentials format from var.github_token to
username:token format required by DigitalOcean App Platform for GHCR.
* chore: trigger deployment with public GHCR package (#38)
* bugfix: use main tag for Docker image in Terraform (#39)
* chore: trigger deployment with public GHCR package
* bugfix: use main tag instead of latest for Docker image
The workflow creates the 'main' tag for pushes to main branch,
not 'latest' (which only gets created for the default branch).
Updated Terraform to reference the correct tag.
* bugfix: copy Prisma engines in Docker production stage (#41)
* chore: trigger deployment with public GHCR package
* bugfix: copy Prisma engines in Docker production stage
The Docker container was failing with PrismaClientInitializationError because
the query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
was not being copied to the production stage.
Now explicitly copying:
- node_modules/.prisma (contains query engine binaries)
- src/generated/prisma (contains Prisma Client)
This ensures Prisma can locate the query engine at runtime in Alpine Linux.
* bugfix: keep Prisma generated files in production Docker stage (#42)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* hotfix: resolve NG0401 and Auth0 SSR errors (#43)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output (#44)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output
Use live_url directly instead of prepending https:// to default_ingress which already contains the protocol
* bugfix: explicitly set DATABASE_URL environment variable (#45)
* chore: trigger deployment with public GHCR package
* bugfix: keep Prisma generated files in production stage instead of copying
The previous approach tried to copy node_modules/.prisma from builder stage,
but it doesn't exist there because we use --ignore-scripts.
Solution:
- Generate Prisma in production stage (already doing this)
- Keep src/generated/prisma directory with query engine binaries
- Only remove other src files, not the generated directory
The query engine binary (libquery_engine-linux-musl-openssl-3.0.x.so.node)
is now properly available at runtime in src/generated/prisma/.
* bugfix: resolve NG0401 and Auth0 SSR errors
- Update main.server.ts to pass BootstrapContext to bootstrapApplication
- Exclude Auth0 from server config to prevent location access during SSR
- Make AuthService injection conditional in auth-button component using Injector
* bugfix: fix double https in app_url terraform output
Use live_url directly instead of prepending https:// to default_ingress which already contains the protocol
* bugfix: explicitly set DATABASE_URL environment variable
Add explicit DATABASE_URL env var pointing to PostgreSQL cluster URI
as a SECRET type to ensure the database connection is properly configured
* bugfix: fix E2E tests for v2.0.0 (#46)
* chore: trigger deployment with public GHCR package
* bugfix: fix E2E tests for v2.0.0
- Re-enable E2E tests in GitHub workflow (Chromium only)
- Configure Playwright to only use Chromium project by default
- Fix accessibility test to check for h1 instead of removed #intro element
- Fix navigation tests to use .first() for duplicate links (nav + homepage CTAs)
- Fix auth test to handle Auth0 redirects properly
- All 20 E2E tests now passing
* feature: simplify navigation bar (#47)
* chore: trigger deployment with public GHCR package
* feature: simplify navigation bar
- Remove Admin link from navbar (accessible via login button)
- Reorder navigation links for better UX (Home > Resume > Projects > Articles > Github)
- Update login button to navigate to /admin page instead of triggering Auth0 directly
- Auth guard on /admin will trigger Auth0 login when needed
- Maintains clean, single-row navigation on desktop
* chore: remove deprecated Husky v10 lines from post-checkout hook
* chore: bump version to 2.0.1 for release
---------
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore: bump version to 2.1.0 for release
---------
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @angular/compiler from 20.3.10 to 20.3.15 (#63)
Bumps [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) from 20.3.10 to 20.3.15.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/20.3.15/packages/compiler)
---
updated-dependencies:
- dependency-name: "@angular/compiler"
dependency-version: 20.3.15
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @modelcontextprotocol/sdk and @angular/cli (#64)
Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) to 1.24.0 and updates ancestor dependency [@angular/cli](https://github.com/angular/angular-cli). These dependencies need to be updated together.
Updates `@modelcontextprotocol/sdk` from 1.17.3 to 1.24.0
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](https://github.com/modelcontextprotocol/typescript-sdk/compare/1.17.3...1.24.0)
Updates `@angular/cli` from 20.3.9 to 20.3.13
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/20.3.9...20.3.13)
---
updated-dependencies:
- dependency-name: "@modelcontextprotocol/sdk"
dependency-version: 1.24.0
dependency-type: indirect
- dependency-name: "@angular/cli"
dependency-version: 20.3.13
dependency-type: direct:development
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump express (#62)
Bumps [express](https://github.com/expressjs/express) to 4.22.1 and updates ancestor dependency . These dependencies need to be updated together.
Updates `express` from 4.21.2 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.2...v4.22.1)
Updates `express` from 5.1.0 to 5.2.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.2...v4.22.1)
---
updated-dependencies:
- dependency-name: express
dependency-version: 4.22.1
dependency-type: direct:production
- dependency-name: express
dependency-version: 5.2.1
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joseph R. Quinn <[email protected]>
* chore(deps): bump node-forge from 1.3.1 to 1.3.2 (#60)
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2)
---
updated-dependencies:
- dependency-name: node-forge
dependency-version: 1.3.2
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps-dev): bump js-yaml from 3.14.1 to 3.14.2 (#59)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.1 to 3.14.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.2)
---
updated-dependencies:
- dependency-name: js-yaml
dependency-version: 3.14.2
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @angular/common from 20.3.10 to 20.3.14 (#61)
Bumps [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) from 20.3.10 to 20.3.14.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/20.3.14/packages/common)
---
updated-dependencies:
- dependency-name: "@angular/common"
dependency-version: 20.3.14
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps-dev): bump brace-expansion from 1.1.11 to 1.1.12 (#66)
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.11 to 1.1.12.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.12)
---
updated-dependencies:
- dependency-name: brace-expansion
dependency-version: 1.1.12
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Feature: tailwind v4 upgrade (#65)
* feature: upgrade to Tailwind CSS v4 with CSS-based configuration
Upgrade tailwindcss from v3.4.17 to v4.1.18 with modern CSS-first approach.
Changes:
- Add @tailwindcss/postcss v4.1.18 for PostCSS integration
- Add @tailwindcss/vite v4.1.18 for Vite support
- Convert styles.scss to use @import 'tailwindcss' syntax
- Migrate theme config to CSS using @theme directive
- Migrate plugins to CSS using @plugin directive
- Simplify tailwind.config.mjs to content paths only
- Add .postcssrc.json for PostCSS configuration
Benefits:
- Faster build times with new v4 engine
- CSS-first configuration approach
- Better tree-shaking and optimization
* chore: add git workflow and branch management cursor rule
Add comprehensive git workflow rule that enforces:
- Always working on feature/bugfix/etc branches (never main)
- Automatic commits when agent completes tasks
- Proper branch naming conventions
- Commit message format requirements
- Pre-commit check guidelines
- Complete workflow examples and checklists
This ensures consistent git practices and proper version control hygiene.
* refactor: consolidate all theme variables into @theme directive
Move all custom theme variables from :root to @theme directive for better
Tailwind v4 integration and CSS-first configuration.
Changes:
- Moved color palette variables to @theme
- Moved background color variables to @theme
- Moved text color variables to @theme
- Moved shadow and glow variables to @theme
- Moved border color variables to @theme
- Moved transition timing variables to @theme
- Removed now-empty :root block
Benefits:
- Full Tailwind v4 CSS-first approach
- All theme config in one @theme block
- Better integration with Tailwind's design system
- Cleaner, more maintainable structure
* chore: add cursor rule to prevent automatic markdown generation
Add rule that prevents creating markdown files unless explicitly requested:
- No auto-generated README.md, CHANGELOG.md, etc.
- No summary documents after task completion
- Exceptions: cursor rules (.mdc) and existing file modifications
- Provide summaries in conversation instead
This reduces file clutter and gives user control over documentation.
* bugfix: fix navbar spacing and layout issues
Improve navigation bar spacing and layout for better readability:
- Change md:space-x-1 to md:gap-6 for proper spacing between items
- Add md:flex and md:items-center to navbar container
- Add whitespace-nowrap to prevent text wrapping
- Increase icon margin from mr-1 to mr-2
- Remove hidden class from auth button container
- Fix padding on desktop (md:p-0) for cleaner look
This fixes the scrunched together navbar items.
* bugfix: initialize Credly certification badges after view loads
Add AfterViewInit lifecycle hook to properly load Credly badges:
- Import AfterViewInit, PLATFORM_ID, and isPlatformBrowser
- Implement ngAfterViewInit to trigger badge loading after view renders
- Add WindowWithCredly interface for type safety
- Add loadCredlyBadges method to initialize Credly.CredlyBadge.init()
- Include retry logic if script hasn't loaded yet
- Only run in browser context (skip during SSR)
- Fix import order and TypeScript strict type checking
This fixes certification badges not displaying on home page.
* feature: add Pegaus Heavy Industries tech company links
Add pegausheavy.dev links throughout the site:
- Add to navigation bar as external link with building icon
- Add to home page footer with company attribution
- Add footer icon link for quick access
- Add to resume contact information section
- Include proper aria-labels for accessibility
This promotes the Pegaus Heavy tech consulting company across the portfolio site.
* feature: add comprehensive SEO and AI crawler optimization
Add extensive SEO meta tags and structured data:
Meta Tags:
- Enhanced title and description tags
- Keywords targeting full-stack development and tech consulting
- Comprehensive robots meta directives
- Canonical URL for duplicate content prevention
Open Graph:
- Complete OG tags for Facebook and social sharing
- OG image and locale specifications
- Site name and type definitions
Twitter Cards:
- Summary large image card format
- Twitter creator attribution
- Optimized preview cards
AI Crawler Support:
- ChatGPT, GPTBot, Claude, and other AI crawler meta tags
- AI-summary meta tag with comprehensive profile
- Explicit permissions in robots.txt for AI crawlers
Structured Data (JSON-LD):
- Person schema with complete professional profile
- Educational credentials and alumni information
- Skills, expertise, and areas of knowledge
- Founder relationship to Pegaus Heavy Industries
- Website schema with search action
- ProfessionalService schema with service catalog
- Detailed service offerings (web dev, cloud, DevOps, consulting)
Robots.txt:
- Explicit allow directives for all major AI crawlers
- Search engine crawler permissions
- Social media bot permissions
- Admin route protection
- Sitemap location
This provides maximum visibility for search engines and AI training systems.
* chore: code formatting and cleanup after merge resolution
Apply Prettier formatting to recently modified files:
- Format meta tags in index.html for consistency
- Remove unused imports in test files
- Update cursor rules
Add untracked files:
- Add pr-merge-policy.mdc cursor rule
- Add diagnose-ssl.sh diagnostic script
All code is now properly formatted and ready for PR.
* test: update navigation component test for 7 items
Fix failing test after adding Pegasus Heavy link:
- Update expected navigation items count from 6 to 7
- Add test case for Pegasus Heavy external link
- Verify link, icon, and external flag
All navigation component tests now passing (5/5).
* test: update E2E test for new SEO-optimized page title
Fix failing E2E test after SEO improvements:
- Update title assertion to match new format
- Old: 'quinnjr.dev'
- New: 'Joseph R. Quinn | Full-Stack Software Engineer & Tech Consultant'
- Use regex to match key parts of the title
This aligns with the comprehensive SEO meta tags added earlier.
* test: fix Flowbite service async test timing issues
Fix flaky Flowbite service test using vi.waitFor:
- Replace setTimeout with vi.waitFor for better reliability
- Increase timeout from 200ms to 1000ms
- Add polling interval of 50ms
- Ensures dynamic import has time to resolve in CI
All client tests now passing (57/57).
* feature: upgrade to Tailwind CSS v4 and improve SEO (#67)
- Upgrade tailwindcss from v3 to v4.1.18 with modern CSS-first approach
- Add @tailwindcss/postcss v4.1.18 for PostCSS integration
- Add @tailwindcss/vite v4.1.18 for Vite support
- Convert styles.scss to use @import 'tailwindcss' syntax
- Migrate theme config to CSS using @theme directive
- Migrate plugins to CSS using @plugin directive
- Add .postcssrc.json for PostCSS configuration
SEO Improvements:
- Update page title to 'Joseph R. Quinn | Full-Stack Software Engineer & Tech Consultant'
- More descriptive and keyword-rich for better search rankings
Test Fixes:
- Update e2e home.spec.ts to match new SEO-friendly title
- Fix flowbite.service.spec.ts to be more resilient in test environments
- All tests passing: 101/101 (25 server + 56 unit + 20 e2e)
Additional:
- Add Cursor rules for git workflow and markdown documentation
- Add robots.txt for SEO and crawler management
* release: version 2.2.0
Release highlights:
- Upgrade to Tailwind CSS v4.1.18 with modern CSS-first configuration
- SEO improvements with descriptive page title
- Enhanced test coverage with all 101 tests passing
- New Cursor rules for git workflow and documentation
---------
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>1 parent 3307327 commit 0267de2
File tree
23 files changed
+2307
-924
lines changed- .cursor/rules
- e2e
- public
- src
- app
- components
- auth-button
- pages
- home
- resume
- services
23 files changed
+2307
-924
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
0 commit comments