diff --git a/apps/marketing/package.json b/apps/marketing/package.json index 469fe7e11..5fd2ff59e 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -28,6 +28,7 @@ "react-dom": "18.2.0", "react-hook-form": "^7.43.9", "react-icons": "^4.8.0", + "recharts": "^2.7.2", "typescript": "5.1.6", "zod": "^3.21.4" }, diff --git a/apps/marketing/src/app/(marketing)/open/data.ts b/apps/marketing/src/app/(marketing)/open/data.ts new file mode 100644 index 000000000..fa831d08b --- /dev/null +++ b/apps/marketing/src/app/(marketing)/open/data.ts @@ -0,0 +1,95 @@ +export const TEAM_MEMBERS = [ + { + name: 'Timur Ercan', + role: 'Co-Founder, CEO', + salary: 95_000, + location: 'Germany', + joinDate: 'November 14th, 2022', + }, + { + name: 'Lucas Smith', + role: 'Co-Founder, CTO', + salary: 95_000, + location: 'Australia', + joinDate: 'April 19th, 2023', + }, + { + name: 'Ephraim Atta-Duncan', + role: 'Software Engineer - Intern (Part-Time)', + salary: 15_000, + location: 'Ghana', + joinDate: 'June 6th, 2023', + }, + { + name: 'Florent Merian', + role: 'Marketer - III', + salary: 80_000, + location: 'France', + joinDate: 'July 10th, 2023', + }, + { + name: 'David Nguyen', + role: 'Software Engineer - III', + salary: 100_000, + location: 'Australia', + joinDate: 'July 26th, 2023', + }, +]; + +export const FUNDING_RAISED = [ + { + date: '2023-05-20', + amount: 0, + }, + { + date: '2023-05-20', + amount: 300_000, + }, + { + date: '2023-07-25', + amount: 1_250_000, + }, +]; + +export const SALARY_BANDS = [ + { + title: 'Software Engineer - Intern', + seniority: 'Intern', + salary: 30_000, + }, + { + title: 'Software Engineer - I', + seniority: 'Junior', + salary: 60_000, + }, + { + title: 'Software Engineer - II', + seniority: 'Mid', + salary: 80_000, + }, + { + title: 'Software Engineer - III', + seniority: 'Senior', + salary: 100_000, + }, + { + title: 'Software Engineer - IV', + seniority: 'Principal', + salary: 120_000, + }, + { + title: 'Marketer - I', + seniority: 'Junior', + salary: 50_000, + }, + { + title: 'Marketer - II', + seniority: 'Mid', + salary: 65_000, + }, + { + title: 'Marketer - III', + seniority: 'Senior', + salary: 80_000, + }, +]; diff --git a/apps/marketing/src/app/(marketing)/open/funding-raised.tsx b/apps/marketing/src/app/(marketing)/open/funding-raised.tsx new file mode 100644 index 000000000..75ba2b2f7 --- /dev/null +++ b/apps/marketing/src/app/(marketing)/open/funding-raised.tsx @@ -0,0 +1,51 @@ +'use client'; + +import { HTMLAttributes } from 'react'; + +import { Bar, BarChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'; + +import { cn } from '@documenso/ui/lib/utils'; + +import { FUNDING_RAISED } from '~/app/(marketing)/open/data'; + +export type FundingRaisedProps = HTMLAttributes; + +export const FundingRaised = ({ className, ...props }: FundingRaisedProps) => { + return ( +
+

Funding Raised

+ +
+ + + + + Number(value).toLocaleString('en-US', { + style: 'currency', + currency: 'USD', + maximumFractionDigits: 0, + }) + } + /> + [ + Number(value).toLocaleString('en-US', { + style: 'currency', + currency: 'USD', + maximumFractionDigits: 0, + }), + 'Amount Raised', + ]} + cursor={{ fill: 'hsl(var(--primary) / 10%)' }} + /> + + + +
+
+ ); +}; diff --git a/apps/marketing/src/app/(marketing)/open/metric-card.tsx b/apps/marketing/src/app/(marketing)/open/metric-card.tsx new file mode 100644 index 000000000..6235f4f5e --- /dev/null +++ b/apps/marketing/src/app/(marketing)/open/metric-card.tsx @@ -0,0 +1,18 @@ +import { HTMLAttributes } from 'react'; + +import { cn } from '@documenso/ui/lib/utils'; + +export type MetricCardProps = HTMLAttributes & { + title: string; + value: string; +}; + +export const MetricCard = ({ className, title, value, ...props }: MetricCardProps) => { + return ( +
+

{title}

+ +

{value}

+
+ ); +}; diff --git a/apps/marketing/src/app/(marketing)/open/page.tsx b/apps/marketing/src/app/(marketing)/open/page.tsx new file mode 100644 index 000000000..0ab3318fd --- /dev/null +++ b/apps/marketing/src/app/(marketing)/open/page.tsx @@ -0,0 +1,99 @@ +import { z } from 'zod'; + +import { MetricCard } from '~/app/(marketing)/open/metric-card'; +import { SalaryBands } from '~/app/(marketing)/open/salary-bands'; + +import { FundingRaised } from './funding-raised'; +import { TeamMembers } from './team-members'; + +export const revalidate = 86400; + +const ZGithubStatsResponse = z.object({ + stargazers_count: z.number(), + forks_count: z.number(), + open_issues: z.number(), +}); + +const ZMergedPullRequestsResponse = z.object({ + total_count: z.number(), +}); + +// const ZOpenPullRequestsResponse = ZMergedPullRequestsResponse; + +export default async function OpenPage() { + const { + forks_count: forksCount, + open_issues: openIssues, + stargazers_count: stargazersCount, + } = await fetch('https://api.github.com/repos/documenso/documenso', { + headers: { + accept: 'application/vnd.github.v3+json', + }, + }) + .then((res) => res.json()) + .then((res) => ZGithubStatsResponse.parse(res)); + + const { total_count: mergedPullRequests } = await fetch( + 'https://api.github.com/search/issues?q=repo:documenso/documenso/+is:pr+merged:>=2010-01-01&page=0&per_page=1', + { + headers: { + accept: 'application/vnd.github.v3+json', + }, + }, + ) + .then((res) => res.json()) + .then((res) => ZMergedPullRequestsResponse.parse(res)); + + return ( +
+
+

