diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..07e6ae2 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,40 @@ +name: Lint & Type checks + +on: [push] + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node_version: 14 + + - name: Install dependencies + run: | + yarn install + + - name: Run Prettier and ESlint + run: | + yarn lint + + types: + name: Types + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node_version: 14 + + - name: Install dependencies + run: | + yarn install + + - name: Run Typescript checks + run: | + yarn tsc diff --git a/README.md b/README.md index 8d55939..8466bbc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # coderhood.dev -This project was bootstrapped with [`create-r3f-app`](https://github.com/RenaudROHLINGER/create-r3f-app) \ No newline at end of file +This project was bootstrapped with [`create-r3f-app`](https://github.com/RenaudROHLINGER/create-r3f-app) diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..7b7aa2c --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/next.config.js b/next.config.js index f60d331..25abb1f 100644 --- a/next.config.js +++ b/next.config.js @@ -8,9 +8,7 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({ const withOffline = require('next-offline') function esbuildLoader(config, options) { - const jsLoader = config.module.rules.find( - (rule) => rule.test && rule.test.test('.js') - ) + const jsLoader = config.module.rules.find((rule) => rule.test && rule.test.test('.js')) if (jsLoader && jsLoader.use) { if (jsLoader.use.length > 0) { jsLoader.use.forEach((e) => { @@ -111,9 +109,7 @@ module.exports = plugins( withOffline, { workboxOpts: { - swDest: process.env.NEXT_EXPORT - ? 'service-worker.js' - : 'static/service-worker.js', + swDest: process.env.NEXT_EXPORT ? 'service-worker.js' : 'static/service-worker.js', runtimeCaching: [ { urlPattern: /^https?.*/, diff --git a/package.json b/package.json index 98a3005..4fcd9d7 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,10 @@ "private": false, "scripts": { "lint": "yarn prettier && yarn eslint", - "eslint": "eslint --fix 'src/**/*.{js,jsx}' --ext jsconfig.json", + "eslint": "eslint --max-warnings 20 'src/**/*.{js,jsx}' --ext jsconfig.json", + "eslint-fix": "eslint --fix 'src/**/*.{js,jsx}' --ext jsconfig.json", "prettier": "prettier --list-different '**/*.{js,jsx,md}'", + "tsc": "tsc --noEmit", "dev": "next dev", "build": "next build", "export": "EXPORT=true next build && EXPORT=true next export", @@ -49,6 +51,8 @@ "devDependencies": { "@babel/core": "^7.12.17", "@next/bundle-analyzer": "^10.0.7", + "@types/node": "^16.3.3", + "@types/react": "^17.0.14", "autoprefixer": "^10.2.6", "babel-eslint": "^10.1.0", "babel-plugin-glsl": "^1.0.0", @@ -75,6 +79,7 @@ "prettier": "^2.2.1", "raw-loader": "^4.0.2", "tailwindcss": "^2.2.4", + "typescript": "^4.3.5", "url-loader": "^4.1.1", "webpack": "^5.36.2" }, diff --git a/public/data/academy/2-git/1-git-init/readme.mdx b/public/data/academy/2-git/1-git-init/readme.mdx index 4651eba..526beee 100644 --- a/public/data/academy/2-git/1-git-init/readme.mdx +++ b/public/data/academy/2-git/1-git-init/readme.mdx @@ -3,7 +3,7 @@ title: 'Git init' publishedAt: '2021-06-24' author: 'Tomas' summary: 'Vamos a ver cómo guardar el progreso de nuestros proyectos y las ventajas de los sistemas de control de versiones. Hay que aprender a usar la consola. Veremos cómo publicar y guardar nuestros proyectos en la nube para accederlos y descargarlos donde queramos, que otros puedan verlo.' -youtubeURL: 'https://www.youtube.com/watch?v=7_d_sx773gs' +youtubeURL: 'https://www.youtube.com/embed/7_d_sx773gs' --- import { themes, Image } from 'mdx-deck' diff --git a/public/data/academy/2-git/2-git-branch/readme.mdx b/public/data/academy/2-git/2-git-branch/readme.mdx index 0a39a65..9b3d5fe 100644 --- a/public/data/academy/2-git/2-git-branch/readme.mdx +++ b/public/data/academy/2-git/2-git-branch/readme.mdx @@ -3,7 +3,7 @@ title: 'Git branch' publishedAt: '2021-06-27' author: 'Tomas' summary: '' -youtubeURL: '' +youtubeURL: 'https://www.youtube.com/embed/y23b5MA8KPc' --- import { themes, Image } from 'mdx-deck' diff --git a/public/data/academy/2-git/3-git-remote/readme.mdx b/public/data/academy/2-git/3-git-remote/readme.mdx new file mode 100644 index 0000000..2aea531 --- /dev/null +++ b/public/data/academy/2-git/3-git-remote/readme.mdx @@ -0,0 +1,257 @@ +--- +title: 'Git remote' +publishedAt: '2021-06-27' +author: 'Tomas' +summary: '' +youtubeURL: 'https://www.youtube.com/embed/tchGAii8OC4' +--- + +import { themes, Image } from 'mdx-deck' + + +# Clase 3: `git remote` + +### Tabla de contenidos + +1. Repositorios remotos + +1. Git fetch + +1. Git push + +1. Git pull + +1. Pull request (PR) + +--- + +## Repositorios remotos + +Hasta ahora todo lo que hicimos con git fue hacer cambios en nuestro repositorio local. El repositorio en nuestra computadora. + +Vimos un breve pantallazo de repositorios remotos al final de la primera clase, para poder subir nuestros cambios a GitHub. + +Los repositorios en GitHub son repositorios remotos! + +Entonces: + +> ##### Los repositorios remotos son repositorios en un server y accedemos a su información usando git. + +--- + + + +### Clonar un repositorio remoto + +Cuando usamos `git clone ` para clonar un repo, `repo_url` es la URL del repositorio remoto. + +En este caso git agrega automáticamente un *remote* llamado `origin` con esta URL. + +Esto es para que nuestro repositorio local recién clonado quede vinculado con el repositorio remoto original. + +--- + + +### git remote + +Para ver los _remotos_ que tenemos configurados hay que ejecutar `git remote`: +``` +$ git remote +origin +``` + +O `git remote -v` para ver las URL donde está el _remote_: +``` +$ git remote -v +origin git@github.com:tomasdisk/mi-repo.git (fetch) +origin git@github.com:tomasdisk/mi-repo.git (push) +``` + +* **fetch** es buscar, es la url donde git busca y lee info del _remote_ +* **push** empujar o publicar, es la url a donde git envia info desde nuestro repo local + +--- + + +### Agregar un remote + +Lo hicimos en la primera clase! + +Se hace con `git remote add `. + +Por ejemplo: +``` +$ git remote add origin_copia git@github.com:tomasdisk/mi-repo.git +$ git remote +origin +origin_copia +``` + +Ahora tenemos dos repositorios remotos (aunque los dos tengan la misma URL). + +--- + + +## Git fetch + +Se usa para traer información de un _remote_. + +``` +git fetch +``` + +Si queremos traer toda la información que tiene de `origin` que aún no tenemos en el repositorio local, hacemos: +``` +$ git fetch origin +``` + +Cómo origin es _remote_ por defecto, no es necesario aclararlo y podemos hacer solo `git fetch`. + +Esto trae todos los cambios(_commits_) del _remote_ pero no los combina(_mergea_) con nuestros cambios. + +--- + + +### ¿Dónde están esos cambios? + +Si hacemos `git branch` vamos a ver la ramas que tenemos: +``` +$ git branch + hotfix +* main +``` + +Pero si le agregamos `--all`, vamos a ver esto: +``` +$ git branch --all + hotfix +* main + remotes/origin/main + remotes/origin/testing +``` + +Nos esta mostrando nuestras ramas locales, pero también las ramas que conocemos del _remote_. + +--- + + +## Git push + +Cuando queremos compartir o publicar nuestros cambios, tenemos que enviarlos al servidor usando `git push `. + +Para enviar la rama `master` al servidor `origin`, entonces ejecutamos: +``` +$ git push origin master +``` + +Esto enviara todos los commits hechos en `master` al servidor. + +--- + +## Git pull + +`git pull `. + +Se usa para descargar lo cambios de una rama del _remote_ y mergearlos en la rama local en un solo paso. + +Por ejemplo: +``` +$ git pull origin master +``` + +En este caso estamos trayendo los cambios de la rama `origin/master` y haciendo el merge en la rama en la que estemos actualmente. + +Esto va a ser posible si no surgen conflictos en el _merge_ entre la rama remota y la local. + +--- + + +### Tracking o seguimiento de ramas + +Son ramas locales que tienen una relación directa con alguna rama remota. + +Esto facilita el uso de las ramas cuando queremos publicar y traernos cambios. + +Si hacemos `git remote show `, git nos da bastantes detalles del _remote_: +``` +$ git remote show origin +* remote origin + Fetch URL: git@github.com:tomasdisk/mi-repo.git + Push URL: git@github.com:tomasdisk/mi-repo.git + HEAD branch: main + Remote branches: + main tracked + testing tracked + Local branch configured for 'git pull': + main merges with remote main + Local ref configured for 'git push': + main pushes to main (local out of date) +``` + +Las últimas líneas dicen que `main` esta configurada para "seguir" a `origin/main`. + +Si nuestra rama está configurada para hacer seguimiento a una rama remota, al hacer `git push` o `git pull` sin especificar ningun _remote_ o _rama_, +nos va a enviar (push) o descargar (pull) los cambios de la rama que se este "siguiendo". + +--- + + +### Renombrar o eliminar remotos + +Renombrar `git remote rename `: +``` +$ git remote +origin +pb +$ git remote rename pb paul +$ git remote +origin +paul +``` + +Eliminar `git remote rm ` +``` +$ git remote rm paul +$ git remote +origin +``` + +--- + + +## Pull request (PR) + +Es una herramienta de GitHub para solicitar, revisar y mergear ramas del _remote_ de forma online. + +--- + + +### Ejercicios + +#### 1. Publicar cambios en una rama que no sea `master` o `main` + +- Crear una rama, hacer un commit con cambios +- Publicar la rama con `git push` + +#### 2. Crear el primer PR + +- Publicar una rama en GitHub y crear un PR +- Mergear el PR 😄 + +--- + +### Resumen + +Todos los comandos usados en la clase ✨ + +--- + + +### Bibliografía + +### 1. [Pro Git, Capitulo 2.5: Fundamentos de Git - Trabajar con Remotos](https://git-scm.com/book/es/v2/Fundamentos-de-Git-Trabajar-con-Remotos) +### 1. [Pro Git, Capitulo 3.5: Ramificaciones en Git - Ramas Remotas](https://git-scm.com/book/es/v2/Ramificaciones-en-Git-Ramas-Remotas) + +
+
+
diff --git a/public/data/academy/2-git/readme.mdx b/public/data/academy/2-git/readme.mdx index afe9904..46875dd 100644 --- a/public/data/academy/2-git/readme.mdx +++ b/public/data/academy/2-git/readme.mdx @@ -28,7 +28,6 @@ summary: 'Módulo de git, donde aprenderemos a usar git en la terminal para vers Cuando una tarea está lista, su rama se puede fusionar con otra para juntar los cambios! -## Próximamente, jueves 8 de Julio ## 2. `git remote` ### ¿Cómo trabajar con un repositorio remoto? diff --git a/public/images/team/Lucas.jpg b/public/images/team/Lucas.jpg new file mode 100644 index 0000000..626f7e7 Binary files /dev/null and b/public/images/team/Lucas.jpg differ diff --git a/public/images/team/Meison.jpg b/public/images/team/Meison.jpg new file mode 100644 index 0000000..af2f470 Binary files /dev/null and b/public/images/team/Meison.jpg differ diff --git a/public/images/team/Pablo.jpg b/public/images/team/Pablo.jpg new file mode 100644 index 0000000..533cef4 Binary files /dev/null and b/public/images/team/Pablo.jpg differ diff --git a/public/images/team/Tomas.png b/public/images/team/Tomas.png new file mode 100644 index 0000000..605ca50 Binary files /dev/null and b/public/images/team/Tomas.png differ diff --git a/src/components/Auth/SignInForm.jsx b/src/components/Auth/SignInForm.jsx index 843b4dd..3795942 100644 --- a/src/components/Auth/SignInForm.jsx +++ b/src/components/Auth/SignInForm.jsx @@ -4,6 +4,7 @@ import { motion } from 'framer-motion' import { Dialog } from '@headlessui/react' import { yupResolver } from '@hookform/resolvers/yup' import * as yup from 'yup' +import Image from 'next/image' import { Input } from '@/components/Input' import { Button } from '@/components/Button' @@ -22,6 +23,8 @@ const schema = yup.object().shape({ export const SignIn = ({ onComplete, onRequestSignUp, unauthorizedMessage }) => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) + const [discordButtonLoading, setDiscordButtonLoading] = useState(false) + const [discordAuthError, setDiscordAuthError] = useState(null) const { register, handleSubmit, formState } = useForm({ resolver: yupResolver(schema), }) @@ -46,11 +49,36 @@ export const SignIn = ({ onComplete, onRequestSignUp, unauthorizedMessage }) => } } + const discordAuth = async () => { + setDiscordAuthError(null) + setDiscordButtonLoading(true) + try { + const { user, error } = await supabase.auth.signIn( + { + provider: 'discord', + }, + { + redirectTo: window.location.href, + } + ) + + if (error) { + throw error + } else { + onComplete(user) + } + } catch (error) { + setError(error.error_description || error.message) + } finally { + setDiscordButtonLoading(false) + } + } + return (
-
+

