diff --git a/__tests__/exif.test.ts b/__tests__/exif.test.ts index b3a20c72..ea770f9b 100644 --- a/__tests__/exif.test.ts +++ b/__tests__/exif.test.ts @@ -12,23 +12,35 @@ describe('EXIF', () => { expect(formatExposureTime(1.5)).toBe('1.5s'); }); it('exposure compensation', () => { + expect(formatExposureCompensation(1)).toBe('+1ev'); expect(formatExposureCompensation(-1)).toBe('-1ev'); expect(formatExposureCompensation(0)).toBe(undefined); expect(formatExposureCompensation(0.25)).toBe('+1/4ev'); expect(formatExposureCompensation(0.33)).toBe('+1/3ev'); expect(formatExposureCompensation(0.333)).toBe('+1/3ev'); + expect(formatExposureCompensation(-0.25)).toBe('-1/4ev'); + expect(formatExposureCompensation(-0.33)).toBe('-1/3ev'); + expect(formatExposureCompensation(-0.333)).toBe('-1/3ev'); expect(formatExposureCompensation(0.5)).toBe('+1/2ev'); + expect(formatExposureCompensation(0.4998458896569944)).toBe('+1/2ev'); expect(formatExposureCompensation(0.66)).toBe('+2/3ev'); expect(formatExposureCompensation(0.67)).toBe('+2/3ev'); expect(formatExposureCompensation(0.015625)).toBe('+1/64ev'); expect(formatExposureCompensation(-0.015625)).toBe('-1/64ev'); expect(formatExposureCompensation(1)).toBe('+1ev'); + expect(formatExposureCompensation(1.1)).toBe('+1 1/10ev'); + expect(formatExposureCompensation(-1.1)).toBe('-1 1/10ev'); + expect(formatExposureCompensation(1.7)).toBe('+1 7/10ev'); + expect(formatExposureCompensation(-1.7)).toBe('-1 7/10ev'); expect(formatExposureCompensation(-1.33)).toBe('-1 1/3ev'); expect(formatExposureCompensation(1.33)).toBe('+1 1/3ev'); expect(formatExposureCompensation(1.333)).toBe('+1 1/3ev'); expect(formatExposureCompensation(1.3333)).toBe('+1 1/3ev'); expect(formatExposureCompensation(1.5)).toBe('+1 1/2ev'); + expect(formatExposureCompensation(2.5)).toBe('+2 1/2ev'); + expect(formatExposureCompensation(-2.5)).toBe('-2 1/2ev'); expect(formatExposureCompensation(1.9960938)).toBe('+2ev'); + expect(formatExposureCompensation(-1.9960938)).toBe('-2ev'); // Ignore long fractions expect(formatExposureCompensation(-0.119)).toBe('-0.12ev'); expect(formatExposureCompensation(-0.112340989)).toBe('-0.11ev'); diff --git a/package.json b/package.json index 5a392a29..27f2ed18 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,15 @@ "dependencies": { "@aws-sdk/client-s3": "3.554.0", "@aws-sdk/s3-request-presigner": "3.554.0", - "@next/bundle-analyzer": "14.2.0", + "@next/bundle-analyzer": "14.2.1", "@radix-ui/react-dropdown-menu": "^2.0.6", "@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/forms": "^0.5.7", "@testing-library/jest-dom": "^6.4.2", - "@testing-library/react": "^15.0.1", + "@testing-library/react": "^15.0.2", "@types/jest": "^29.5.12", "@types/node": "^20.12.7", - "@types/react": "18.2.76", + "@types/react": "18.2.78", "@types/react-dom": "18.2.25", "@typescript-eslint/eslint-plugin": "^7.6.0", "@typescript-eslint/parser": "^7.6.0", @@ -29,23 +29,23 @@ "@vercel/kv": "^1.0.1", "@vercel/postgres": "0.8.0", "@vercel/speed-insights": "^1.0.10", - "ai": "^3.0.21", + "ai": "^3.0.22", "autoprefixer": "10.4.19", "camelcase-keys": "^9.1.3", "clsx": "^2.1.0", "cmdk": "^1.0.0", "date-fns": "^3.6.0", "eslint": "8.57.0", - "eslint-config-next": "14.2.0", + "eslint-config-next": "14.2.1", "exifr": "^7.1.3", "framer-motion": "^11.0.28", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "nanoid": "^5.0.7", - "next": "14.2.1-canary.0", + "next": "14.3.0-canary.5", "next-auth": "5.0.0-beta.15", "next-themes": "^0.3.0", - "openai": "^4.33.0", + "openai": "^4.33.1", "postcss": "8.4.38", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 468fbc5d..9154e7f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,11 +12,11 @@ dependencies: specifier: 3.554.0 version: 3.554.0 '@next/bundle-analyzer': - specifier: 14.2.0 - version: 14.2.0 + specifier: 14.2.1 + version: 14.2.1 '@radix-ui/react-dropdown-menu': specifier: ^2.0.6 - version: 2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) + version: 2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) '@tailwindcss/container-queries': specifier: ^0.1.1 version: 0.1.1(tailwindcss@3.4.3) @@ -27,8 +27,8 @@ dependencies: specifier: ^6.4.2 version: 6.4.2(@types/jest@29.5.12)(jest@29.7.0) '@testing-library/react': - specifier: ^15.0.1 - version: 15.0.1(react-dom@18.2.0)(react@18.2.0) + specifier: ^15.0.2 + version: 15.0.2(react-dom@18.2.0)(react@18.2.0) '@types/jest': specifier: ^29.5.12 version: 29.5.12 @@ -36,8 +36,8 @@ dependencies: specifier: ^20.12.7 version: 20.12.7 '@types/react': - specifier: 18.2.76 - version: 18.2.76 + specifier: 18.2.78 + version: 18.2.78 '@types/react-dom': specifier: 18.2.25 version: 18.2.25 @@ -52,7 +52,7 @@ dependencies: version: 1.0.3 '@vercel/analytics': specifier: ^1.2.2 - version: 1.2.2(next@14.2.1-canary.0)(react@18.2.0) + version: 1.2.2(next@14.3.0-canary.5)(react@18.2.0) '@vercel/blob': specifier: ^0.22.3 version: 0.22.3 @@ -64,10 +64,10 @@ dependencies: version: 0.8.0 '@vercel/speed-insights': specifier: ^1.0.10 - version: 1.0.10(next@14.2.1-canary.0)(react@18.2.0)(svelte@4.2.12)(vue@3.4.21) + version: 1.0.10(next@14.3.0-canary.5)(react@18.2.0)(svelte@4.2.12)(vue@3.4.21) ai: - specifier: ^3.0.21 - version: 3.0.21(react@18.2.0)(solid-js@1.8.15)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4) + specifier: ^3.0.22 + version: 3.0.22(react@18.2.0)(solid-js@1.8.15)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4) autoprefixer: specifier: 10.4.19 version: 10.4.19(postcss@8.4.38) @@ -79,7 +79,7 @@ dependencies: version: 2.1.0 cmdk: specifier: ^1.0.0 - version: 1.0.0(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.0(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) date-fns: specifier: ^3.6.0 version: 3.6.0 @@ -87,8 +87,8 @@ dependencies: specifier: 8.57.0 version: 8.57.0 eslint-config-next: - specifier: 14.2.0 - version: 14.2.0(eslint@8.57.0)(typescript@5.4.5) + specifier: 14.2.1 + version: 14.2.1(eslint@8.57.0)(typescript@5.4.5) exifr: specifier: ^7.1.3 version: 7.1.3 @@ -105,17 +105,17 @@ dependencies: specifier: ^5.0.7 version: 5.0.7 next: - specifier: 14.2.1-canary.0 - version: 14.2.1-canary.0(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) + specifier: 14.3.0-canary.5 + version: 14.3.0-canary.5(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) next-auth: specifier: 5.0.0-beta.15 - version: 5.0.0-beta.15(next@14.2.1-canary.0)(react@18.2.0) + version: 5.0.0-beta.15(next@14.3.0-canary.5)(react@18.2.0) next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.2.0)(react@18.2.0) openai: - specifier: ^4.33.0 - version: 4.33.0 + specifier: ^4.33.1 + version: 4.33.1 postcss: specifier: 8.4.38 version: 8.4.38 @@ -155,6 +155,22 @@ packages: resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} dev: false + /@ai-sdk/provider-utils@0.0.0(zod@3.22.4): + resolution: {integrity: sha512-A6gFv6EHimayd2c2ayWMpKwADgsRrJg4DYYFnvJ71TXaWuSom7vUoALIobcaggmZ76xuzi17cXPFYg2vVu04WA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + peerDependenciesMeta: + zod: + optional: true + dependencies: + '@ai-sdk/provider': 0.0.0 + eventsource-parser: 1.1.2 + nanoid: 3.3.6 + secure-json-parse: 2.7.0 + zod: 3.22.4 + dev: false + /@ai-sdk/provider@0.0.0: resolution: {integrity: sha512-Gbl9Ei8NPtM85gB/o8cY7s7CLGxK/U6QVheVaI3viFn7o6IpTfy1Ja389e2FXVMNJ4WHK2qYWSp5fAFDuKulTA==} engines: {node: '>=18'} @@ -1561,8 +1577,8 @@ packages: '@types/pg': 8.6.6 dev: false - /@next/bundle-analyzer@14.2.0: - resolution: {integrity: sha512-fFzOvgHJgqILHCoZnfBbjvvODbZNqVIVQOaMgzOrOfKnrz0RVZvaNYSXynCIpJK4J7TIhFW0bQ8vFjDhTDKSmQ==} + /@next/bundle-analyzer@14.2.1: + resolution: {integrity: sha512-Qwy3Mu/dfnu4rs2xzCy7gKZlwzZzYtiq/rjPcK/7xq3BHSyLthkHf1NAF8NNfjVTouDwo2KchisHrmAamUNWWw==} dependencies: webpack-bundle-analyzer: 4.10.1 transitivePeerDependencies: @@ -1570,18 +1586,18 @@ packages: - utf-8-validate dev: false - /@next/env@14.2.1-canary.0: - resolution: {integrity: sha512-rllz3+XPlNnFhE1/EaymITb7Ai3lbIi2BZnspuJ/gwAOmLOpu5AyZgiVE0U78iekmrg4/cZl0GdKi7yuzlVntw==} + /@next/env@14.3.0-canary.5: + resolution: {integrity: sha512-toVqlCXUkXlNEguu6n87eQjYoQJojR8AjV2zAYIAhUAI3f7oRKtpppmscdLl7WUNe6RUhXD/49YFp3dkj4GR/Q==} dev: false - /@next/eslint-plugin-next@14.2.0: - resolution: {integrity: sha512-QkM01VPhwcupezVevy9Uyl1rmpg2PimhMjkb+ySmnPgSKUUM/PGGRQxdFgMpHv/JzQoC8kRySgKeM441GiizcA==} + /@next/eslint-plugin-next@14.2.1: + resolution: {integrity: sha512-Fp+mthEBjkn8r9qd6o4JgxKp0IDEzW0VYHD8ZC05xS5/lFNwHKuOdr2kVhWG7BQCO9L6eeepshM1Wbs2T+LgSg==} dependencies: glob: 10.3.10 dev: false - /@next/swc-darwin-arm64@14.2.1-canary.0: - resolution: {integrity: sha512-IapSALkIwbNVKAlG27zxHZIcY3rdX3qCrAsxzClOH+YNrLj1aW+JseWVdnjNjZSOCbT6GdPGUgLUshMQVU5LSA==} + /@next/swc-darwin-arm64@14.3.0-canary.5: + resolution: {integrity: sha512-F0olKgxrVAEfgpCcb3xOLva7WHlX00Up9AoqNrKnz/PFWPZp9A7wIMz4ut5v+6yY4yp0GOE/hn+u1qoBGvQMow==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -1589,8 +1605,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@14.2.1-canary.0: - resolution: {integrity: sha512-MMpkmb6EFMjLQ0JlATK10Ynuu7CUdT1wy+6n7iedyQjfebspdU6pd17rT0LoY8fTi2XD7BPZ/lBET+7WU42b2w==} + /@next/swc-darwin-x64@14.3.0-canary.5: + resolution: {integrity: sha512-0USyezfBpMJVaXOlvj/0QkFXE3ImgDFVSq0NXItQMkJa9yJHJ/JkoysJZrLTgt9smbum1DfTB3+QqD0sLokY0g==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -1598,8 +1614,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@14.2.1-canary.0: - resolution: {integrity: sha512-UOSTH9FQXHK3r6Z6yl7QmjUAMCV5H3mF1kwPhKAtDq/tOFJlK58xUCxL7NNBZ9JZnWsPaBGBvq8BC7ZBo1+F3g==} + /@next/swc-linux-arm64-gnu@14.3.0-canary.5: + resolution: {integrity: sha512-4VPt6mBuLqjh5f7h/FTPbP/eJWuGrSdoD0QJ9zHH7InA8pug5gefyziWqE49//HISR5xq8ul7jpJHdBEEKvksA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1607,8 +1623,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@14.2.1-canary.0: - resolution: {integrity: sha512-BmaFCWkxTC3g8sAjCtiUqVjvw5koCvNPJHsBZoKZ7GnxC8CknM9yOJ0S+VPeDHhAGtlaUXmpWQ1Tl0zUSFvP4g==} + /@next/swc-linux-arm64-musl@14.3.0-canary.5: + resolution: {integrity: sha512-nMCmUApCBly9YvdaCEPk1GPcfVqHkeNAyeTEuVIAL+ijw5naDagscPJS4t581Tfpgm6zOP4uM1dV+FKQfZ8n4A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1616,8 +1632,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@14.2.1-canary.0: - resolution: {integrity: sha512-SzlkGXptu9SN05yRf0k0hEIEZnNreZhWAOmiF5kwMWjW83dJ9wjdGMU2caUChf52Q51GS3YCF1TLmCI3n88Tzg==} + /@next/swc-linux-x64-gnu@14.3.0-canary.5: + resolution: {integrity: sha512-1LRy+m2MzbOd3XfCn5qkMyg8A3VzRgL5g4/WlbP6cAt1nwxt3zBwftMm6+aoCFuQ+svYz2Gr5sP95/GXYw7JqA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1625,8 +1641,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@14.2.1-canary.0: - resolution: {integrity: sha512-WcGis1t9KHvQGeIzNvY1dSy5WH9avfvDD6Cb9gS9IHJgxCJYXQ66/VPSV/HcztNeLgESwh063+PTLIZB+sv5MA==} + /@next/swc-linux-x64-musl@14.3.0-canary.5: + resolution: {integrity: sha512-b+lhx4jR6mTsM3saAa74Gh3gy2fUKtB8mXQb+hQqZfKom+HrsTLcLOBBpqZtxcRhppaOdwvrBABaBTQkYZ7oAQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1634,8 +1650,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@14.2.1-canary.0: - resolution: {integrity: sha512-/LnWlZLThyiEl+nQXodwQCHNsTDV2YCCVEysUuI3wC0JevP7lhC3TujhEi0Z1Wqy+b5nFtn5WZqLSvLKEL2W6Q==} + /@next/swc-win32-arm64-msvc@14.3.0-canary.5: + resolution: {integrity: sha512-yqM6PylDR0XGwjT7EGU9e+GM0nOCUjFSBic8MKHWkRh9Gg0/HYVvLLDHtYtm7LASxalHMkyEdKE6HR5/Jmh6Rg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -1643,8 +1659,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@14.2.1-canary.0: - resolution: {integrity: sha512-LLGkJC2o53/O3YEQYqieAJNKbesSpZDBkAjAhxkoJAanmxfUaPaoV8+BYdG0dqewNtQkh8ehNncX/F6rxHBXfw==} + /@next/swc-win32-ia32-msvc@14.3.0-canary.5: + resolution: {integrity: sha512-8EKpJyGDyydJV2FYoLiDQZYicn8Boir1ijQicUO1yja8LBZmVC+dN24QH1upTLqVD53YaeQmy0aV0RsgikQQiQ==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -1652,8 +1668,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@14.2.1-canary.0: - resolution: {integrity: sha512-5vqMcp9dZf7Qe89035rQCexIpLBlWRWtlJwrksEdMPE6tp7zroR6PGJzYRfRrdqTz041MTMmkwpkHSMbwH+eqQ==} + /@next/swc-win32-x64-msvc@14.3.0-canary.5: + resolution: {integrity: sha512-GBKwhhRwphLe5e9MNT4QWov79+7Whbr+YwqTJqQ+ffAmFuKbmFFgn4p7SuTTR9wKu3mfLzUfO0QanhyyKWmz9Q==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1703,7 +1719,7 @@ packages: '@babel/runtime': 7.23.9 dev: false - /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} peerDependencies: '@types/react': '*' @@ -1717,14 +1733,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} peerDependencies: '@types/react': '*' @@ -1738,17 +1754,17 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} peerDependencies: '@types/react': '*' @@ -1758,11 +1774,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-context@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-context@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} peerDependencies: '@types/react': '*' @@ -1772,11 +1788,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: '@types/react': '*' @@ -1791,26 +1807,26 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.76)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.78)(react@18.2.0) dev: false - /@radix-ui/react-direction@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-direction@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} peerDependencies: '@types/react': '*' @@ -1820,11 +1836,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} peerDependencies: '@types/react': '*' @@ -1839,17 +1855,17 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-dropdown-menu@2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dropdown-menu@2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==} peerDependencies: '@types/react': '*' @@ -1864,19 +1880,19 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-menu': 2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-menu': 2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} peerDependencies: '@types/react': '*' @@ -1886,11 +1902,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} peerDependencies: '@types/react': '*' @@ -1904,16 +1920,16 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-id@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-id@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} peerDependencies: '@types/react': '*' @@ -1923,12 +1939,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-menu@2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-menu@2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==} peerDependencies: '@types/react': '*' @@ -1943,30 +1959,30 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.76)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.78)(react@18.2.0) dev: false - /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} peerDependencies: '@types/react': '*' @@ -1981,22 +1997,22 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.76)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.78)(react@18.2.0) '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.76 + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} peerDependencies: '@types/react': '*' @@ -2010,14 +2026,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: '@types/react': '*' @@ -2031,15 +2047,15 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} peerDependencies: '@types/react': '*' @@ -2053,14 +2069,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} peerDependencies: '@types/react': '*' @@ -2075,21 +2091,21 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 '@types/react-dom': 18.2.25 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-slot@1.0.2(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-slot@1.0.2(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: '@types/react': '*' @@ -2099,12 +2115,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: '@types/react': '*' @@ -2114,11 +2130,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} peerDependencies: '@types/react': '*' @@ -2128,12 +2144,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} peerDependencies: '@types/react': '*' @@ -2143,12 +2159,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} peerDependencies: '@types/react': '*' @@ -2158,11 +2174,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} peerDependencies: '@types/react': '*' @@ -2173,11 +2189,11 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 dev: false - /@radix-ui/react-use-size@1.0.1(@types/react@18.2.76)(react@18.2.0): + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} peerDependencies: '@types/react': '*' @@ -2187,8 +2203,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.76)(react@18.2.0) - '@types/react': 18.2.76 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@types/react': 18.2.78 react: 18.2.0 dev: false @@ -2748,8 +2764,8 @@ packages: redent: 3.0.0 dev: false - /@testing-library/react@15.0.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-I8u4qqGAuBg7C1/kRB9n7Oz9Pc/UHEkmiQRbJziSG8B13eZfAcAUn8TSP26ZIvfSeb68CngmtZbKKcRqcQKa3g==} + /@testing-library/react@15.0.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-5mzIpuytB1ctpyywvyaY2TAAUQVCZIGqwiqFQf6u9lvj/SJQepGUzNV18Xpk+NLCaCE2j7CWrZE0tEf9xLZYiQ==} engines: {node: '>=18'} peerDependencies: react: ^18.0.0 @@ -2891,11 +2907,11 @@ packages: /@types/react-dom@18.2.25: resolution: {integrity: sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==} dependencies: - '@types/react': 18.2.76 + '@types/react': 18.2.78 dev: false - /@types/react@18.2.76: - resolution: {integrity: sha512-T6z/v7YxpswDM61Vq5KoSPTJqCkroJfsDIsvXCr4+qOY6gik5Ju4w0jf67cpC5z7ydOnp/E0V0W08pDRy8u9Xw==} + /@types/react@18.2.78: + resolution: {integrity: sha512-qOwdPnnitQY4xKlKayt42q5W5UQrSHjgoXNVEtxeqdITJ99k4VXJOP3vt8Rkm9HmgJpH50UNU+rlqfkfWOqp0A==} dependencies: '@types/prop-types': 15.7.11 csstype: 3.1.3 @@ -3148,7 +3164,7 @@ packages: crypto-js: 4.2.0 dev: false - /@vercel/analytics@1.2.2(next@14.2.1-canary.0)(react@18.2.0): + /@vercel/analytics@1.2.2(next@14.3.0-canary.5)(react@18.2.0): resolution: {integrity: sha512-X0rctVWkQV1e5Y300ehVNqpOfSOufo7ieA5PIdna8yX/U7Vjz0GFsGf4qvAhxV02uQ2CVt7GYcrFfddXXK2Y4A==} peerDependencies: next: '>= 13' @@ -3159,7 +3175,7 @@ packages: react: optional: true dependencies: - next: 14.2.1-canary.0(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) + next: 14.3.0-canary.5(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 server-only: 0.0.1 dev: false @@ -3191,7 +3207,7 @@ packages: ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) dev: false - /@vercel/speed-insights@1.0.10(next@14.2.1-canary.0)(react@18.2.0)(svelte@4.2.12)(vue@3.4.21): + /@vercel/speed-insights@1.0.10(next@14.3.0-canary.5)(react@18.2.0)(svelte@4.2.12)(vue@3.4.21): resolution: {integrity: sha512-4uzdKB0RW6Ff2FkzshzjZ+RlJfLPxgm/00i0XXgxfMPhwnnsk92YgtqsxT9OcPLdJUyVU1DqFlSWWjIQMPkh0g==} requiresBuild: true peerDependencies: @@ -3215,7 +3231,7 @@ packages: vue-router: optional: true dependencies: - next: 14.2.1-canary.0(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) + next: 14.3.0-canary.5(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 svelte: 4.2.12 vue: 3.4.21(typescript@5.4.5) @@ -3348,9 +3364,9 @@ packages: humanize-ms: 1.2.1 dev: false - /ai@3.0.21(react@18.2.0)(solid-js@1.8.15)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4): - resolution: {integrity: sha512-ieWylO8pnrIO7tuGMEBUpa1rC+kFdnsdjM1qgO0nAi3INa+5lCB2iLJdTQSnhSZbmWQx3wDlnToaXSZRiZvc+Q==} - engines: {node: '>=14.6'} + /ai@3.0.22(react@18.2.0)(solid-js@1.8.15)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4): + resolution: {integrity: sha512-VkObPBejjUA9mSJBurVtMpwdqDqzrzjKvsrrj1SsKsUOH/pbmzL6U2ym61Sz8pQXuPYJqcm3SpYOfqrIMRUH0Q==} + engines: {node: '>=18'} peerDependencies: react: ^18.2.0 solid-js: ^1.7.7 @@ -3370,6 +3386,7 @@ packages: optional: true dependencies: '@ai-sdk/provider': 0.0.0 + '@ai-sdk/provider-utils': 0.0.0(zod@3.22.4) eventsource-parser: 1.1.2 json-schema: 0.4.0 jsondiffpatch: 0.6.0 @@ -3897,14 +3914,14 @@ packages: engines: {node: '>=6'} dev: false - /cmdk@1.0.0(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0): + /cmdk@1.0.0(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 dependencies: - '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.76)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -4382,8 +4399,8 @@ packages: source-map: 0.6.1 dev: false - /eslint-config-next@14.2.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-N0eQkn/wz557mIpW4JQWGEv4wGU8zvJ7emLHMS15uC18jjaU4kx6leR4U9QYT/eNghUZT7N9lBlfd8E4N0cp1w==} + /eslint-config-next@14.2.1(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-BgD0kPCWMlqoItRf3xe9fG0MqwObKfVch+f2ccwDpZiCJA8ghkz2wrASH+bI6nLZzGcOJOpMm1v1Q1euhfpt4Q==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 typescript: '>=3.3.1' @@ -4391,7 +4408,7 @@ packages: typescript: optional: true dependencies: - '@next/eslint-plugin-next': 14.2.0 + '@next/eslint-plugin-next': 14.2.1 '@rushstack/eslint-patch': 1.7.2 '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 @@ -6309,7 +6326,7 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: false - /next-auth@5.0.0-beta.15(next@14.2.1-canary.0)(react@18.2.0): + /next-auth@5.0.0-beta.15(next@14.3.0-canary.5)(react@18.2.0): resolution: {integrity: sha512-UQggNq8CDu3/w8CYkihKLLnRPNXel98K0j7mtjj9a6XTNYo4Hni8xg/2h1YhElW6vXE8mgtvmH11rU8NKw86jQ==} peerDependencies: '@simplewebauthn/browser': ^9.0.1 @@ -6326,7 +6343,7 @@ packages: optional: true dependencies: '@auth/core': 0.28.0 - next: 14.2.1-canary.0(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) + next: 14.3.0-canary.5(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 dev: false @@ -6340,8 +6357,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /next@14.2.1-canary.0(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-tecwgTemv3NIM4EhvI8xsVBPzGWJZdAgcqauzErZnWxbf2QRy1ngABVPvO3TF5KROukjU0SG8275CtBCl6w7RQ==} + /next@14.3.0-canary.5(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-TC0l2QmuGU+NL+qsTVlvZeaRjrq1ifGILJ2cOcSlwJexQtjGMykmElqANuBMAd/OVEweXtafWju601ONydDJaA==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -6358,7 +6375,7 @@ packages: sass: optional: true dependencies: - '@next/env': 14.2.1-canary.0 + '@next/env': 14.3.0-canary.5 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001600 @@ -6368,15 +6385,15 @@ packages: react-dom: 18.2.0(react@18.2.0) styled-jsx: 5.1.1(@babel/core@7.23.9)(react@18.2.0) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.1-canary.0 - '@next/swc-darwin-x64': 14.2.1-canary.0 - '@next/swc-linux-arm64-gnu': 14.2.1-canary.0 - '@next/swc-linux-arm64-musl': 14.2.1-canary.0 - '@next/swc-linux-x64-gnu': 14.2.1-canary.0 - '@next/swc-linux-x64-musl': 14.2.1-canary.0 - '@next/swc-win32-arm64-msvc': 14.2.1-canary.0 - '@next/swc-win32-ia32-msvc': 14.2.1-canary.0 - '@next/swc-win32-x64-msvc': 14.2.1-canary.0 + '@next/swc-darwin-arm64': 14.3.0-canary.5 + '@next/swc-darwin-x64': 14.3.0-canary.5 + '@next/swc-linux-arm64-gnu': 14.3.0-canary.5 + '@next/swc-linux-arm64-musl': 14.3.0-canary.5 + '@next/swc-linux-x64-gnu': 14.3.0-canary.5 + '@next/swc-linux-x64-musl': 14.3.0-canary.5 + '@next/swc-win32-arm64-msvc': 14.3.0-canary.5 + '@next/swc-win32-ia32-msvc': 14.3.0-canary.5 + '@next/swc-win32-x64-msvc': 14.3.0-canary.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -6523,8 +6540,8 @@ packages: mimic-fn: 2.1.0 dev: false - /openai@4.33.0: - resolution: {integrity: sha512-Sh4KvplkvkAREuhb8yZpohqsOo08cBBu6LNWLD8YyMxe8yCxbE+ouJYUs1X2oDPrzQGANj0rFNQYiwW9gWLBOg==} + /openai@4.33.1: + resolution: {integrity: sha512-0DH572aSxGTT1JPOXgJQ9mjiuSPg/7scPot8hLc5I1mfQxPxLXTZWJpWerKaIWOuPkR2nrB0SamGDEehH8RuWA==} hasBin: true dependencies: '@types/node': 18.19.24 @@ -6911,7 +6928,7 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: false - /react-remove-scroll-bar@2.3.4(@types/react@18.2.76)(react@18.2.0): + /react-remove-scroll-bar@2.3.4(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} engines: {node: '>=10'} peerDependencies: @@ -6921,13 +6938,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 - react-style-singleton: 2.2.1(@types/react@18.2.76)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.78)(react@18.2.0) tslib: 2.6.2 dev: false - /react-remove-scroll@2.5.5(@types/react@18.2.76)(react@18.2.0): + /react-remove-scroll@2.5.5(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} engines: {node: '>=10'} peerDependencies: @@ -6937,16 +6954,16 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 - react-remove-scroll-bar: 2.3.4(@types/react@18.2.76)(react@18.2.0) - react-style-singleton: 2.2.1(@types/react@18.2.76)(react@18.2.0) + react-remove-scroll-bar: 2.3.4(@types/react@18.2.78)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.78)(react@18.2.0) tslib: 2.6.2 - use-callback-ref: 1.3.1(@types/react@18.2.76)(react@18.2.0) - use-sidecar: 1.1.2(@types/react@18.2.76)(react@18.2.0) + use-callback-ref: 1.3.1(@types/react@18.2.78)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.78)(react@18.2.0) dev: false - /react-style-singleton@2.2.1(@types/react@18.2.76)(react@18.2.0): + /react-style-singleton@2.2.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} peerDependencies: @@ -6956,7 +6973,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.76 + '@types/react': 18.2.78 get-nonce: 1.0.1 invariant: 2.2.4 react: 18.2.0 @@ -7789,7 +7806,7 @@ packages: requires-port: 1.0.0 dev: false - /use-callback-ref@1.3.1(@types/react@18.2.76)(react@18.2.0): + /use-callback-ref@1.3.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==} engines: {node: '>=10'} peerDependencies: @@ -7799,7 +7816,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.76 + '@types/react': 18.2.78 react: 18.2.0 tslib: 2.6.2 dev: false @@ -7813,7 +7830,7 @@ packages: react: 18.2.0 dev: false - /use-sidecar@1.1.2(@types/react@18.2.76)(react@18.2.0): + /use-sidecar@1.1.2(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} peerDependencies: @@ -7823,7 +7840,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.76 + '@types/react': 18.2.78 detect-node-es: 1.1.0 react: 18.2.0 tslib: 2.6.2 diff --git a/src/utility/number.ts b/src/utility/number.ts index 701e9f15..2d36bf11 100644 --- a/src/utility/number.ts +++ b/src/utility/number.ts @@ -14,10 +14,13 @@ const gcd = (a: number, b: number): number => { } }; -const formatDecimalToFraction = (decimal: number) => { - if (Math.abs(decimal - 0.33) < 0.011) { +const formatDecimalToFraction = (_decimal: number) => { + // Prevent imprecision which causes numbers such as, + // 0.1 to equal 0.10000000000000009 + const decimal = parseFloat(_decimal.toPrecision(8)); + if (Math.abs(Math.abs(decimal) - 0.33) < 0.011) { return '1/3'; - } else if (Math.abs(decimal - 0.66) <= 0.011) { + } else if (Math.abs(Math.abs(decimal) - 0.66) <= 0.011) { return '2/3'; } else { const length = decimal.toString().length - 2; @@ -34,21 +37,41 @@ const formatDecimalToFraction = (decimal: number) => { } }; +const STICKY_THRESHOLD = 0.011; +const STICKY_DECIMALS = [0.25, 0.33, 0.5, 0.66, 0.75]; +const MAX_FRACTION_LENGTH = 4; // Permit 1/64 but not 1/100 + export const formatNumberToFraction = (number: number) => { - const decimal = (1 - number % 1) > 0.01 + const sign = number >= 0 ? '+' : '-'; + + let decimal = (1 - Math.abs(number % 1)) > STICKY_THRESHOLD ? number % 1 : 0; - const integer = Math.round(Math.abs(number - decimal)); + if (decimal !== 0) { + for (const stickyDecimal of STICKY_DECIMALS) { + if (Math.abs(Math.abs(decimal) - stickyDecimal) < STICKY_THRESHOLD) { + decimal = decimal < 0 ? -stickyDecimal : stickyDecimal; + break; + } + } + } + + let integer = Math.round(Math.abs(number - decimal)); + if (Math.abs(decimal) === 1) { + decimal = 0; + integer += 1; + } + const fraction = decimal !== 0 ? formatDecimalToFraction(Math.abs(decimal)) : ''; - const sign = number >= 0 ? '+' : '-'; - // Ensure fractions are not too long - if (!fraction || fraction.length <= 4) { - const whole = integer > 0 + + // Ensure fractions aren't too long + if (!fraction || fraction.length <= MAX_FRACTION_LENGTH) { + const integerString = integer > 0 ? fraction ? `${integer} ` : integer : fraction ? '' : '0'; - return `${sign}${whole}${fraction}`; + return `${sign}${integerString}${fraction}`; } else { const decimalFormatted = decimal.toPrecision(2).replace(/^-*0+/, ''); return `${sign}${integer}${decimalFormatted}`;