Open Startup

+ +

+ All our metrics, finances, and learnings are public. We believe in transparency and want + to share our journey with you. +

+
+ +
+
+ + + + +
+ + + + + + + +
+

Where's the rest?

+ +

+ We're still working on getting all our metrics together. We'll update this page as soon + as we have more to share. +

+
+
+
+ ); +} diff --git a/apps/marketing/src/app/(marketing)/open/salary-bands.tsx b/apps/marketing/src/app/(marketing)/open/salary-bands.tsx new file mode 100644 index 000000000..31c254157 --- /dev/null +++ b/apps/marketing/src/app/(marketing)/open/salary-bands.tsx @@ -0,0 +1,50 @@ +import { HTMLAttributes } from 'react'; + +import { cn } from '@documenso/ui/lib/utils'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@documenso/ui/primitives/table'; + +import { SALARY_BANDS } from '~/app/(marketing)/open/data'; + +export type SalaryBandsProps = HTMLAttributes; + +export const SalaryBands = ({ className, ...props }: SalaryBandsProps) => { + return ( +
+

Global Salary Bands

+ +
+ + + + Title + Seniority + Salary + + + + {SALARY_BANDS.map((band, index) => ( + + {band.title} + {band.seniority} + + {band.salary.toLocaleString('en-US', { + style: 'currency', + currency: 'USD', + maximumFractionDigits: 0, + })} + + + ))} + +
+
+
+ ); +}; diff --git a/apps/marketing/src/app/(marketing)/open/team-members.tsx b/apps/marketing/src/app/(marketing)/open/team-members.tsx new file mode 100644 index 000000000..f14b5a73d --- /dev/null +++ b/apps/marketing/src/app/(marketing)/open/team-members.tsx @@ -0,0 +1,56 @@ +import { HTMLAttributes } from 'react'; + +import { cn } from '@documenso/ui/lib/utils'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@documenso/ui/primitives/table'; + +import { TEAM_MEMBERS } from './data'; + +export type TeamMembersProps = HTMLAttributes; + +export const TeamMembers = ({ className, ...props }: TeamMembersProps) => { + return ( +
+