Inicia sesión con tu email y contraseña.

@@ -71,6 +99,22 @@ export const SignIn = ({ onComplete, onRequestSignUp, unauthorizedMessage }) => Iniciar sesión
+
+
+ +
+

{getErrorMessage(discordAuthError)}

{ +export const Author: React.FC<{ author: string }> = ({ author }) => { const src = team[author] || '/images/logos/logo.png' return ( Bubble Image { const mesh = useRef() // Subscribe this to the render-loop, rotate the mesh every frame useFrame((state, delta) => - mesh.current - ? (mesh.current.rotation.y = mesh.current.rotation.x += 0.002) - : null + mesh.current ? (mesh.current.rotation.y = mesh.current.rotation.x += 0.002) : null ) // Return the view, these are regular Threejs elements expressed in JSX return ( diff --git a/src/components/Head.jsx b/src/components/Head.jsx index 0e0e4a1..8290f92 100644 --- a/src/components/Head.jsx +++ b/src/components/Head.jsx @@ -2,15 +2,10 @@ import NextHead from 'next/head' const TITLE = 'Coderhood' const URL = 'https://coderhood.dev/' -const DESCRIPTION = - 'La comunidad que impulsa el aprendizaje autodidacta y colaborativo' +const DESCRIPTION = 'La comunidad que impulsa el aprendizaje autodidacta y colaborativo' const author = 'Ema Lorenzo' -export const Head = ({ - title = TITLE, - url = URL, - description = DESCRIPTION, -}) => { +export const Head = ({ title = TITLE, url = URL, description = DESCRIPTION }) => { return ( <> diff --git a/src/components/MDX.tsx b/src/components/MDX.tsx new file mode 100644 index 0000000..5667984 --- /dev/null +++ b/src/components/MDX.tsx @@ -0,0 +1,18 @@ +import React from 'react' +import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote' + +const MDX: React.FC<{ source: MDXRemoteSerializeResult> }> = ({ + source, +}) => { + return ( +
    {children}
, + Image: ({ alt, ...props }) => {alt}, + }} + /> + ) +} + +export default MDX diff --git a/src/examples/canvas/test_shader.js b/src/examples/canvas/test_shader.js index a2c51e4..6875452 100644 --- a/src/examples/canvas/test_shader.js +++ b/src/examples/canvas/test_shader.js @@ -43,8 +43,7 @@ const TestShader = (props) => { mesh.current.rotation.x = mesh.current.rotation.y += 0.01 } if (mesh.current.material) { - mesh.current.material.uniforms.time.value += - Math.sin(delta / 2) * Math.cos(delta / 2) + mesh.current.material.uniforms.time.value += Math.sin(delta / 2) * Math.cos(delta / 2) } }) diff --git a/src/layouts/Lesson.jsx b/src/layouts/Lesson.jsx index 1ab70c1..8fe52ba 100644 --- a/src/layouts/Lesson.jsx +++ b/src/layouts/Lesson.jsx @@ -26,9 +26,14 @@ export const LessonLayout = ({ title, frontMatter, pdfURL, lessons, children }) {/*

{author}

*/} -

