abhishek-portfolio-template 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +59 -0
  2. package/bin/cli.js +54 -0
  3. package/package.json +27 -0
  4. package/template/components.json +22 -0
  5. package/template/next.config.ts +79 -0
  6. package/template/package.json +43 -0
  7. package/template/postcss.config.js +6 -0
  8. package/template/public/BoliviaSignature-ZpWnz.ttf +0 -0
  9. package/template/public/Gemini_Generated_Image_xc97toxc97toxc97.png +0 -0
  10. package/template/public/Hendrigo.otf +0 -0
  11. package/template/public/audiomass-output.mp3 +0 -0
  12. package/template/public/file.svg +1 -0
  13. package/template/public/globe.svg +1 -0
  14. package/template/public/googlec77e59474f5a09cb.html +1 -0
  15. package/template/public/icon-192x192.png +0 -0
  16. package/template/public/icon-512x512.png +0 -0
  17. package/template/public/next.svg +1 -0
  18. package/template/public/paper sound .mpeg +0 -0
  19. package/template/public/removebg.png +0 -0
  20. package/template/public/resume.pdf +0 -0
  21. package/template/public/sw.js +1 -0
  22. package/template/public/swe-worker-5c72df51bb1f6ee0.js +1 -0
  23. package/template/public/vercel.svg +1 -0
  24. package/template/public/window.svg +1 -0
  25. package/template/public/workbox-f1770938.js +1 -0
  26. package/template/src/app/about/page.tsx +91 -0
  27. package/template/src/app/actions/optimize-text.ts +54 -0
  28. package/template/src/app/gaming/page.tsx +308 -0
  29. package/template/src/app/github/[username]/page.tsx +97 -0
  30. package/template/src/app/globals.css +321 -0
  31. package/template/src/app/layout.tsx +39 -0
  32. package/template/src/app/manifest.ts +25 -0
  33. package/template/src/app/not-found.tsx +16 -0
  34. package/template/src/app/page.tsx +28 -0
  35. package/template/src/app/robots.ts +12 -0
  36. package/template/src/app/sitemap.ts +38 -0
  37. package/template/src/app/template.tsx +5 -0
  38. package/template/src/app/works/[slug]/page.tsx +50 -0
  39. package/template/src/app/works/client.tsx +44 -0
  40. package/template/src/app/works/page.tsx +24 -0
  41. package/template/src/components/about/about-client.tsx +259 -0
  42. package/template/src/components/home/bento-gallery.tsx +52 -0
  43. package/template/src/components/home/contact-section.tsx +34 -0
  44. package/template/src/components/home/craft-card.tsx +18 -0
  45. package/template/src/components/home/featured-projects.tsx +186 -0
  46. package/template/src/components/home/focus-card.tsx +171 -0
  47. package/template/src/components/home/identity-card.tsx +45 -0
  48. package/template/src/components/home/philosophy-card.tsx +104 -0
  49. package/template/src/components/home/skills-in-motion.tsx +109 -0
  50. package/template/src/components/home/tech-stack-marquee.tsx +56 -0
  51. package/template/src/components/ui/3d-folder.tsx +569 -0
  52. package/template/src/components/ui/avatar.tsx +50 -0
  53. package/template/src/components/ui/badge.tsx +36 -0
  54. package/template/src/components/ui/basic-avatar.tsx +12 -0
  55. package/template/src/components/ui/button.tsx +117 -0
  56. package/template/src/components/ui/clipboard-secret.tsx +39 -0
  57. package/template/src/components/ui/command-menu.tsx +519 -0
  58. package/template/src/components/ui/command-palette.tsx +152 -0
  59. package/template/src/components/ui/consciousness-mode.tsx +200 -0
  60. package/template/src/components/ui/copy-code-button.tsx +135 -0
  61. package/template/src/components/ui/display-cards.tsx +70 -0
  62. package/template/src/components/ui/dotted-map.tsx +128 -0
  63. package/template/src/components/ui/dropdown-menu.tsx +200 -0
  64. package/template/src/components/ui/emoji-rating.tsx +123 -0
  65. package/template/src/components/ui/exit-message.tsx +50 -0
  66. package/template/src/components/ui/image-zoom-overlay.tsx +178 -0
  67. package/template/src/components/ui/input-otp.tsx +71 -0
  68. package/template/src/components/ui/kbd.tsx +87 -0
  69. package/template/src/components/ui/location-tag.tsx +232 -0
  70. package/template/src/components/ui/minimal-testimonial.tsx +97 -0
  71. package/template/src/components/ui/mobile-menu.tsx +191 -0
  72. package/template/src/components/ui/navbar.tsx +148 -0
  73. package/template/src/components/ui/page-transition.tsx +24 -0
  74. package/template/src/components/ui/pixeleted-404-not-found.tsx +110 -0
  75. package/template/src/components/ui/preloader-wrapper.tsx +102 -0
  76. package/template/src/components/ui/preloader.tsx +104 -0
  77. package/template/src/components/ui/project-contributors.tsx +57 -0
  78. package/template/src/components/ui/scroll-area.tsx +117 -0
  79. package/template/src/components/ui/signature.tsx +173 -0
  80. package/template/src/components/ui/smooth-scroll.tsx +31 -0
  81. package/template/src/components/ui/social-icons.tsx +103 -0
  82. package/template/src/components/ui/social-stories.tsx +394 -0
  83. package/template/src/components/ui/sound-constants.ts +1 -0
  84. package/template/src/components/ui/text-explode.tsx +188 -0
  85. package/template/src/components/ui/toast.tsx +80 -0
  86. package/template/src/components/ui/tooltip.tsx +30 -0
  87. package/template/src/components/ui/user-location.tsx +151 -0
  88. package/template/src/components/ui/vertical-image-stack.tsx +345 -0
  89. package/template/src/components/works/changelog-overlay.tsx +212 -0
  90. package/template/src/components/works/currently-working-card.tsx +130 -0
  91. package/template/src/components/works/project-details-view.tsx +464 -0
  92. package/template/src/components/works/project-grid.tsx +81 -0
  93. package/template/src/fonts/BoliviaSignature-ZpWnz.ttf +0 -0
  94. package/template/src/fonts/Hendrigo.otf +0 -0
  95. package/template/src/lib/data.ts +61 -0
  96. package/template/src/lib/fonts.ts +14 -0
  97. package/template/src/lib/github.ts +15 -0
  98. package/template/src/lib/supabase.ts +11 -0
  99. package/template/src/lib/utils.ts +6 -0
  100. package/template/tailwind.config.ts +31 -0
  101. package/template/tsconfig.json +34 -0
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Abhishek Portfolio Template (NPX Scaffolder)
2
+
3
+ A premium portfolio template with a Bento layout and smooth animations, inspired by Abhishek's personal website.
4
+
5
+ ## 🚀 How to use
6
+
7
+ You can use this template to scaffold a new portfolio project by running:
8
+
9
+ ```bash
10
+ npx abhishek-portfolio-template
11
+ ```
12
+
13
+ Follow the prompts to name your project. Once created:
14
+
15
+ ```bash
16
+ cd your-project-name
17
+ npm install
18
+ npm run dev
19
+ ```
20
+
21
+ ## ✨ Highlights
22
+
23
+ - **Bento Layout**: Responsive grid system for a modern look.
24
+ - **Premium Animations**: Built with `framer-motion` for smooth interactions.
25
+ - **Next.js 15 Ready**: Optimized for the latest Next.js features.
26
+ - **Shadcn/UI**: Beautifully crafted components.
27
+ - **PWA Support**: Offline capabilities and app-like feel.
28
+
29
+ ---
30
+
31
+ ## 📦 How to Publish (For Developer)
32
+
33
+ If you made changes to this package and want to publish it to NPM:
34
+
35
+ 1. **Login to NPM**:
36
+ ```bash
37
+ npm login
38
+ ```
39
+
40
+ 2. **Check Package Name**:
41
+ Ensure the `"name"` in `package.json` is unique and what you want (e.g., `@yourusername/abhishek-portfolio-template`).
42
+
43
+ 3. **Publish**:
44
+ ```bash
45
+ npm publish --access public
46
+ ```
47
+
48
+ 4. **Verify**:
49
+ Try running your package with `npx`:
50
+ ```bash
51
+ npx [your-package-name]
52
+ ```
53
+
54
+ ## 🛠️ Modifying the Template
55
+
56
+ The actual project files are located in the `template/` directory. Any changes you make there will be included in the new projects created via `npx`.
57
+
58
+ ---
59
+ Created with ❤️ by Abhishek
package/bin/cli.js ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs-extra');
4
+ const path = require('path');
5
+ const inquirer = require('inquirer');
6
+ const chalk = require('chalk');
7
+
8
+ async function init() {
9
+ console.log(chalk.cyan('\n🚀 Welcome to the Abhishek Portfolio Template Installer!\n'));
10
+
11
+ const answers = await inquirer.prompt([
12
+ {
13
+ type: 'input',
14
+ name: 'projectName',
15
+ message: 'What is your project name?',
16
+ default: 'my-portfolio',
17
+ }
18
+ ]);
19
+
20
+ const targetDir = path.join(process.cwd(), answers.projectName);
21
+
22
+ if (fs.existsSync(targetDir)) {
23
+ console.error(chalk.red(`\n❌ Error: Directory ${answers.projectName} already exists.\n`));
24
+ process.exit(1);
25
+ }
26
+
27
+ console.log(chalk.yellow(`\n📦 Creating ${answers.projectName}...\n`));
28
+
29
+ const templateDir = path.join(__dirname, '../template');
30
+
31
+ try {
32
+ await fs.copy(templateDir, targetDir);
33
+
34
+ // Update package.json name
35
+ const pkgPath = path.join(targetDir, 'package.json');
36
+ if (fs.existsSync(pkgPath)) {
37
+ const pkg = await fs.readJson(pkgPath);
38
+ pkg.name = answers.projectName;
39
+ await fs.writeJson(pkgPath, pkg, { spaces: 2 });
40
+ }
41
+
42
+ console.log(chalk.green(`\n✅ Success! Project ${answers.projectName} created.\n`));
43
+ console.log(chalk.white('Next steps:'));
44
+ console.log(chalk.cyan(` cd ${answers.projectName}`));
45
+ console.log(chalk.cyan(' npm install'));
46
+ console.log(chalk.cyan(' npm run dev\n'));
47
+
48
+ } catch (err) {
49
+ console.error(chalk.red(`\n❌ Error copying template: ${err.message}\n`));
50
+ process.exit(1);
51
+ }
52
+ }
53
+
54
+ init();
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "abhishek-portfolio-template",
3
+ "version": "1.0.0",
4
+ "description": "A premium portfolio template with Bento layout and smooth animations.",
5
+ "main": "bin/cli.js",
6
+ "bin": {
7
+ "create-abhishek-portfolio": "bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "keywords": [
13
+ "portfolio",
14
+ "template",
15
+ "nextjs",
16
+ "framer-motion",
17
+ "bento"
18
+ ],
19
+ "author": "Abhishek",
20
+ "license": "MIT",
21
+ "dependencies": {
22
+ "chalk": "^4.1.2",
23
+ "fs-extra": "^10.0.0",
24
+ "inquirer": "^8.2.0",
25
+ "path": "^0.12.7"
26
+ }
27
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.ts",
8
+ "css": "src/app/globals.css",
9
+ "baseColor": "neutral",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "iconLibrary": "lucide",
14
+ "aliases": {
15
+ "components": "@/components",
16
+ "utils": "@/lib/utils",
17
+ "ui": "@/components/ui",
18
+ "lib": "@/lib",
19
+ "hooks": "@/hooks"
20
+ },
21
+ "registries": {}
22
+ }
@@ -0,0 +1,79 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const withPWA = require("@ducanh2912/next-pwa").default({
4
+ dest: "public",
5
+ cacheOnFrontEndNav: true,
6
+ aggressiveFrontEndNavCaching: true,
7
+ reloadOnOnline: true,
8
+ disable: process.env.NODE_ENV === "development",
9
+ workboxOptions: {
10
+ disableDevLogs: true,
11
+ },
12
+ });
13
+
14
+ const nextConfig: NextConfig = {
15
+ images: {
16
+ formats: ['image/avif', 'image/webp'],
17
+ remotePatterns: [
18
+ {
19
+ protocol: "https",
20
+ hostname: "images.unsplash.com",
21
+ },
22
+ {
23
+ protocol: "https",
24
+ hostname: "plus.unsplash.com",
25
+ },
26
+ {
27
+ protocol: "https",
28
+ hostname: "github.com",
29
+ },
30
+ {
31
+ protocol: "https",
32
+ hostname: "raw.githubusercontent.com",
33
+ },
34
+ {
35
+ protocol: "https",
36
+ hostname: "avatars.githubusercontent.com",
37
+ },
38
+ {
39
+ protocol: "https",
40
+ hostname: "res.cloudinary.com",
41
+ },
42
+ {
43
+ protocol: "https",
44
+ hostname: "media.licdn.com",
45
+ },
46
+ {
47
+ protocol: "https",
48
+ hostname: "wallpapers.com",
49
+ },
50
+ ],
51
+ },
52
+ async headers() {
53
+ return [
54
+ {
55
+ source: '/(.*)',
56
+ headers: [
57
+ {
58
+ key: 'X-Frame-Options',
59
+ value: 'DENY',
60
+ },
61
+ {
62
+ key: 'X-Content-Type-Options',
63
+ value: 'nosniff',
64
+ },
65
+ {
66
+ key: 'Referrer-Policy',
67
+ value: 'strict-origin-when-cross-origin',
68
+ },
69
+ {
70
+ key: 'Permissions-Policy',
71
+ value: 'camera=(), microphone=(), geolocation=()',
72
+ },
73
+ ],
74
+ },
75
+ ];
76
+ },
77
+ };
78
+
79
+ export default withPWA(nextConfig);
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "abhishek-portfolio-template-app",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "@ducanh2912/next-pwa": "^10.2.9",
13
+ "@radix-ui/react-avatar": "^1.1.1",
14
+ "@radix-ui/react-dialog": "^1.1.1",
15
+ "@radix-ui/react-dropdown-menu": "^2.1.1",
16
+ "@radix-ui/react-scroll-area": "^1.1.0",
17
+ "@radix-ui/react-slot": "^1.1.0",
18
+ "@radix-ui/react-tooltip": "^1.1.2",
19
+ "@radix-ui/react-visually-hidden": "^1.1.0",
20
+ "class-variance-authority": "^0.7.0",
21
+ "clsx": "^2.1.1",
22
+ "framer-motion": "^11.5.4",
23
+ "lenis": "^1.1.13",
24
+ "lucide-react": "^0.439.0",
25
+ "next": "15.0.0",
26
+ "react": "18.3.1",
27
+ "react-dom": "18.3.1",
28
+ "react-icons": "^5.3.0",
29
+ "tailwind-merge": "^2.5.2",
30
+ "tailwindcss-animate": "^1.0.7"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20",
34
+ "@types/react": "^18",
35
+ "@types/react-dom": "^18",
36
+ "autoprefixer": "^10.4.20",
37
+ "eslint": "^8",
38
+ "eslint-config-next": "15.0.0",
39
+ "postcss": "^8.4.45",
40
+ "tailwindcss": "3.4.10",
41
+ "typescript": "^5"
42
+ }
43
+ }
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ plugins: {
3
+ '@tailwindcss/postcss': {},
4
+ autoprefixer: {},
5
+ },
6
+ }
Binary file
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ google-site-verification: googlec77e59474f5a09cb.html
Binary file
Binary file
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
Binary file
Binary file
@@ -0,0 +1 @@
1
+ if(!self.define){let e,s={};const a=(a,c)=>(a=new URL(a+".js",c).href,s[a]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=a,e.onload=s,document.head.appendChild(e)}else e=a,importScripts(a),s()}).then(()=>{let e=s[a];if(!e)throw new Error(`Module ${a} didn’t register its module`);return e}));self.define=(c,n)=>{const i=e||("document"in self?document.currentScript.src:"")||location.href;if(s[i])return;let t={};const r=e=>a(e,i),f={module:{uri:i},exports:t,require:r};s[i]=Promise.all(c.map(e=>f[e]||r(e))).then(e=>(n(...e),t))}}define(["./workbox-f1770938"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/BoliviaSignature-ZpWnz.ttf",revision:"080673fee5d8932de18b88239b8168bb"},{url:"/Gemini_Generated_Image_xc97toxc97toxc97.png",revision:"e07f4c28e48f4bbd126fb5958b524ce0"},{url:"/Hendrigo.otf",revision:"74f36c17cb680fe176bb693632f09af8"},{url:"/_next/static/bQh5f3TPrSgfLJJxB5t_J/_buildManifest.js",revision:"8fb509058f620c477741c0425fa0e456"},{url:"/_next/static/bQh5f3TPrSgfLJJxB5t_J/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/1732-55ad7b1be46671db.js",revision:"55ad7b1be46671db"},{url:"/_next/static/chunks/1966.b8f83f7ba376c962.js",revision:"b8f83f7ba376c962"},{url:"/_next/static/chunks/2192-a94678b5fa4ef21a.js",revision:"a94678b5fa4ef21a"},{url:"/_next/static/chunks/2926-d574cde473bc3396.js",revision:"d574cde473bc3396"},{url:"/_next/static/chunks/30a37ab2-295605e24af2bc7d.js",revision:"295605e24af2bc7d"},{url:"/_next/static/chunks/3248-4e5003528c0e1cbd.js",revision:"4e5003528c0e1cbd"},{url:"/_next/static/chunks/3899.3f761f7e3a944e8c.js",revision:"3f761f7e3a944e8c"},{url:"/_next/static/chunks/3962-c1587a20c7165297.js",revision:"c1587a20c7165297"},{url:"/_next/static/chunks/4003-1ed2ee03bce67582.js",revision:"1ed2ee03bce67582"},{url:"/_next/static/chunks/467-c47af4c4ab697459.js",revision:"c47af4c4ab697459"},{url:"/_next/static/chunks/4753-504a71c4bda02820.js",revision:"504a71c4bda02820"},{url:"/_next/static/chunks/4bd1b696-1400c1b9494d4acb.js",revision:"1400c1b9494d4acb"},{url:"/_next/static/chunks/5091-52068415e65d5833.js",revision:"52068415e65d5833"},{url:"/_next/static/chunks/5772-770b676a6d009d31.js",revision:"770b676a6d009d31"},{url:"/_next/static/chunks/5859.fa4cda25ccea600f.js",revision:"fa4cda25ccea600f"},{url:"/_next/static/chunks/5865-cfd2e51057b0baf5.js",revision:"cfd2e51057b0baf5"},{url:"/_next/static/chunks/654.c3d39ac257329e4a.js",revision:"c3d39ac257329e4a"},{url:"/_next/static/chunks/7712-52875e8abb8419d4.js",revision:"52875e8abb8419d4"},{url:"/_next/static/chunks/778-dd62f1e2a3091344.js",revision:"dd62f1e2a3091344"},{url:"/_next/static/chunks/8409-9d23a5336e2bf296.js",revision:"9d23a5336e2bf296"},{url:"/_next/static/chunks/8500-34f068059d5977b3.js",revision:"34f068059d5977b3"},{url:"/_next/static/chunks/8928-ba07c6cff0b9ef30.js",revision:"ba07c6cff0b9ef30"},{url:"/_next/static/chunks/8955-6429877558358936.js",revision:"6429877558358936"},{url:"/_next/static/chunks/8e1d74a4-ddc81ea8be09c626.js",revision:"ddc81ea8be09c626"},{url:"/_next/static/chunks/9030-37f6fe9179f635fe.js",revision:"37f6fe9179f635fe"},{url:"/_next/static/chunks/9082-edb2f4d3f819db96.js",revision:"edb2f4d3f819db96"},{url:"/_next/static/chunks/9136.35d616257cea14c1.js",revision:"35d616257cea14c1"},{url:"/_next/static/chunks/9300-e0c5ebb91f52cf0b.js",revision:"e0c5ebb91f52cf0b"},{url:"/_next/static/chunks/9338-c6617c40798e856f.js",revision:"c6617c40798e856f"},{url:"/_next/static/chunks/app/_global-error/page-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/app/_not-found/page-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/app/about/page-4226ceb3c289bfa2.js",revision:"4226ceb3c289bfa2"},{url:"/_next/static/chunks/app/admin/about/page-9857f440da42d71b.js",revision:"9857f440da42d71b"},{url:"/_next/static/chunks/app/admin/contact/page-64ac702099071bc8.js",revision:"64ac702099071bc8"},{url:"/_next/static/chunks/app/admin/gallery/page-68f911868a613bd6.js",revision:"68f911868a613bd6"},{url:"/_next/static/chunks/app/admin/layout-3eeaf4410d62167a.js",revision:"3eeaf4410d62167a"},{url:"/_next/static/chunks/app/admin/login/page-e1a9e78132cd1cc8.js",revision:"e1a9e78132cd1cc8"},{url:"/_next/static/chunks/app/admin/mfa-setup/page-431614b7e51cc540.js",revision:"431614b7e51cc540"},{url:"/_next/static/chunks/app/admin/page-f22beb9dd387d3dd.js",revision:"f22beb9dd387d3dd"},{url:"/_next/static/chunks/app/admin/profile/page-4fa14d6a4d4e8240.js",revision:"4fa14d6a4d4e8240"},{url:"/_next/static/chunks/app/admin/projects/page-649e69511d2d2786.js",revision:"649e69511d2d2786"},{url:"/_next/static/chunks/app/admin/settings/page-2ebb3649401d7b6f.js",revision:"2ebb3649401d7b6f"},{url:"/_next/static/chunks/app/admin/stories/page-6d688daa1b8daf6a.js",revision:"6d688daa1b8daf6a"},{url:"/_next/static/chunks/app/admin/tech/page-59a028a57134a8ea.js",revision:"59a028a57134a8ea"},{url:"/_next/static/chunks/app/admin/verify-2fa/page-d4d584e31c34c2e9.js",revision:"d4d584e31c34c2e9"},{url:"/_next/static/chunks/app/api/ratings/route-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/app/gaming/page-8e492676b3f47a60.js",revision:"8e492676b3f47a60"},{url:"/_next/static/chunks/app/github/%5Busername%5D/page-599ef160f39922d4.js",revision:"599ef160f39922d4"},{url:"/_next/static/chunks/app/layout-4d84a897f4b1138f.js",revision:"4d84a897f4b1138f"},{url:"/_next/static/chunks/app/manifest.webmanifest/route-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/app/not-found-7d0ee3a483888401.js",revision:"7d0ee3a483888401"},{url:"/_next/static/chunks/app/page-eed5a12a0efcf9e1.js",revision:"eed5a12a0efcf9e1"},{url:"/_next/static/chunks/app/robots.txt/route-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/app/sitemap.xml/route-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/app/template-2d47ac775387897d.js",revision:"2d47ac775387897d"},{url:"/_next/static/chunks/app/works/%5Bslug%5D/page-92260814acbff342.js",revision:"92260814acbff342"},{url:"/_next/static/chunks/app/works/page-2f2c0fdcf89e8103.js",revision:"2f2c0fdcf89e8103"},{url:"/_next/static/chunks/b1644e8c-57fe1f2dc6df044a.js",revision:"57fe1f2dc6df044a"},{url:"/_next/static/chunks/framework-d7945a8ad0653f37.js",revision:"d7945a8ad0653f37"},{url:"/_next/static/chunks/main-app-d73bd3878d6c2703.js",revision:"d73bd3878d6c2703"},{url:"/_next/static/chunks/main-be4653141a65e171.js",revision:"be4653141a65e171"},{url:"/_next/static/chunks/next/dist/client/components/builtin/app-error-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/next/dist/client/components/builtin/forbidden-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/next/dist/client/components/builtin/global-error-c0df9956904723bf.js",revision:"c0df9956904723bf"},{url:"/_next/static/chunks/next/dist/client/components/builtin/unauthorized-f0a41e9c5c2bca10.js",revision:"f0a41e9c5c2bca10"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-c719c8547acb795d.js",revision:"c719c8547acb795d"},{url:"/_next/static/css/1592591f0d388096.css",revision:"1592591f0d388096"},{url:"/_next/static/css/c0f96597b4edf880.css",revision:"c0f96597b4edf880"},{url:"/_next/static/css/e7f9110eaa0c9715.css",revision:"e7f9110eaa0c9715"},{url:"/_next/static/css/f5693affeaccb9db.css",revision:"f5693affeaccb9db"},{url:"/_next/static/media/4e063e4da012536e-s.woff2",revision:"72752d0828e32f4e98e2f6e3f3d468d0"},{url:"/_next/static/media/7b0b24f36b1a6d0b-s.p.woff2",revision:"98ccc2b7f18991a5126a91ac56fbb1fc"},{url:"/_next/static/media/7b3465dd004c697c-s.p.ttf",revision:"080673fee5d8932de18b88239b8168bb"},{url:"/_next/static/media/98848575513c9742-s.woff2",revision:"e2b64ddcb351dbe7397e0da426a8c8d6"},{url:"/_next/static/media/dd053ec84d009e81-s.p.woff2",revision:"3f8a9f93af4d2a7206b0a312c53aedd5"},{url:"/audiomass-output.mp3",revision:"98ab64f7cb12ff5434c95f9b7daab2a4"},{url:"/file.svg",revision:"d09f95206c3fa0bb9bd9fefabfd0ea71"},{url:"/globe.svg",revision:"2aaafa6a49b6563925fe440891e32717"},{url:"/googlec77e59474f5a09cb.html",revision:"ec6a8f3094347c416e488713f5b5c50c"},{url:"/icon-192x192.png",revision:"e07f4c28e48f4bbd126fb5958b524ce0"},{url:"/icon-512x512.png",revision:"e07f4c28e48f4bbd126fb5958b524ce0"},{url:"/next.svg",revision:"8e061864f388b47f33a1c3780831193e"},{url:"/paper sound .mpeg",revision:"1a26dcc1a02ac1de9bab6ca3deefe0d6"},{url:"/removebg.png",revision:"ebe1c6d934fdf0b55a10e890694b552e"},{url:"/resume.pdf",revision:"22d4bafa7d94a2ac4d76ae2f55f11d66"},{url:"/swe-worker-5c72df51bb1f6ee0.js",revision:"76fdd3369f623a3edcf74ce2200bfdd0"},{url:"/vercel.svg",revision:"c0af2f507b369b085b35ef4bbe3bcf1e"},{url:"/window.svg",revision:"a2760511c65806022ad20adf74370ff3"}],{ignoreURLParametersMatching:[/^utm_/,/^fbclid$/]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({response:e})=>e&&"opaqueredirect"===e.type?new Response(e.body,{status:200,statusText:"OK",headers:e.headers}):e}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/_next\/static.+\.js$/i,new e.CacheFirst({cacheName:"next-static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4|webm)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:48,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({sameOrigin:e,url:{pathname:s}})=>!(!e||s.startsWith("/api/auth/callback")||!s.startsWith("/api/")),new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({request:e,url:{pathname:s},sameOrigin:a})=>"1"===e.headers.get("RSC")&&"1"===e.headers.get("Next-Router-Prefetch")&&a&&!s.startsWith("/api/"),new e.NetworkFirst({cacheName:"pages-rsc-prefetch",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({request:e,url:{pathname:s},sameOrigin:a})=>"1"===e.headers.get("RSC")&&a&&!s.startsWith("/api/"),new e.NetworkFirst({cacheName:"pages-rsc",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:{pathname:e},sameOrigin:s})=>s&&!e.startsWith("/api/"),new e.NetworkFirst({cacheName:"pages",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({sameOrigin:e})=>!e,new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET"),self.__WB_DISABLE_DEV_LOGS=!0});
@@ -0,0 +1 @@
1
+ (()=>{"use strict";self.onmessage=async e=>{switch(e.data.type){case"__START_URL_CACHE__":{let t=e.data.url,a=await fetch(t);if(!a.redirected)return(await caches.open("start-url")).put(t,a);return Promise.resolve()}case"__FRONTEND_NAV_CACHE__":{let t=e.data.url,a=await caches.open("pages");if(await a.match(t,{ignoreSearch:!0}))return;let s=await fetch(t);if(!s.ok)return;if(a.put(t,s.clone()),e.data.shouldCacheAggressively&&s.headers.get("Content-Type")?.includes("text/html"))try{let e=await s.text(),t=[],a=await caches.open("static-style-assets"),r=await caches.open("next-static-js-assets"),c=await caches.open("static-js-assets");for(let[s,r]of e.matchAll(/<link.*?href=['"](.*?)['"].*?>/g))/rel=['"]stylesheet['"]/.test(s)&&t.push(a.match(r).then(e=>e?Promise.resolve():a.add(r)));for(let[,a]of e.matchAll(/<script.*?src=['"](.*?)['"].*?>/g)){let e=/\/_next\/static.+\.js$/i.test(a)?r:c;t.push(e.match(a).then(t=>t?Promise.resolve():e.add(a)))}return await Promise.all(t)}catch{}return Promise.resolve()}default:return Promise.resolve()}}})();
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
@@ -0,0 +1 @@
1
+ define(["exports"],function(t){"use strict";try{self["workbox:core:7.0.0"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:7.0.0"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class r{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class i extends r{constructor(t,e,s){super(({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)},e,s)}}class a{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)})}addCacheListener(){self.addEventListener("message",t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})}));t.waitUntil(s),t.ports&&t.ports[0]&&s.then(()=>t.ports[0].postMessage(!0))}})}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:r,route:i}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let a=i&&i.handler;const o=t.method;if(!a&&this.i.has(o)&&(a=this.i.get(o)),!a)return;let c;try{c=a.handle({url:s,request:t,event:e,params:r})}catch(t){c=Promise.reject(t)}const h=i&&i.catchHandler;return c instanceof Promise&&(this.o||h)&&(c=c.catch(async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:r})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n})),c}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const r=this.t.get(s.method)||[];for(const i of r){let r;const a=i.match({url:t,sameOrigin:e,request:s,event:n});if(a)return r=a,(Array.isArray(r)&&0===r.length||a.constructor===Object&&0===Object.keys(a).length||"boolean"==typeof a)&&(r=void 0),{route:i,params:r}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let o;const c=()=>(o||(o=new a,o.addFetchListener(),o.addCacheListener()),o);function h(t,e,n){let a;if("string"==typeof t){const s=new URL(t,location.href);a=new r(({url:t})=>t.href===s.href,e,n)}else if(t instanceof RegExp)a=new i(t,e,n);else if("function"==typeof t)a=new r(t,e,n);else{if(!(t instanceof r))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});a=t}return c().registerRoute(a),a}try{self["workbox:strategies:7.0.0"]&&_()}catch(t){}const u={cacheWillUpdate:async({response:t})=>200===t.status||0===t.status?t:null},l={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},f=t=>[l.prefix,t,l.suffix].filter(t=>t&&t.length>0).join("-"),w=t=>t||f(l.precache),d=t=>t||f(l.runtime);function p(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class y{constructor(){this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}}const g=new Set;function m(t){return"string"==typeof t?new Request(t):t}class v{constructor(t,e){this.h={},Object.assign(this,e),this.event=e.event,this.u=t,this.l=new y,this.p=[],this.m=[...t.plugins],this.v=new Map;for(const t of this.m)this.v.set(t,{});this.event.waitUntil(this.l.promise)}async fetch(t){const{event:e}=this;let n=m(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const r=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const i=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.u.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:i,response:t});return t}catch(t){throw r&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:r.clone(),request:i.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=m(t);let s;const{cacheName:n,matchOptions:r}=this.u,i=await this.getCacheKey(e,"read"),a=Object.assign(Object.assign({},r),{cacheName:n});s=await caches.match(i,a);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:r,cachedResponse:s,request:i,event:this.event})||void 0;return s}async cachePut(t,e){const n=m(t);var r;await(r=0,new Promise(t=>setTimeout(t,r)));const i=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(a=i.url,new URL(String(a),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var a;const o=await this.R(e);if(!o)return!1;const{cacheName:c,matchOptions:h}=this.u,u=await self.caches.open(c),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const r=p(e.url,s);if(e.url===r)return t.match(e,n);const i=Object.assign(Object.assign({},n),{ignoreSearch:!0}),a=await t.keys(e,i);for(const e of a)if(r===p(e.url,s))return t.match(e,n)}(u,i.clone(),["__WB_REVISION__"],h):null;try{await u.put(i,l?o.clone():o)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of g)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:c,oldResponse:f,newResponse:o.clone(),request:i,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.h[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=m(await t({mode:e,request:n,event:this.event,params:this.params}));this.h[s]=n}return this.h[s]}hasCallback(t){for(const e of this.u.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.u.plugins)if("function"==typeof e[t]){const s=this.v.get(e),n=n=>{const r=Object.assign(Object.assign({},n),{state:s});return e[t](r)};yield n}}waitUntil(t){return this.p.push(t),t}async doneWaiting(){let t;for(;t=this.p.shift();)await t}destroy(){this.l.resolve(null)}async R(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class R{constructor(t={}){this.cacheName=d(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,r=new v(this,{event:e,request:s,params:n}),i=this.q(r,s,e);return[i,this.D(i,r,s,e)]}async q(t,e,n){let r;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(r=await this.U(e,t),!r||"error"===r.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const i of t.iterateCallbacks("handlerDidError"))if(r=await i({error:s,event:n,request:e}),r)break;if(!r)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))r=await s({event:n,request:e,response:r});return r}async D(t,e,s,n){let r,i;try{r=await t}catch(i){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:r}),await e.doneWaiting()}catch(t){t instanceof Error&&(i=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:r,error:i}),e.destroy(),i)throw i}}function b(t){t.then(()=>{})}function q(){return q=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var n in s)({}).hasOwnProperty.call(s,n)&&(t[n]=s[n])}return t},q.apply(null,arguments)}let D,U;const x=new WeakMap,L=new WeakMap,I=new WeakMap,C=new WeakMap,E=new WeakMap;let N={get(t,e,s){if(t instanceof IDBTransaction){if("done"===e)return L.get(t);if("objectStoreNames"===e)return t.objectStoreNames||I.get(t);if("store"===e)return s.objectStoreNames[1]?void 0:s.objectStore(s.objectStoreNames[0])}return k(t[e])},set:(t,e,s)=>(t[e]=s,!0),has:(t,e)=>t instanceof IDBTransaction&&("done"===e||"store"===e)||e in t};function O(t){return t!==IDBDatabase.prototype.transaction||"objectStoreNames"in IDBTransaction.prototype?(U||(U=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])).includes(t)?function(...e){return t.apply(B(this),e),k(x.get(this))}:function(...e){return k(t.apply(B(this),e))}:function(e,...s){const n=t.call(B(this),e,...s);return I.set(n,e.sort?e.sort():[e]),k(n)}}function T(t){return"function"==typeof t?O(t):(t instanceof IDBTransaction&&function(t){if(L.has(t))return;const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("complete",r),t.removeEventListener("error",i),t.removeEventListener("abort",i)},r=()=>{e(),n()},i=()=>{s(t.error||new DOMException("AbortError","AbortError")),n()};t.addEventListener("complete",r),t.addEventListener("error",i),t.addEventListener("abort",i)});L.set(t,e)}(t),e=t,(D||(D=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])).some(t=>e instanceof t)?new Proxy(t,N):t);var e}function k(t){if(t instanceof IDBRequest)return function(t){const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("success",r),t.removeEventListener("error",i)},r=()=>{e(k(t.result)),n()},i=()=>{s(t.error),n()};t.addEventListener("success",r),t.addEventListener("error",i)});return e.then(e=>{e instanceof IDBCursor&&x.set(e,t)}).catch(()=>{}),E.set(e,t),e}(t);if(C.has(t))return C.get(t);const e=T(t);return e!==t&&(C.set(t,e),E.set(e,t)),e}const B=t=>E.get(t);const P=["get","getKey","getAll","getAllKeys","count"],M=["put","add","delete","clear"],W=new Map;function j(t,e){if(!(t instanceof IDBDatabase)||e in t||"string"!=typeof e)return;if(W.get(e))return W.get(e);const s=e.replace(/FromIndex$/,""),n=e!==s,r=M.includes(s);if(!(s in(n?IDBIndex:IDBObjectStore).prototype)||!r&&!P.includes(s))return;const i=async function(t,...e){const i=this.transaction(t,r?"readwrite":"readonly");let a=i.store;return n&&(a=a.index(e.shift())),(await Promise.all([a[s](...e),r&&i.done]))[0]};return W.set(e,i),i}N=(t=>q({},t,{get:(e,s,n)=>j(e,s)||t.get(e,s,n),has:(e,s)=>!!j(e,s)||t.has(e,s)}))(N);try{self["workbox:expiration:7.0.0"]&&_()}catch(t){}const S="cache-entries",K=t=>{const e=new URL(t,location.href);return e.hash="",e.href};class A{constructor(t){this._=null,this.L=t}I(t){const e=t.createObjectStore(S,{keyPath:"id"});e.createIndex("cacheName","cacheName",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1})}C(t){this.I(t),this.L&&function(t,{blocked:e}={}){const s=indexedDB.deleteDatabase(t);e&&s.addEventListener("blocked",t=>e(t.oldVersion,t)),k(s).then(()=>{})}(this.L)}async setTimestamp(t,e){const s={url:t=K(t),timestamp:e,cacheName:this.L,id:this.N(t)},n=(await this.getDb()).transaction(S,"readwrite",{durability:"relaxed"});await n.store.put(s),await n.done}async getTimestamp(t){const e=await this.getDb(),s=await e.get(S,this.N(t));return null==s?void 0:s.timestamp}async expireEntries(t,e){const s=await this.getDb();let n=await s.transaction(S).store.index("timestamp").openCursor(null,"prev");const r=[];let i=0;for(;n;){const s=n.value;s.cacheName===this.L&&(t&&s.timestamp<t||e&&i>=e?r.push(n.value):i++),n=await n.continue()}const a=[];for(const t of r)await s.delete(S,t.id),a.push(t.url);return a}N(t){return this.L+"|"+K(t)}async getDb(){return this._||(this._=await function(t,e,{blocked:s,upgrade:n,blocking:r,terminated:i}={}){const a=indexedDB.open(t,e),o=k(a);return n&&a.addEventListener("upgradeneeded",t=>{n(k(a.result),t.oldVersion,t.newVersion,k(a.transaction),t)}),s&&a.addEventListener("blocked",t=>s(t.oldVersion,t.newVersion,t)),o.then(t=>{i&&t.addEventListener("close",()=>i()),r&&t.addEventListener("versionchange",t=>r(t.oldVersion,t.newVersion,t))}).catch(()=>{}),o}("workbox-expiration",1,{upgrade:this.C.bind(this)})),this._}}class F{constructor(t,e={}){this.O=!1,this.T=!1,this.k=e.maxEntries,this.B=e.maxAgeSeconds,this.P=e.matchOptions,this.L=t,this.M=new A(t)}async expireEntries(){if(this.O)return void(this.T=!0);this.O=!0;const t=this.B?Date.now()-1e3*this.B:0,e=await this.M.expireEntries(t,this.k),s=await self.caches.open(this.L);for(const t of e)await s.delete(t,this.P);this.O=!1,this.T&&(this.T=!1,b(this.expireEntries()))}async updateTimestamp(t){await this.M.setTimestamp(t,Date.now())}async isURLExpired(t){if(this.B){const e=await this.M.getTimestamp(t),s=Date.now()-1e3*this.B;return void 0===e||e<s}return!1}async delete(){this.T=!1,await this.M.expireEntries(1/0)}}try{self["workbox:range-requests:7.0.0"]&&_()}catch(t){}async function H(t,e){try{if(206===e.status)return e;const n=t.headers.get("range");if(!n)throw new s("no-range-header");const r=function(t){const e=t.trim().toLowerCase();if(!e.startsWith("bytes="))throw new s("unit-must-be-bytes",{normalizedRangeHeader:e});if(e.includes(","))throw new s("single-range-only",{normalizedRangeHeader:e});const n=/(\d*)-(\d*)/.exec(e);if(!n||!n[1]&&!n[2])throw new s("invalid-range-values",{normalizedRangeHeader:e});return{start:""===n[1]?void 0:Number(n[1]),end:""===n[2]?void 0:Number(n[2])}}(n),i=await e.blob(),a=function(t,e,n){const r=t.size;if(n&&n>r||e&&e<0)throw new s("range-not-satisfiable",{size:r,end:n,start:e});let i,a;return void 0!==e&&void 0!==n?(i=e,a=n+1):void 0!==e&&void 0===n?(i=e,a=r):void 0!==n&&void 0===e&&(i=r-n,a=r),{start:i,end:a}}(i,r.start,r.end),o=i.slice(a.start,a.end),c=o.size,h=new Response(o,{status:206,statusText:"Partial Content",headers:e.headers});return h.headers.set("Content-Length",String(c)),h.headers.set("Content-Range",`bytes ${a.start}-${a.end-1}/${i.size}`),h}catch(t){return new Response("",{status:416,statusText:"Range Not Satisfiable"})}}function $(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:7.0.0"]&&_()}catch(t){}function z(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const r=new URL(n,location.href),i=new URL(n,location.href);return r.searchParams.set("__WB_REVISION__",e),{cacheKey:r.href,url:i.href}}class G{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class V{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.W.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.W=t}}let J,Q;async function X(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const r=t.clone(),i={headers:new Headers(r.headers),status:r.status,statusText:r.statusText},a=e?e(i):i,o=function(){if(void 0===J){const t=new Response("");if("body"in t)try{new Response(t.body),J=!0}catch(t){J=!1}J=!1}return J}()?r.body:await r.blob();return new Response(o,a)}class Y extends R{constructor(t={}){t.cacheName=w(t.cacheName),super(t),this.j=!1!==t.fallbackToNetwork,this.plugins.push(Y.copyRedirectedCacheableResponsesPlugin)}async U(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.S(t,e):await this.K(t,e))}async K(t,e){let n;const r=e.params||{};if(!this.j)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=r.integrity,i=t.integrity,a=!i||i===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?i||s:void 0})),s&&a&&"no-cors"!==t.mode&&(this.A(),await e.cachePut(t,n.clone()))}return n}async S(t,e){this.A();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}A(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==Y.copyRedirectedCacheableResponsesPlugin&&(n===Y.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(Y.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}Y.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},Y.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await X(t):t};class Z{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.F=new Map,this.H=new Map,this.$=new Map,this.u=new Y({cacheName:w(t),plugins:[...e,new V({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.u}precache(t){this.addToCacheList(t),this.G||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.G=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:r}=z(n),i="string"!=typeof n&&n.revision?"reload":"default";if(this.F.has(r)&&this.F.get(r)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.F.get(r),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.$.has(t)&&this.$.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:r});this.$.set(t,n.integrity)}if(this.F.set(r,t),this.H.set(r,i),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return $(t,async()=>{const e=new G;this.strategy.plugins.push(e);for(const[e,s]of this.F){const n=this.$.get(s),r=this.H.get(e),i=new Request(e,{integrity:n,cache:r,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:i,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}})}activate(t){return $(t,async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.F.values()),n=[];for(const r of e)s.has(r.url)||(await t.delete(r),n.push(r.url));return{deletedURLs:n}})}getURLsToCacheKeys(){return this.F}getCachedURLs(){return[...this.F.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.F.get(e.href)}getIntegrityForCacheKey(t){return this.$.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}const tt=()=>(Q||(Q=new Z),Q);class et extends r{constructor(t,e){super(({request:s})=>{const n=t.getURLsToCacheKeys();for(const r of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:r}={}){const i=new URL(t,location.href);i.hash="",yield i.href;const a=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some(t=>t.test(s))&&t.searchParams.delete(s);return t}(i,e);if(yield a.href,s&&a.pathname.endsWith("/")){const t=new URL(a.href);t.pathname+=s,yield t.href}if(n){const t=new URL(a.href);t.pathname+=".html",yield t.href}if(r){const t=r({url:i});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(r);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}},t.strategy)}}t.CacheFirst=class extends R{async U(t,e){let n,r=await e.cacheMatch(t);if(!r)try{r=await e.fetchAndCachePut(t)}catch(t){t instanceof Error&&(n=t)}if(!r)throw new s("no-response",{url:t.url,error:n});return r}},t.ExpirationPlugin=class{constructor(t={}){this.cachedResponseWillBeUsed=async({event:t,request:e,cacheName:s,cachedResponse:n})=>{if(!n)return null;const r=this.V(n),i=this.J(s);b(i.expireEntries());const a=i.updateTimestamp(e.url);if(t)try{t.waitUntil(a)}catch(t){}return r?n:null},this.cacheDidUpdate=async({cacheName:t,request:e})=>{const s=this.J(t);await s.updateTimestamp(e.url),await s.expireEntries()},this.X=t,this.B=t.maxAgeSeconds,this.Y=new Map,t.purgeOnQuotaError&&function(t){g.add(t)}(()=>this.deleteCacheAndMetadata())}J(t){if(t===d())throw new s("expire-custom-caches-only");let e=this.Y.get(t);return e||(e=new F(t,this.X),this.Y.set(t,e)),e}V(t){if(!this.B)return!0;const e=this.Z(t);if(null===e)return!0;return e>=Date.now()-1e3*this.B}Z(t){if(!t.headers.has("date"))return null;const e=t.headers.get("date"),s=new Date(e).getTime();return isNaN(s)?null:s}async deleteCacheAndMetadata(){for(const[t,e]of this.Y)await self.caches.delete(t),await e.delete();this.Y=new Map}},t.NetworkFirst=class extends R{constructor(t={}){super(t),this.plugins.some(t=>"cacheWillUpdate"in t)||this.plugins.unshift(u),this.tt=t.networkTimeoutSeconds||0}async U(t,e){const n=[],r=[];let i;if(this.tt){const{id:s,promise:a}=this.et({request:t,logs:n,handler:e});i=s,r.push(a)}const a=this.st({timeoutId:i,request:t,logs:n,handler:e});r.push(a);const o=await e.waitUntil((async()=>await e.waitUntil(Promise.race(r))||await a)());if(!o)throw new s("no-response",{url:t.url});return o}et({request:t,logs:e,handler:s}){let n;return{promise:new Promise(e=>{n=setTimeout(async()=>{e(await s.cacheMatch(t))},1e3*this.tt)}),id:n}}async st({timeoutId:t,request:e,logs:s,handler:n}){let r,i;try{i=await n.fetchAndCachePut(e)}catch(t){t instanceof Error&&(r=t)}return t&&clearTimeout(t),!r&&i||(i=await n.cacheMatch(e)),i}},t.RangeRequestsPlugin=class{constructor(){this.cachedResponseWillBeUsed=async({request:t,cachedResponse:e})=>e&&t.headers.has("range")?await H(t,e):e}},t.StaleWhileRevalidate=class extends R{constructor(t={}){super(t),this.plugins.some(t=>"cacheWillUpdate"in t)||this.plugins.unshift(u)}async U(t,e){const n=e.fetchAndCachePut(t).catch(()=>{});e.waitUntil(n);let r,i=await e.cacheMatch(t);if(i);else try{i=await n}catch(t){t instanceof Error&&(r=t)}if(!i)throw new s("no-response",{url:t.url,error:r});return i}},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",t=>{const e=w();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter(s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t);return await Promise.all(s.map(t=>self.caches.delete(t))),s})(e).then(t=>{}))})},t.clientsClaim=function(){self.addEventListener("activate",()=>self.clients.claim())},t.precacheAndRoute=function(t,e){!function(t){tt().precache(t)}(t),function(t){const e=tt();h(new et(e,t))}(e)},t.registerRoute=h});
@@ -0,0 +1,91 @@
1
+ import { NavBar } from "@/components/ui/navbar";
2
+ import { AboutClient } from "@/components/about/about-client";
3
+
4
+ export default function AboutPage() {
5
+ // Static Data - Editable via Code
6
+ const general = {
7
+ full_name: "Abhishek Singh",
8
+ role_title: "Product Engineer",
9
+ bio_description: "My name is Abhishek Singh, a self-taught Product Engineer with 4+ years of experience creating modern, clean, and minimal digital experiences that make a lasting impression.",
10
+ availability_status: "Available",
11
+ is_available: true,
12
+ contact_email: "Abhishek23main@gmail.com",
13
+ phone_number: "+91 9883511660",
14
+ location: "Kolkata, India",
15
+ birthday: "2004-10-23",
16
+ profile_image_url: "https://res.cloudinary.com/dap0u41dz/image/upload/v1766771167/file_00000000d51472078b7e2f9d883a6674_majhmb.jpg"
17
+ };
18
+
19
+ const experience = [
20
+ {
21
+ id: "1",
22
+ role: "Freelance Designer & Dev",
23
+ company: "Self-Employed",
24
+ period: "2021 - Present",
25
+ description_points: [
26
+ "Worked on diverse UI system and brand identity projects.",
27
+ "Collaborated with clients from multiple countries.",
28
+ "Developed a versatile design skill set."
29
+ ]
30
+ },
31
+ {
32
+ id: "2",
33
+ role: "Product Designer",
34
+ company: "Meetzed",
35
+ period: "2020 - 2021",
36
+ description_points: [
37
+ "Collaboration: Supported Lead Designer on projects.",
38
+ "Branding: Crafted unique brand identities.",
39
+ "Tools: Worked on design systems and prototypes."
40
+ ]
41
+ }
42
+ ];
43
+
44
+ const education = [
45
+ {
46
+ id: "1",
47
+ degree: "Graduation",
48
+ institution: "Adamas University",
49
+ year: "2023"
50
+ },
51
+ {
52
+ id: "2",
53
+ degree: "Higher Secondary",
54
+ institution: "Rampurhat JL Vidyabhaban",
55
+ year: "2023"
56
+ },
57
+ {
58
+ id: "3",
59
+ degree: "Secondary Education",
60
+ institution: "Rampurhat JL Vidyabhaban",
61
+ year: "2020"
62
+ }
63
+ ];
64
+
65
+ const skills = [
66
+ { id: "1", category: "design", name: "Figma", icon_name: "Fg", color_code: "#F24E1E" },
67
+ { id: "2", category: "design", name: "Photoshop", icon_name: "Ps", color_code: "#31A8FF" },
68
+ { id: "3", category: "design", name: "Illustrator", icon_name: "Ai", color_code: "#FF3366" },
69
+ { id: "4", category: "editing", name: "After Effects", icon_name: "Ae", color_code: "#9999FF" },
70
+ { id: "5", category: "editing", name: "Premiere Pro", icon_name: "Pr", color_code: "#FF66FF" }
71
+ ];
72
+
73
+ const interests = [
74
+ { id: "1", label: "Gaming", icon_name: "Gamepad2" },
75
+ { id: "2", label: "Film Making", icon_name: "Film" },
76
+ { id: "3", label: "Traveling", icon_name: "Plane" }
77
+ ];
78
+
79
+ return (
80
+ <main className="min-h-screen bg-[#0a0a0a] text-white selection:bg-white/20 relative overflow-x-hidden">
81
+ <NavBar />
82
+ <AboutClient
83
+ general={general}
84
+ experience={experience}
85
+ education={education}
86
+ skills={skills}
87
+ interests={interests}
88
+ />
89
+ </main>
90
+ );
91
+ }
@@ -0,0 +1,54 @@
1
+ "use server";
2
+
3
+ import OpenAI from "openai";
4
+
5
+ // Initialize OpenAI client with OpenRouter base URL
6
+ const client = new OpenAI({
7
+ baseURL: "https://openrouter.ai/api/v1",
8
+ apiKey: process.env.OPENROUTER_API_KEY,
9
+ defaultHeaders: {
10
+ "HTTP-Referer": "http://localhost:3000",
11
+ "X-Title": "Portfolio Admin",
12
+ },
13
+ });
14
+
15
+ export async function optimizeText(currentText: string) {
16
+ if (!process.env.OPENROUTER_API_KEY) {
17
+ return { error: "Development Config Error: OPENROUTER_API_KEY is missing via process.env" };
18
+ }
19
+
20
+ if (!currentText || currentText.trim().length === 0) {
21
+ return { error: "No text provided" };
22
+ }
23
+
24
+ try {
25
+ const response = await client.chat.completions.create({
26
+ model: "google/gemma-3-27b-it:free",
27
+ messages: [
28
+ {
29
+ role: "system",
30
+ content: `Refine the following text for clarity, conciseness, and professionalism.
31
+ Preserve the original meaning and intent.
32
+ Do not add new ideas, claims, or information.
33
+ Keep the tone confident, minimal, and natural.`,
34
+ },
35
+ {
36
+ role: "user",
37
+ content: currentText,
38
+ },
39
+ ],
40
+ temperature: 0.7, // Balance between creativity and strictness
41
+ });
42
+
43
+ const optimizedText = response.choices[0]?.message?.content?.trim();
44
+
45
+ if (!optimizedText) {
46
+ throw new Error("No response from AI");
47
+ }
48
+
49
+ return { optimizedText };
50
+ } catch (error: any) {
51
+ console.error("AI Optimization Error:", error);
52
+ return { error: error?.message || "Failed to optimize text. Please check server logs." };
53
+ }
54
+ }