Team

+ +
+ + + + Name + Role + {/* Status */} + Salary + Location + Join Date + + + + {TEAM_MEMBERS.map((member) => ( + + {member.name} + {member.role} + {/* {teamMember.employmentStatus} */} + + {member.salary.toLocaleString('en-US', { + style: 'currency', + currency: 'USD', + maximumFractionDigits: 0, + })} + + {member.location} + {member.joinDate} + + ))} + +
+
+
+ ); +}; diff --git a/apps/marketing/src/app/(marketing)/page.tsx b/apps/marketing/src/app/(marketing)/page.tsx index 9992c51a4..09e9e3dec 100644 --- a/apps/marketing/src/app/(marketing)/page.tsx +++ b/apps/marketing/src/app/(marketing)/page.tsx @@ -9,6 +9,8 @@ import { Hero } from '~/components/(marketing)/hero'; import { OpenBuildTemplateBento } from '~/components/(marketing)/open-build-template-bento'; import { ShareConnectPaidWidgetBento } from '~/components/(marketing)/share-connect-paid-widget-bento'; +export const revalidate = 600; + const fontCaveat = Caveat({ weight: ['500'], subsets: ['latin'], @@ -17,15 +19,24 @@ const fontCaveat = Caveat({ }); export default async function IndexPage() { + const starCount = await fetch('https://api.github.com/repos/documenso/documenso', { + headers: { + accept: 'application/vnd.github.v3+json', + }, + }) + .then((res) => res.json()) + .then((res) => (typeof res.stargazers_count === 'number' ? res.stargazers_count : undefined)) + .catch(() => undefined); + return (
- + - +
); } diff --git a/apps/marketing/src/components/(marketing)/callout.tsx b/apps/marketing/src/components/(marketing)/callout.tsx index 30a1abdbf..d83983141 100644 --- a/apps/marketing/src/components/(marketing)/callout.tsx +++ b/apps/marketing/src/components/(marketing)/callout.tsx @@ -7,7 +7,12 @@ import { usePlausible } from 'next-plausible'; import { Button } from '@documenso/ui/primitives/button'; -export const Callout = () => { +export type CalloutProps = { + starCount?: number; + [key: string]: unknown; +}; + +export const Callout = ({ starCount }: CalloutProps) => { const event = usePlausible(); const onSignUpClick = () => { @@ -36,7 +41,7 @@ export const Callout = () => { onClick={onSignUpClick} > Get the Community Plan - + $30/mo. forever! @@ -49,6 +54,11 @@ export const Callout = () => { diff --git a/apps/web/src/components/(marketing)/callout.tsx b/apps/web/src/components/(marketing)/callout.tsx index 0c2613ec8..d83983141 100644 --- a/apps/web/src/components/(marketing)/callout.tsx +++ b/apps/web/src/components/(marketing)/callout.tsx @@ -7,7 +7,12 @@ import { usePlausible } from 'next-plausible'; import { Button } from '@documenso/ui/primitives/button'; -export const Callout = () => { +export type CalloutProps = { + starCount?: number; + [key: string]: unknown; +}; + +export const Callout = ({ starCount }: CalloutProps) => { const event = usePlausible(); const onSignUpClick = () => { @@ -36,21 +41,26 @@ export const Callout = () => { onClick={onSignUpClick} > Get the Community Plan - + $30/mo. forever! - + {starCount && starCount > 0 && ( + + {starCount.toLocaleString('en-US')} + + )} + + ); }; diff --git a/apps/web/src/components/(marketing)/hero.tsx b/apps/web/src/components/(marketing)/hero.tsx index 7f7aa6d05..7896a010e 100644 --- a/apps/web/src/components/(marketing)/hero.tsx +++ b/apps/web/src/components/(marketing)/hero.tsx @@ -16,6 +16,7 @@ import { Widget } from './widget'; export type HeroProps = { className?: string; + starCount?: number; [key: string]: unknown; }; @@ -48,7 +49,7 @@ const HeroTitleVariants: Variants = { }, }; -export const Hero = ({ className, ...props }: HeroProps) => { +export const Hero = ({ className, starCount, ...props }: HeroProps) => { const event = usePlausible(); const onSignUpClick = () => { @@ -109,44 +110,44 @@ export const Hero = ({ className, ...props }: HeroProps) => { onClick={onSignUpClick} > Get the Community Plan - + $30/mo. forever! - - - - - - Documenso - The open source DocuSign alternative | Product Hunt + {starCount && starCount > 0 && ( + + {starCount.toLocaleString('en-US')} + + )} + +
+ + + Documenso - The open source DocuSign alternative | Product Hunt + + +
+ = 8" } }, + "node_modules/css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -5521,6 +5586,116 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -5565,6 +5740,11 @@ } } }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "node_modules/decode-named-character-reference": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", @@ -5784,6 +5964,14 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -6961,6 +7149,11 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/execa": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", @@ -7009,6 +7202,14 @@ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -7969,6 +8170,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -11188,6 +11397,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "node_modules/react-pdf": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.3.0.tgz", @@ -11274,6 +11488,18 @@ } } }, + "node_modules/react-resize-detector": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.1.0.tgz", + "integrity": "sha512-S7szxlaIuiy5UqLhLL1KY3aoyGHbZzsTpYal9eYMwCyKqoqoVLCmIgAgNyIM1FhnP2KyBygASJxdhejrzjMb+w==", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-rnd": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/react-rnd/-/react-rnd-10.4.1.tgz", @@ -11293,6 +11519,20 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, + "node_modules/react-smooth": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.3.tgz", + "integrity": "sha512-yl4y3XiMorss7ayF5QnBiSprig0+qFHui8uh7Hgg46QX5O+aRMRKlfGGNGLHno35JkQSvSYY8eCWkBfHfrSHfg==", + "dependencies": { + "fast-equals": "^5.0.0", + "react-transition-group": "2.9.0" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-ssr-prepass": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/react-ssr-prepass/-/react-ssr-prepass-1.5.0.tgz", @@ -11323,6 +11563,21 @@ } } }, + "node_modules/react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "dependencies": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0", + "react-dom": ">=15.0.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -11401,6 +11656,52 @@ "node": ">=8.10.0" } }, + "node_modules/recharts": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.7.2.tgz", + "integrity": "sha512-HMKRBkGoOXHW+7JcRa6+MukPSifNtJlqbc+JreGVNA407VLE/vOP+8n3YYjprDVVIF9E2ZgwWnL3D7K/LUFzBg==", + "dependencies": { + "classnames": "^2.2.5", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.19", + "react-is": "^16.10.2", + "react-resize-detector": "^8.0.4", + "react-smooth": "^2.0.2", + "recharts-scale": "^0.4.4", + "reduce-css-calc": "^2.1.8", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "dependencies": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/reduce-css-calc/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -13562,6 +13863,27 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/victory-vendor": { + "version": "36.6.11", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.11.tgz", + "integrity": "sha512-nT8kCiJp8dQh8g991J/R5w5eE2KnO8EAIP0xocWlh9l2okngMWglOPoMZzJvek8Q1KUc4XE/mJxTZnvOB1sTYg==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",