mirror of
https://github.com/soconnor0919/personal-website.git
synced 2025-12-12 23:04:43 -05:00
add pubs
This commit is contained in:
@@ -36,6 +36,18 @@ const nextConfig = {
|
||||
},
|
||||
];
|
||||
},
|
||||
images: {
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
formats: ['image/webp', 'image/avif'],
|
||||
minimumCacheTTL: 60,
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: 'https',
|
||||
hostname: '**',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
33
package.json
33
package.json
@@ -11,26 +11,27 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-avatar": "^1.1.1",
|
||||
"@radix-ui/react-dialog": "^1.1.1",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
"@radix-ui/react-popover": "^1.1.1",
|
||||
"@radix-ui/react-select": "^2.1.1",
|
||||
"@radix-ui/react-popover": "^1.1.2",
|
||||
"@radix-ui/react-select": "^2.1.2",
|
||||
"@radix-ui/react-separator": "^1.1.0",
|
||||
"@radix-ui/react-slot": "^1.1.0",
|
||||
"@radix-ui/react-toast": "^1.2.1",
|
||||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"@react-pdf/renderer": "^3.4.0",
|
||||
"@radix-ui/react-toast": "^1.2.2",
|
||||
"@radix-ui/react-tooltip": "^1.1.3",
|
||||
"@react-pdf/renderer": "^3.4.5",
|
||||
"@t3-oss/env-nextjs": "^0.10.1",
|
||||
"@vercel/analytics": "^1.3.2",
|
||||
"@vercel/speed-insights": "^1.0.14",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"cn": "^0.1.1",
|
||||
"fs": "0.0.1-security",
|
||||
"geist": "^1.3.1",
|
||||
"lucide-react": "^0.441.0",
|
||||
"next": "^14.2.13",
|
||||
"next": "^14.2.16",
|
||||
"next-themes": "^0.3.0",
|
||||
"radix-ui": "^1.0.1",
|
||||
"react": "^18.3.1",
|
||||
@@ -42,18 +43,18 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/eslint": "^8.56.12",
|
||||
"@types/node": "^20.16.5",
|
||||
"@types/react": "^18.3.7",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.6.0",
|
||||
"@typescript-eslint/parser": "^8.6.0",
|
||||
"@types/node": "^20.17.2",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.12.0",
|
||||
"@typescript-eslint/parser": "^8.12.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-next": "^14.2.12",
|
||||
"eslint-config-next": "^14.2.16",
|
||||
"postcss": "^8.4.47",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.6",
|
||||
"tailwindcss": "^3.4.12",
|
||||
"typescript": "^5.6.2"
|
||||
"prettier-plugin-tailwindcss": "^0.6.8",
|
||||
"tailwindcss": "^3.4.14",
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"ct3aMetadata": {
|
||||
"initVersion": "7.37.0"
|
||||
|
||||
223
pnpm-lock.yaml
generated
223
pnpm-lock.yaml
generated
@@ -12,7 +12,7 @@ importers:
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: ^1.1.1
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-dropdown-menu':
|
||||
specifier: ^2.1.2
|
||||
@@ -24,10 +24,10 @@ importers:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-popover':
|
||||
specifier: ^1.1.1
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-select':
|
||||
specifier: ^2.1.1
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-separator':
|
||||
specifier: ^1.1.0
|
||||
@@ -36,13 +36,13 @@ importers:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0(@types/react@18.3.12)(react@18.3.1)
|
||||
'@radix-ui/react-toast':
|
||||
specifier: ^1.2.1
|
||||
specifier: ^1.2.2
|
||||
version: 1.2.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-tooltip':
|
||||
specifier: ^1.1.2
|
||||
specifier: ^1.1.3
|
||||
version: 1.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@react-pdf/renderer':
|
||||
specifier: ^3.4.0
|
||||
specifier: ^3.4.5
|
||||
version: 3.4.5(react@18.3.1)
|
||||
'@t3-oss/env-nextjs':
|
||||
specifier: ^0.10.1
|
||||
@@ -62,6 +62,9 @@ importers:
|
||||
cn:
|
||||
specifier: ^0.1.1
|
||||
version: 0.1.1
|
||||
fs:
|
||||
specifier: 0.0.1-security
|
||||
version: 0.0.1-security
|
||||
geist:
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1(next@14.2.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
|
||||
@@ -69,7 +72,7 @@ importers:
|
||||
specifier: ^0.441.0
|
||||
version: 0.441.0(react@18.3.1)
|
||||
next:
|
||||
specifier: ^14.2.13
|
||||
specifier: ^14.2.16
|
||||
version: 14.2.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
@@ -100,25 +103,25 @@ importers:
|
||||
specifier: ^8.56.12
|
||||
version: 8.56.12
|
||||
'@types/node':
|
||||
specifier: ^20.16.5
|
||||
version: 20.17.0
|
||||
specifier: ^20.17.2
|
||||
version: 20.17.2
|
||||
'@types/react':
|
||||
specifier: ^18.3.7
|
||||
specifier: ^18.3.12
|
||||
version: 18.3.12
|
||||
'@types/react-dom':
|
||||
specifier: ^18.3.0
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.6.0
|
||||
version: 8.11.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)
|
||||
specifier: ^8.12.0
|
||||
version: 8.12.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^8.6.0
|
||||
version: 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
specifier: ^8.12.0
|
||||
version: 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
eslint:
|
||||
specifier: ^8.57.1
|
||||
version: 8.57.1
|
||||
eslint-config-next:
|
||||
specifier: ^14.2.12
|
||||
specifier: ^14.2.16
|
||||
version: 14.2.16(eslint@8.57.1)(typescript@5.6.3)
|
||||
postcss:
|
||||
specifier: ^8.4.47
|
||||
@@ -127,13 +130,13 @@ importers:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3
|
||||
prettier-plugin-tailwindcss:
|
||||
specifier: ^0.6.6
|
||||
specifier: ^0.6.8
|
||||
version: 0.6.8(prettier@3.3.3)
|
||||
tailwindcss:
|
||||
specifier: ^3.4.12
|
||||
specifier: ^3.4.14
|
||||
version: 3.4.14
|
||||
typescript:
|
||||
specifier: ^5.6.2
|
||||
specifier: ^5.6.3
|
||||
version: 5.6.3
|
||||
|
||||
packages:
|
||||
@@ -146,14 +149,14 @@ packages:
|
||||
resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.0':
|
||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||
'@eslint-community/eslint-utils@4.4.1':
|
||||
resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
|
||||
'@eslint-community/regexpp@4.11.1':
|
||||
resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==}
|
||||
'@eslint-community/regexpp@4.12.1':
|
||||
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
|
||||
'@eslint/eslintrc@2.1.4':
|
||||
@@ -1011,8 +1014,8 @@ packages:
|
||||
'@types/json5@0.0.29':
|
||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||
|
||||
'@types/node@20.17.0':
|
||||
resolution: {integrity: sha512-a7zRo0f0eLo9K5X9Wp5cAqTUNGzuFLDG2R7C4HY2BhcMAsxgSPuRvAC1ZB6QkuUQXf0YZAgfOX2ZyrBa2n4nHQ==}
|
||||
'@types/node@20.17.2':
|
||||
resolution: {integrity: sha512-OOHK4sjXqkL7yQ7VEEHcf6+0jSvKjWqwnaCtY7AKD/VLEvRHMsxxu7eI8ErnjxHS8VwmekD4PeVCpu4qZEZSxg==}
|
||||
|
||||
'@types/prop-types@15.7.13':
|
||||
resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==}
|
||||
@@ -1023,8 +1026,8 @@ packages:
|
||||
'@types/react@18.3.12':
|
||||
resolution: {integrity: sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.11.0':
|
||||
resolution: {integrity: sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==}
|
||||
'@typescript-eslint/eslint-plugin@8.12.0':
|
||||
resolution: {integrity: sha512-uRqchEKT0/OwDePTwCjSFO2aH4zccdeQ7DgAzM/8fuXc+PAXvpdMRbuo+oCmK1lSfXssk2UUBNiWihobKxQp/g==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
|
||||
@@ -1034,8 +1037,8 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/parser@8.11.0':
|
||||
resolution: {integrity: sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==}
|
||||
'@typescript-eslint/parser@8.12.0':
|
||||
resolution: {integrity: sha512-7U20duDQWAOhCk2VtyY41Vor/CJjiEW063Zel9aoRXq89FQ/jr+0e0m3kxh9Sk5SFW9B1AblVIBtXd+1xQ1NWQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -1044,12 +1047,12 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/scope-manager@8.11.0':
|
||||
resolution: {integrity: sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==}
|
||||
'@typescript-eslint/scope-manager@8.12.0':
|
||||
resolution: {integrity: sha512-jbuCXK18iEshRFUtlCIMAmOKA6OAsKjo41UcXPqx7ZWh2b4cmg6pV/pNcZSB7oW9mtgF95yizr7Jnwt3IUD2pA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/type-utils@8.11.0':
|
||||
resolution: {integrity: sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==}
|
||||
'@typescript-eslint/type-utils@8.12.0':
|
||||
resolution: {integrity: sha512-cHioAZO/nLgyzTmwv7gWIjEKMHSbioKEZqLCaItTn7RvJP1QipuGVwEjPJa6Kv9u9UiUMVAESY9JH186TjKITw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
@@ -1057,12 +1060,12 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/types@8.11.0':
|
||||
resolution: {integrity: sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==}
|
||||
'@typescript-eslint/types@8.12.0':
|
||||
resolution: {integrity: sha512-Cc+iNtqBJ492f8KLEmKXe1l6683P0MlFO8Bk1NMphnzVIGH4/Wn9kvandFH+gYR1DDUjH/hgeWRGdO5Tj8gjYg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.11.0':
|
||||
resolution: {integrity: sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==}
|
||||
'@typescript-eslint/typescript-estree@8.12.0':
|
||||
resolution: {integrity: sha512-a4koVV7HHVOQWcGb6ZcAlunJnAdwo/CITRbleQBSjq5+2WLoAJQCAAiecvrAdSM+n/man6Ghig5YgdGVIC6xqw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
@@ -1070,14 +1073,14 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/utils@8.11.0':
|
||||
resolution: {integrity: sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==}
|
||||
'@typescript-eslint/utils@8.12.0':
|
||||
resolution: {integrity: sha512-5i1tqLwlf0fpX1j05paNKyIzla/a4Y3Xhh6AFzi0do/LDJLvohtZYaisaTB9kq0D4uBocAxWDTGzNMOCCwIgXA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.11.0':
|
||||
resolution: {integrity: sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==}
|
||||
'@typescript-eslint/visitor-keys@8.12.0':
|
||||
resolution: {integrity: sha512-2rXkr+AtZZLuNY18aUjv5wtB9oUiwY1WnNi7VTsdCdy1m958ULeUKoAegldQTjqpbpNJ5cQ4egR8/bh5tbrKKQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@ungap/structured-clone@1.2.0':
|
||||
@@ -1125,8 +1128,8 @@ packages:
|
||||
peerDependencies:
|
||||
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
|
||||
acorn@8.13.0:
|
||||
resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==}
|
||||
acorn@8.14.0:
|
||||
resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -1223,8 +1226,8 @@ packages:
|
||||
aws-sign@0.3.0:
|
||||
resolution: {integrity: sha512-pEMJAknifcXqXqYVXzGPIu8mJvxtJxIdpVpAs8HNS+paT+9srRUDMQn+3hULS7WbLmttcmvgMvnDcFujqXJyPw==}
|
||||
|
||||
axe-core@4.10.1:
|
||||
resolution: {integrity: sha512-qPC9o+kD8Tir0lzNGLeghbOrWMr3ZJpaRlCIb6Uobt/7N4FiEDvqUMnxzCHRHmg8vOg14kr5gVNyScRmbMaJ9g==}
|
||||
axe-core@4.10.2:
|
||||
resolution: {integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
axobject-query@4.1.0:
|
||||
@@ -1281,8 +1284,8 @@ packages:
|
||||
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
caniuse-lite@1.0.30001669:
|
||||
resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==}
|
||||
caniuse-lite@1.0.30001673:
|
||||
resolution: {integrity: sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==}
|
||||
|
||||
chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
@@ -1539,8 +1542,8 @@ packages:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
|
||||
eslint-plugin-jsx-a11y@6.10.1:
|
||||
resolution: {integrity: sha512-zHByM9WTUMnfsDTafGXRiqxp6lFtNoSOWBY6FonVRn3A+BUwN1L/tdBXT40BcBJi0cZjOGTXZ0eD/rTG9fEJ0g==}
|
||||
eslint-plugin-jsx-a11y@6.10.2:
|
||||
resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9
|
||||
@@ -1650,6 +1653,9 @@ packages:
|
||||
fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
fs@0.0.1-security:
|
||||
resolution: {integrity: sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==}
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
@@ -2789,12 +2795,12 @@ snapshots:
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)':
|
||||
'@eslint-community/eslint-utils@4.4.1(eslint@8.57.1)':
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/regexpp@4.11.1': {}
|
||||
'@eslint-community/regexpp@4.12.1': {}
|
||||
|
||||
'@eslint/eslintrc@2.1.4':
|
||||
dependencies:
|
||||
@@ -3736,7 +3742,7 @@ snapshots:
|
||||
|
||||
'@types/json5@0.0.29': {}
|
||||
|
||||
'@types/node@20.17.0':
|
||||
'@types/node@20.17.2':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
@@ -3751,14 +3757,14 @@ snapshots:
|
||||
'@types/prop-types': 15.7.13
|
||||
csstype: 3.1.3
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.11.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)':
|
||||
'@typescript-eslint/eslint-plugin@8.12.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.11.1
|
||||
'@typescript-eslint/parser': 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/scope-manager': 8.11.0
|
||||
'@typescript-eslint/type-utils': 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/visitor-keys': 8.11.0
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@typescript-eslint/parser': 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/scope-manager': 8.12.0
|
||||
'@typescript-eslint/type-utils': 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/visitor-keys': 8.12.0
|
||||
eslint: 8.57.1
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.2
|
||||
@@ -3769,12 +3775,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3)':
|
||||
'@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.11.0
|
||||
'@typescript-eslint/types': 8.11.0
|
||||
'@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3)
|
||||
'@typescript-eslint/visitor-keys': 8.11.0
|
||||
'@typescript-eslint/scope-manager': 8.12.0
|
||||
'@typescript-eslint/types': 8.12.0
|
||||
'@typescript-eslint/typescript-estree': 8.12.0(typescript@5.6.3)
|
||||
'@typescript-eslint/visitor-keys': 8.12.0
|
||||
debug: 4.3.7
|
||||
eslint: 8.57.1
|
||||
optionalDependencies:
|
||||
@@ -3782,15 +3788,15 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/scope-manager@8.11.0':
|
||||
'@typescript-eslint/scope-manager@8.12.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.11.0
|
||||
'@typescript-eslint/visitor-keys': 8.11.0
|
||||
'@typescript-eslint/types': 8.12.0
|
||||
'@typescript-eslint/visitor-keys': 8.12.0
|
||||
|
||||
'@typescript-eslint/type-utils@8.11.0(eslint@8.57.1)(typescript@5.6.3)':
|
||||
'@typescript-eslint/type-utils@8.12.0(eslint@8.57.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/typescript-estree': 8.12.0(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
debug: 4.3.7
|
||||
ts-api-utils: 1.3.0(typescript@5.6.3)
|
||||
optionalDependencies:
|
||||
@@ -3799,12 +3805,12 @@ snapshots:
|
||||
- eslint
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/types@8.11.0': {}
|
||||
'@typescript-eslint/types@8.12.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.11.0(typescript@5.6.3)':
|
||||
'@typescript-eslint/typescript-estree@8.12.0(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.11.0
|
||||
'@typescript-eslint/visitor-keys': 8.11.0
|
||||
'@typescript-eslint/types': 8.12.0
|
||||
'@typescript-eslint/visitor-keys': 8.12.0
|
||||
debug: 4.3.7
|
||||
fast-glob: 3.3.2
|
||||
is-glob: 4.0.3
|
||||
@@ -3816,20 +3822,20 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.11.0(eslint@8.57.1)(typescript@5.6.3)':
|
||||
'@typescript-eslint/utils@8.12.0(eslint@8.57.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1)
|
||||
'@typescript-eslint/scope-manager': 8.11.0
|
||||
'@typescript-eslint/types': 8.11.0
|
||||
'@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3)
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1)
|
||||
'@typescript-eslint/scope-manager': 8.12.0
|
||||
'@typescript-eslint/types': 8.12.0
|
||||
'@typescript-eslint/typescript-estree': 8.12.0(typescript@5.6.3)
|
||||
eslint: 8.57.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.11.0':
|
||||
'@typescript-eslint/visitor-keys@8.12.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.11.0
|
||||
'@typescript-eslint/types': 8.12.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
@@ -3848,11 +3854,11 @@ snapshots:
|
||||
|
||||
abs-svg-path@0.1.1: {}
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.13.0):
|
||||
acorn-jsx@5.3.2(acorn@8.14.0):
|
||||
dependencies:
|
||||
acorn: 8.13.0
|
||||
acorn: 8.14.0
|
||||
|
||||
acorn@8.13.0: {}
|
||||
acorn@8.14.0: {}
|
||||
|
||||
ajv@6.12.6:
|
||||
dependencies:
|
||||
@@ -3967,7 +3973,7 @@ snapshots:
|
||||
|
||||
aws-sign@0.3.0: {}
|
||||
|
||||
axe-core@4.10.1: {}
|
||||
axe-core@4.10.2: {}
|
||||
|
||||
axobject-query@4.1.0: {}
|
||||
|
||||
@@ -4022,7 +4028,7 @@ snapshots:
|
||||
|
||||
camelcase-css@2.0.1: {}
|
||||
|
||||
caniuse-lite@1.0.30001669: {}
|
||||
caniuse-lite@1.0.30001673: {}
|
||||
|
||||
chalk@4.1.2:
|
||||
dependencies:
|
||||
@@ -4274,13 +4280,13 @@ snapshots:
|
||||
dependencies:
|
||||
'@next/eslint-plugin-next': 14.2.16
|
||||
'@rushstack/eslint-patch': 1.10.4
|
||||
'@typescript-eslint/eslint-plugin': 8.11.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/eslint-plugin': 8.12.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
eslint: 8.57.1
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
eslint-plugin-jsx-a11y: 6.10.1(eslint@8.57.1)
|
||||
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
|
||||
eslint-plugin-react: 7.37.2(eslint@8.57.1)
|
||||
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1)
|
||||
optionalDependencies:
|
||||
@@ -4298,37 +4304,37 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1):
|
||||
eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1):
|
||||
dependencies:
|
||||
'@nolyfill/is-core-module': 1.0.39
|
||||
debug: 4.3.7
|
||||
enhanced-resolve: 5.17.1
|
||||
eslint: 8.57.1
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
fast-glob: 3.3.2
|
||||
get-tsconfig: 4.8.1
|
||||
is-bun-module: 1.2.1
|
||||
is-glob: 4.0.3
|
||||
optionalDependencies:
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
transitivePeerDependencies:
|
||||
- '@typescript-eslint/parser'
|
||||
- eslint-import-resolver-node
|
||||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
eslint: 8.57.1
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||
dependencies:
|
||||
'@rtsao/scc': 1.1.0
|
||||
array-includes: 3.1.8
|
||||
@@ -4339,7 +4345,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.57.1
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.12.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.15.1
|
||||
is-glob: 4.0.3
|
||||
@@ -4351,23 +4357,22 @@ snapshots:
|
||||
string.prototype.trimend: 1.0.8
|
||||
tsconfig-paths: 3.15.0
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.11.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.12.0(eslint@8.57.1)(typescript@5.6.3)
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1):
|
||||
eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1):
|
||||
dependencies:
|
||||
aria-query: 5.3.2
|
||||
array-includes: 3.1.8
|
||||
array.prototype.flatmap: 1.3.2
|
||||
ast-types-flow: 0.0.8
|
||||
axe-core: 4.10.1
|
||||
axe-core: 4.10.2
|
||||
axobject-query: 4.1.0
|
||||
damerau-levenshtein: 1.0.8
|
||||
emoji-regex: 9.2.2
|
||||
es-iterator-helpers: 1.1.0
|
||||
eslint: 8.57.1
|
||||
hasown: 2.0.2
|
||||
jsx-ast-utils: 3.3.5
|
||||
@@ -4412,8 +4417,8 @@ snapshots:
|
||||
|
||||
eslint@8.57.1:
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1)
|
||||
'@eslint-community/regexpp': 4.11.1
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1)
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint/eslintrc': 2.1.4
|
||||
'@eslint/js': 8.57.1
|
||||
'@humanwhocodes/config-array': 0.13.0
|
||||
@@ -4455,8 +4460,8 @@ snapshots:
|
||||
|
||||
espree@9.6.1:
|
||||
dependencies:
|
||||
acorn: 8.13.0
|
||||
acorn-jsx: 5.3.2(acorn@8.13.0)
|
||||
acorn: 8.14.0
|
||||
acorn-jsx: 5.3.2(acorn@8.14.0)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
esquery@1.6.0:
|
||||
@@ -4543,6 +4548,8 @@ snapshots:
|
||||
|
||||
fs.realpath@1.0.0: {}
|
||||
|
||||
fs@0.0.1-security: {}
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
@@ -4946,7 +4953,7 @@ snapshots:
|
||||
'@next/env': 14.2.16
|
||||
'@swc/helpers': 0.5.5
|
||||
busboy: 1.6.0
|
||||
caniuse-lite: 1.0.30001669
|
||||
caniuse-lite: 1.0.30001673
|
||||
graceful-fs: 4.2.11
|
||||
postcss: 8.4.31
|
||||
react: 18.3.1
|
||||
|
||||
12
public/publications.bib
Normal file
12
public/publications.bib
Normal file
@@ -0,0 +1,12 @@
|
||||
@inproceedings{OConnor2024,
|
||||
abstract = {Human-robot interaction (HRI) research plays a pivotal role in shaping how robots communicate and collaborate with humans. However, conducting HRI studies, particularly those employing the Wizard-of-Oz (WoZ) technique, can be challenging. WoZ user studies can have complexities at the technical and methodological levels that may render the results irreproducible. We propose to address these challenges with HRIStudio, a novel web-based platform designed to streamline the design, execution, and analysis of WoZ experiments. HRIStudio offers an intuitive interface for experiment creation, real-time control and monitoring during experimental runs, and comprehensive data logging and playback tools for analysis and reproducibility. By lowering technical barriers, promoting collaboration, and offering methodological guidelines, HRIStudio aims to make human-centered robotics research easier, and at the same time, empower researchers to develop scientifically rigorous user studies.},
|
||||
author = {O'Connor, Sean and Perrone, L. Felipe},
|
||||
title = {HRIStudio: A Framework for Wizard-of-Oz Experiments in Human-Robot Interaction Studies (Late Breaking Report)},
|
||||
booktitle={33rd IEEE International Conference on Robot and Human Interactive Communication (RO-MAN)},
|
||||
year = {2024}
|
||||
url = {https://soconnor.dev/publications/hristudio-lbr.pdf},
|
||||
paperUrl = {/publications/hristudio-lbr.pdf},
|
||||
posterUrl = {/publications/hristudio-lbr-poster.pdf}
|
||||
}
|
||||
|
||||
|
||||
BIN
public/publications/hristudio-lbr-poster.pdf
Normal file
BIN
public/publications/hristudio-lbr-poster.pdf
Normal file
Binary file not shown.
BIN
public/publications/hristudio-lbr.pdf
Normal file
BIN
public/publications/hristudio-lbr.pdf
Normal file
Binary file not shown.
@@ -2,25 +2,34 @@
|
||||
|
||||
export default function CVPage() {
|
||||
return (
|
||||
<div className="bg-white shadow-sm rounded-lg overflow-hidden">
|
||||
<object
|
||||
data="/cv.pdf"
|
||||
type="application/pdf"
|
||||
className="w-full h-[calc(100vh-11rem)]"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center p-8">
|
||||
<p className="text-lg text-muted-foreground">
|
||||
Your browser doesn't support PDF preview.
|
||||
</p>
|
||||
<a
|
||||
href="/cv.pdf"
|
||||
download
|
||||
className="mt-4 inline-flex items-center justify-center px-4 pt-2 pb-0 border border-transparent text-sm font-medium rounded-md text-white bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"
|
||||
>
|
||||
Download PDF
|
||||
</a>
|
||||
</div>
|
||||
</object>
|
||||
<div className="space-y-8">
|
||||
<section className="prose prose-zinc dark:prose-invert max-w-none">
|
||||
<h1 className="text-2xl font-bold">Curriculum Vitae</h1>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
My academic and professional experience in computer science, robotics, and engineering.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div className="bg-white shadow-sm rounded-lg overflow-hidden">
|
||||
<object
|
||||
data="/cv.pdf"
|
||||
type="application/pdf"
|
||||
className="w-full h-[calc(100vh-18rem)] lg:h-[calc(100vh-15rem)]"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center p-8">
|
||||
<p className="text-lg text-muted-foreground">
|
||||
Your browser doesn't support PDF preview.
|
||||
</p>
|
||||
<a
|
||||
href="/cv.pdf"
|
||||
download
|
||||
className="mt-4 inline-flex items-center justify-center px-4 pt-2 pb-0 border border-transparent text-sm font-medium rounded-md text-white bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"
|
||||
>
|
||||
Download PDF
|
||||
</a>
|
||||
</div>
|
||||
</object>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ export default function HomePage() {
|
||||
{/* About Section */}
|
||||
<section className="space-y-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">About Me</h1>
|
||||
<h1 className="text-2xl font-bold">Hi! I'm Sean.</h1>
|
||||
<p className="text-lg text-muted-foreground mt-2">
|
||||
I'm a Computer Science and Engineering student at Bucknell University, passionate about robotics,
|
||||
I am a Computer Science and Engineering student at Bucknell University, passionate about robotics,
|
||||
software development, and human-computer interaction. With a strong foundation in both academic
|
||||
research and practical development, I bridge the gap between theoretical concepts and real-world applications.
|
||||
</p>
|
||||
|
||||
@@ -57,8 +57,10 @@ export default function ProjectsPage() {
|
||||
<Image
|
||||
src={project.image}
|
||||
alt={project.title}
|
||||
fill
|
||||
className="object-contain"
|
||||
width={400}
|
||||
height={300}
|
||||
className="object-contain w-full h-full"
|
||||
priority={index === 0}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
124
src/app/publications/page.tsx
Normal file
124
src/app/publications/page.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
'use client';
|
||||
|
||||
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "~/components/ui/card";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import { ArrowUpRight, FileText, Presentation } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { parseBibtex } from "~/lib/bibtex";
|
||||
import { useEffect, useState } from "react";
|
||||
import type { Publication } from "~/lib/bibtex";
|
||||
import { Skeleton } from "~/components/ui/skeleton";
|
||||
|
||||
export default function PublicationsPage() {
|
||||
const [publications, setPublications] = useState<Publication[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('/publications.bib')
|
||||
.then(res => res.text())
|
||||
.then(text => {
|
||||
const pubs = parseBibtex(text);
|
||||
setPublications(pubs);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<section className="prose prose-zinc dark:prose-invert max-w-none">
|
||||
<h1 className="text-2xl font-bold">Publications</h1>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
My research publications in human-robot interaction and robotics.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div className="space-y-6">
|
||||
{loading ? (
|
||||
<Card>
|
||||
<CardHeader className="pb-2">
|
||||
<Skeleton className="h-6 w-1/2" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-4 w-full" />
|
||||
<Skeleton className="h-4 w-full mt-2" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : (
|
||||
publications.map((pub, index) => (
|
||||
<Card key={index}>
|
||||
<CardHeader className="pb-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle>{pub.title}</CardTitle>
|
||||
{pub.url && (
|
||||
<Link
|
||||
href={pub.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-muted-foreground hover:text-primary"
|
||||
>
|
||||
<ArrowUpRight className="h-5 w-5" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<CardDescription className="text-base">
|
||||
{pub.authors.join(', ')}
|
||||
</CardDescription>
|
||||
<CardDescription className="text-sm">
|
||||
{pub.venue} ({pub.year})
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
{pub.abstract && (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{pub.abstract}
|
||||
</p>
|
||||
)}
|
||||
<div className="flex flex-wrap gap-2 mt-4">
|
||||
<Badge variant="secondary" className="capitalize">
|
||||
{pub.type}
|
||||
</Badge>
|
||||
{pub.doi && (
|
||||
<Link
|
||||
href={`https://doi.org/${pub.doi}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Badge variant="outline" className="capitalize">
|
||||
<ArrowUpRight className="h-4 w-4" />
|
||||
DOI
|
||||
</Badge>
|
||||
</Link>
|
||||
)}
|
||||
{pub.paperUrl && (
|
||||
<Link
|
||||
href={pub.paperUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Badge variant="outline" className="capitalize">
|
||||
<FileText className="h-4 w-4" />
|
||||
Paper
|
||||
</Badge>
|
||||
</Link>
|
||||
)}
|
||||
{pub.posterUrl && (
|
||||
<Link
|
||||
href={pub.posterUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Badge variant="outline" className="capitalize">
|
||||
<Presentation className="h-4 w-4" />
|
||||
Poster
|
||||
</Badge>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -4,12 +4,13 @@ import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { useState } from 'react';
|
||||
import { Home, FolderGit2, FileText, Menu, X } from 'lucide-react';
|
||||
import { Home, FolderGit2, FileText, BookOpenText, Menu, X } from 'lucide-react';
|
||||
|
||||
// Define the nav items without icons
|
||||
const navItems = [
|
||||
{ href: '/', label: 'About', icon: Home },
|
||||
{ href: '/projects', label: 'Projects', icon: FolderGit2 },
|
||||
{ href: '/publications', label: 'Publications', icon: BookOpenText },
|
||||
{ href: '/cv', label: 'CV', icon: FileText },
|
||||
];
|
||||
|
||||
|
||||
@@ -65,8 +65,9 @@ export function Sidebar() {
|
||||
<Image
|
||||
src="/headshot.png"
|
||||
alt="Sean O'Connor"
|
||||
fill
|
||||
className="object-cover"
|
||||
width={240}
|
||||
height={240}
|
||||
className="object-cover rounded-xl"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
@@ -119,9 +120,12 @@ export function Sidebar() {
|
||||
<Image
|
||||
src="/headshot.png"
|
||||
alt="Sean O'Connor"
|
||||
fill
|
||||
className="object-cover"
|
||||
width={240}
|
||||
height={240}
|
||||
className="object-cover rounded-xl"
|
||||
priority
|
||||
placeholder="blur"
|
||||
blurDataURL="data:image/jpeg;base64,/9j..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority"
|
||||
import { cn } from "~/lib/utils"
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
"inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
||||
15
src/components/ui/skeleton.tsx
Normal file
15
src/components/ui/skeleton.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { cn } from "~/lib/utils"
|
||||
|
||||
function Skeleton({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) {
|
||||
return (
|
||||
<div
|
||||
className={cn("animate-pulse rounded-md bg-primary/10", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Skeleton }
|
||||
100
src/lib/bibtex.ts
Normal file
100
src/lib/bibtex.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
export type Publication = {
|
||||
title: string;
|
||||
authors: string[];
|
||||
venue: string;
|
||||
year: number;
|
||||
doi?: string;
|
||||
url?: string;
|
||||
paperUrl?: string;
|
||||
posterUrl?: string;
|
||||
abstract?: string;
|
||||
type: 'conference' | 'journal' | 'workshop' | 'thesis';
|
||||
};
|
||||
|
||||
type BibTeXEntry = {
|
||||
type: string;
|
||||
fields: Record<string, string>;
|
||||
};
|
||||
|
||||
function parseAuthors(authorString: string): string[] {
|
||||
return authorString
|
||||
.split(' and ')
|
||||
.map(author => author.trim())
|
||||
.map(author => {
|
||||
if (author.includes(',')) {
|
||||
const [lastName, firstName] = author.split(',').map(s => s.trim());
|
||||
return `${firstName} ${lastName}`;
|
||||
}
|
||||
return author;
|
||||
});
|
||||
}
|
||||
|
||||
function parseBibTeXEntry(entry: string): BibTeXEntry | null {
|
||||
// Match the entry type and content
|
||||
const typeMatch = entry.match(/^(\w+)\s*{\s*[\w\d-_]+\s*,/);
|
||||
if (!typeMatch) return null;
|
||||
|
||||
const type = typeMatch[1]!.toLowerCase();
|
||||
const content = entry.slice(typeMatch[0].length);
|
||||
|
||||
const fields: Record<string, string> = {};
|
||||
let currentField = '';
|
||||
let buffer = '';
|
||||
|
||||
// Split into lines and process each line
|
||||
const lines = content.split('\n');
|
||||
for (const line of lines) {
|
||||
const trimmedLine = line.trim();
|
||||
if (!trimmedLine || trimmedLine === '}') continue;
|
||||
|
||||
// Try to match a new field
|
||||
const fieldMatch = trimmedLine.match(/(\w+)\s*=\s*{(.+?)},?$/);
|
||||
if (fieldMatch?.[1] && fieldMatch?.[2]) {
|
||||
// Save previous field if exists
|
||||
if (currentField) {
|
||||
fields[currentField] = buffer.trim();
|
||||
}
|
||||
// Start new field
|
||||
currentField = fieldMatch[1].toLowerCase();
|
||||
buffer = fieldMatch[2];
|
||||
} else if (currentField) {
|
||||
// Continue previous field
|
||||
buffer += ' ' + trimmedLine.replace(/},$/, '');
|
||||
}
|
||||
}
|
||||
|
||||
// Save last field if exists
|
||||
if (currentField) {
|
||||
fields[currentField] = buffer.trim();
|
||||
}
|
||||
|
||||
return { type, fields };
|
||||
}
|
||||
|
||||
export function parseBibtex(bibtex: string): Publication[] {
|
||||
const entries = bibtex
|
||||
.split('@')
|
||||
.slice(1) // Skip first empty element
|
||||
.map(entry => parseBibTeXEntry(entry))
|
||||
.filter((entry): entry is BibTeXEntry => entry !== null);
|
||||
|
||||
return entries.map(entry => {
|
||||
const publicationType =
|
||||
entry.type === 'inproceedings' ? 'conference' :
|
||||
entry.type === 'article' ? 'journal' :
|
||||
entry.type === 'mastersthesis' ? 'thesis' : 'workshop';
|
||||
|
||||
return {
|
||||
title: entry.fields.title?.replace(/[{}]/g, '') || '',
|
||||
authors: parseAuthors(entry.fields.author || ''),
|
||||
venue: entry.fields.booktitle || entry.fields.journal || '',
|
||||
year: parseInt(entry.fields.year || '0', 10),
|
||||
doi: entry.fields.doi,
|
||||
url: entry.fields.url,
|
||||
paperUrl: entry.fields.paperurl,
|
||||
posterUrl: entry.fields.posterurl,
|
||||
abstract: entry.fields.abstract,
|
||||
type: publicationType
|
||||
};
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user