- {publishedAt && format(parseISO(publishedAt), 'MMMM dd, yyyy')} -

+
+

+ {publishedAt && format(parseISO(publishedAt), 'MMMM dd, yyyy')} +

+

+ {author || null} +

+
{pdfURL ? ( ⚡️ Descarga el pdf de la clase

) : ( -

Próximamente

+

Próximamente en PDF

)}
diff --git a/src/layouts/Module.jsx b/src/layouts/Module.jsx index b9f6693..90862ae 100644 --- a/src/layouts/Module.jsx +++ b/src/layouts/Module.jsx @@ -12,9 +12,7 @@ export const ModuleLayout = ({ frontMatter, title, lessons, children }) => {
-
- {children} -
+
{children}
diff --git a/src/pages/academy/[module]/[lesson].jsx b/src/pages/academy/[module]/[lesson].jsx index 88fef05..fb8daf2 100644 --- a/src/pages/academy/[module]/[lesson].jsx +++ b/src/pages/academy/[module]/[lesson].jsx @@ -1,5 +1,4 @@ -import { MDXRemote } from 'next-mdx-remote' - +import MDX from '@/components/MDX' import useStore from '@/lib/store' import { getFolderContent, getLesson, getLessons, getModuleTitle } from '@/lib/files' import { LessonLayout } from '@/layouts/Lesson' @@ -10,13 +9,7 @@ const LessonPage = ({ title, pdfURL, mdxSource, frontMatter, lessons }) => { return ( <> -
    {children}
, - Image: ({ children, ...props }) => {children}, - }} - /> +
) diff --git a/src/pages/academy/[module]/index.jsx b/src/pages/academy/[module]/index.jsx index 5793150..80574ac 100644 --- a/src/pages/academy/[module]/index.jsx +++ b/src/pages/academy/[module]/index.jsx @@ -1,5 +1,4 @@ -import { MDXRemote } from 'next-mdx-remote' - +import MDX from '@/components/MDX' import useStore from '@/lib/store' import { ModuleLayout } from '@/layouts/Module' import { @@ -16,13 +15,7 @@ const Module = ({ mdxSource, title, lessons, frontMatter }) => { return ( <> -
    {children}
, - Image: ({ children, ...props }) => {children}, - }} - /> +
) diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 6634c9e..d014258 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -1,13 +1,13 @@ -import { useState, useEffect } from 'react' +// import { useState, useEffect } from 'react' import { motion } from 'framer-motion' -import { Bubbles } from '@/components/Bubbles' +// import { Bubbles } from '@/components/Bubbles' import { Container } from '@/components/Container' -import { learningBubbles } from '@/data/learningBubbles' -import { useAuth } from '@/hooks/useAuth' -import { Account } from '@/components/Account' +// import { learningBubbles } from '@/data/learningBubbles' +// import { useAuth } from '@/hooks/useAuth' +// import { Account } from '@/components/Account' // import { Auth } from '@/components/Auth/_Signin' -import { AuthModal } from '@/components/Auth' -import { supabase } from '@/lib/supabaseClient' +// import { AuthModal } from '@/components/Auth' +// import { supabase } from '@/lib/supabaseClient' const Home = ({ modules }) => { return ( diff --git a/src/pages/profile.jsx b/src/pages/profile.jsx index f68bfb1..34f24ef 100644 --- a/src/pages/profile.jsx +++ b/src/pages/profile.jsx @@ -11,12 +11,15 @@ const Profile = () => { <> {user &&
{JSON.stringify(user, null, 2)}
} +

+ Querés cambiar de cuenta cuenta o salir? +

diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..64c56b6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "@/data/*": ["public/data/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock index b9c2572..f1f5aec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2710,6 +2710,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.1.tgz#5e07e0cb2ff793aa7a1b41deae76221e6166049f" integrity sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw== +"@types/node@^16.3.3": + version "16.3.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.3.3.tgz#0c30adff37bbbc7a50eb9b58fae2a504d0d88038" + integrity sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ== + "@types/node@^8.5.7": version "8.10.66" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" @@ -2756,6 +2761,15 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@^17.0.14": + version "17.0.14" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.14.tgz#f0629761ca02945c4e8fea99b8177f4c5c61fb0f" + integrity sha512-0WwKHUbWuQWOce61UexYuWTGuGY/8JvtUe/dtQ6lR4sZ3UiylHotJeWpf3ArP9+DSGUoLY3wbU59VyMrJps5VQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/readable-stream@^2.3.9": version "2.3.10" resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.10.tgz#0f1a512ca30bec5e53d3282133b9237a703e7562" @@ -15496,6 +15510,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@^4.3.5: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== + unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"