-
-
{t(title)}
-
- {t(description)}
-
- {buttons}
-
+
+
+
+
{t(title)}
+
+ {t(description)}
+
+ {buttons}
+
-
- {features.map((feature) => (
-
- {feature.icon}
-
{feature.title}
-
{feature.description}
-
- ))}
-
+
+ {features.map((feature) => (
+
+ {feature.icon}
+
{feature.title}
+
{feature.description}
+
+ ))}
>
);
diff --git a/packages/prisma/package.json b/packages/prisma/package.json
index 047c11436c5ac..4bd768baa467b 100644
--- a/packages/prisma/package.json
+++ b/packages/prisma/package.json
@@ -16,7 +16,8 @@
"generate-schemas": "prisma generate && prisma format",
"post-install": "yarn generate-schemas",
"seed-app-store": "ts-node --transpile-only ./seed-app-store.ts",
- "delete-app": "ts-node --transpile-only ./delete-app.ts"
+ "delete-app": "ts-node --transpile-only ./delete-app.ts",
+ "seed-analytics": "ts-node --transpile-only ./seed-analytics.ts"
},
"devDependencies": {
"npm-run-all": "^4.1.5"
diff --git a/packages/prisma/seed-analytics.ts b/packages/prisma/seed-analytics.ts
new file mode 100644
index 0000000000000..9e9b9e4b0efc0
--- /dev/null
+++ b/packages/prisma/seed-analytics.ts
@@ -0,0 +1,234 @@
+import type { Prisma } from "@prisma/client";
+import { BookingStatus, PrismaClient } from "@prisma/client";
+import { v4 as uuidv4 } from "uuid";
+
+import dayjs from "@calcom/dayjs";
+import { hashPassword } from "@calcom/features/auth/lib/hashPassword";
+
+const prisma = new PrismaClient();
+async function main() {
+ // First find if not then create everything
+ let insightsAdmin = await prisma.user.findFirst({
+ where: {
+ email: "insights@example.com",
+ },
+ });
+
+ if (!insightsAdmin) {
+ insightsAdmin = await prisma.user.create({
+ data: {
+ email: "insights@example.com",
+ password: await hashPassword("insights"),
+ name: "Insights Admin",
+ role: "ADMIN",
+ username: "insights",
+ completedOnboarding: true,
+ },
+ });
+ }
+
+ let insightsUser = await prisma.user.findFirst({
+ where: {
+ email: "insightuser@example.com",
+ },
+ });
+
+ if (!insightsUser) {
+ insightsUser = await prisma.user.create({
+ data: {
+ email: "insightuser@example.com",
+ password: await hashPassword("insightsuser"),
+ name: "Insights User",
+ role: "USER",
+ username: "insights-user",
+ completedOnboarding: true,
+ },
+ });
+ }
+
+ let insightsTeam = await prisma.team.findFirst({
+ where: {
+ slug: "insights-team",
+ },
+ });
+
+ if (!insightsTeam) {
+ insightsTeam = await prisma.team.create({
+ data: {
+ name: "Insights",
+ slug: "insights-team",
+ },
+ });
+ await prisma.membership.createMany({
+ data: [
+ {
+ teamId: insightsTeam.id,
+ userId: insightsAdmin.id,
+ role: "OWNER",
+ accepted: true,
+ },
+ {
+ teamId: insightsTeam.id,
+ userId: insightsUser.id,
+ role: "MEMBER",
+ accepted: true,
+ },
+ ],
+ });
+ await prisma.team.update({
+ where: {
+ id: insightsTeam.id,
+ },
+ data: {
+ members: {
+ connect: {
+ userId_teamId: {
+ userId: insightsAdmin.id,
+ teamId: insightsTeam.id,
+ },
+ },
+ },
+ },
+ });
+ }
+ await prisma.team.update({
+ where: {
+ id: insightsTeam.id,
+ },
+ data: {
+ members: {
+ connect: {
+ userId_teamId: {
+ userId: insightsUser.id,
+ teamId: insightsTeam.id,
+ },
+ },
+ },
+ },
+ });
+
+ let teamEvents = await prisma.eventType.findMany({
+ where: {
+ teamId: insightsTeam.id,
+ },
+ });
+
+ if (teamEvents.length === 0) {
+ await prisma.eventType.createMany({
+ data: [
+ {
+ title: "Team Meeting",
+ slug: "team-meeting",
+ description: "Team Meeting",
+ length: 60,
+ teamId: insightsTeam.id,
+ schedulingType: "ROUND_ROBIN",
+ },
+ {
+ title: "Team Lunch",
+ slug: "team-lunch",
+ description: "Team Lunch",
+ length: 30,
+ teamId: insightsTeam.id,
+ schedulingType: "COLLECTIVE",
+ },
+ {
+ title: "Team Coffee",
+ slug: "team-coffee",
+ description: "Team Coffee",
+ length: 15,
+ teamId: insightsTeam.id,
+ schedulingType: "COLLECTIVE",
+ },
+ ],
+ });
+ } else {
+ teamEvents = await prisma.eventType.findMany({
+ where: {
+ teamId: insightsTeam.id,
+ },
+ });
+ }
+
+ const baseBooking: Prisma.BookingCreateManyInput = {
+ uid: "demoUID",
+ title: "Team Meeting",
+ description: "Team Meeting",
+ startTime: dayjs().toISOString(),
+ endTime: dayjs().toISOString(),
+ userId: insightsUser.id,
+ eventTypeId: teamEvents[0].id,
+ };
+
+ const shuffle = (booking: typeof baseBooking, year) => {
+ const startTime = dayjs(booking.startTime)
+ .add(Math.floor(Math.random() * 365), "day")
+ .add(Math.floor(Math.random() * 24), "hour")
+ .add(Math.floor(Math.random() * 60), "minute")
+ .set("y", year);
+ const randomEvent = teamEvents[Math.floor(Math.random() * teamEvents.length)];
+ const endTime = dayjs(startTime).add(Math.floor(Math.random() * randomEvent.length), "minute");
+
+ booking.startTime = startTime.toISOString();
+ booking.endTime = endTime.toISOString();
+ booking.createdAt = startTime.subtract(1, "day").toISOString();
+
+ // Pick a random status
+ const randomStatusIndex = Math.floor(Math.random() * Object.keys(BookingStatus).length);
+ const statusKey = Object.keys(BookingStatus)[randomStatusIndex];
+
+ booking.status = BookingStatus[statusKey];
+
+ booking.rescheduled = Math.random() > 0.5 && Math.random() > 0.5 && Math.random() > 0.5;
+
+ if (booking.rescheduled) {
+ booking.status = "CANCELLED";
+ }
+ const randomEventTypeId = teamEvents[Math.floor(Math.random() * teamEvents.length)].id;
+
+ booking.eventTypeId = randomEventTypeId;
+ booking.uid = uuidv4();
+
+ if (insightsUser && insightsAdmin) {
+ booking.userId = Math.random() > 0.5 ? insightsUser.id : insightsAdmin.id;
+ }
+
+ return booking;
+ };
+
+ // Create past bookings
+ await prisma.booking.createMany({
+ data: [...new Array(100).fill(0).map(() => shuffle({ ...baseBooking }, dayjs().get("y") - 2))],
+ });
+
+ await prisma.booking.createMany({
+ data: [...new Array(100).fill(0).map(() => shuffle({ ...baseBooking }, dayjs().get("y") - 1))],
+ });
+
+ await prisma.booking.createMany({
+ data: [...new Array(100).fill(0).map(() => shuffle({ ...baseBooking }, dayjs().get("y")))],
+ });
+}
+main()
+ .then(async () => {
+ await prisma.$disconnect();
+ })
+ .catch(async (e) => {
+ console.error(e);
+ await prisma.user.deleteMany({
+ where: {
+ email: {
+ in: ["insights@example", "insightsuser@example.com"],
+ },
+ },
+ });
+
+ await prisma.team.deleteMany({
+ where: {
+ slug: "insights",
+ },
+ });
+
+ await prisma.$disconnect();
+ process.exit(1);
+ });
diff --git a/packages/trpc/server/routers/viewer.tsx b/packages/trpc/server/routers/viewer.tsx
index bf3457ea3c179..de13e9a64b776 100644
--- a/packages/trpc/server/routers/viewer.tsx
+++ b/packages/trpc/server/routers/viewer.tsx
@@ -23,10 +23,10 @@ import { sendCancelledEmails, sendFeedbackEmail } from "@calcom/emails";
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
import { verifyPassword } from "@calcom/features/auth/lib/verifyPassword";
import { samlTenantProduct } from "@calcom/features/ee/sso/lib/saml";
+import { insightsRouter } from "@calcom/features/insights/server/trpc-router";
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
import getEnabledApps from "@calcom/lib/apps/getEnabledApps";
-import { IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants";
-import { FULL_NAME_LENGTH_MAX_LIMIT } from "@calcom/lib/constants";
+import { FULL_NAME_LENGTH_MAX_LIMIT, IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants";
import { symmetricDecrypt } from "@calcom/lib/crypto";
import getPaymentAppData from "@calcom/lib/getPaymentAppData";
import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata";
@@ -1273,6 +1273,7 @@ export const viewerRouter = mergeRouters(
slots: slotsRouter,
workflows: workflowsRouter,
saml: ssoRouter,
+ insights: insightsRouter,
// NOTE: Add all app related routes in the bottom till the problem described in @calcom/app-store/trpc-routers.ts is solved.
// After that there would just one merge call here for all the apps.
appRoutingForms: app_RoutingForms,
diff --git a/packages/trpc/server/trpc.ts b/packages/trpc/server/trpc.ts
index be54d719d19d9..f15bfae37eee1 100644
--- a/packages/trpc/server/trpc.ts
+++ b/packages/trpc/server/trpc.ts
@@ -4,6 +4,7 @@ import superjson from "superjson";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { defaultAvatarSrc } from "@calcom/lib/defaultAvatarImage";
+import rateLimit from "@calcom/lib/rateLimit";
import prisma from "@calcom/prisma";
import type { Maybe } from "@trpc/server";
@@ -103,7 +104,7 @@ const perfMiddleware = t.middleware(async ({ path, type, next }) => {
return result;
});
-const isAuthed = t.middleware(async ({ ctx: { session, locale, ...ctx }, next }) => {
+export const isAuthed = t.middleware(async ({ ctx: { session, locale, ...ctx }, next }) => {
const user = await getUserFromSession({ session });
if (!user || !session) {
throw new TRPCError({ code: "UNAUTHORIZED" });
@@ -135,10 +136,37 @@ const isAdminMiddleware = isAuthed.unstable_pipe(({ ctx, next }) => {
});
});
+interface IRateLimitOptions {
+ intervalInMs: number;
+ limit: number;
+}
+const isRateLimitedByUserIdMiddleware = ({ intervalInMs, limit }: IRateLimitOptions) =>
+ t.middleware(({ ctx, next }) => {
+ // validate user exists
+ if (!ctx.user) {
+ throw new TRPCError({ code: "UNAUTHORIZED" });
+ }
+
+ const { isRateLimited } = rateLimit({ intervalInMs }).check(limit, ctx.user.id.toString());
+
+ if (isRateLimited) {
+ throw new TRPCError({ code: "TOO_MANY_REQUESTS" });
+ }
+
+ return next({
+ ctx: {
+ // infers that `user` and `session` are non-nullable to downstream procedures
+ session: ctx.session,
+ user: ctx.user,
+ },
+ });
+ });
+
export const router = t.router;
export const mergeRouters = t.mergeRouters;
export const middleware = t.middleware;
export const publicProcedure = t.procedure.use(perfMiddleware);
export const authedProcedure = t.procedure.use(perfMiddleware).use(isAuthed);
-
+export const authedRateLimitedProcedure = ({ intervalInMs, limit }: IRateLimitOptions) =>
+ authedProcedure.use(isRateLimitedByUserIdMiddleware({ intervalInMs, limit }));
export const authedAdminProcedure = t.procedure.use(perfMiddleware).use(isAdminMiddleware);
diff --git a/yarn.lock b/yarn.lock
index a9aa33bfec457..570444396ea6f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3534,6 +3534,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.20.13":
+ version: 7.21.0
+ resolution: "@babel/runtime@npm:7.21.0"
+ dependencies:
+ regenerator-runtime: ^0.13.11
+ checksum: 7b33e25bfa9e0e1b9e8828bb61b2d32bdd46b41b07ba7cb43319ad08efc6fda8eb89445193e67d6541814627df0ca59122c0ea795e412b99c5183a0540d338ab
+ languageName: node
+ linkType: hard
+
"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.5.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4":
version: 7.18.6
resolution: "@babel/runtime@npm:7.18.6"
@@ -3561,15 +3570,6 @@ __metadata:
languageName: node
linkType: hard
-"@babel/runtime@npm:^7.20.13":
- version: 7.21.0
- resolution: "@babel/runtime@npm:7.21.0"
- dependencies:
- regenerator-runtime: ^0.13.11
- checksum: 7b33e25bfa9e0e1b9e8828bb61b2d32bdd46b41b07ba7cb43319ad08efc6fda8eb89445193e67d6541814627df0ca59122c0ea795e412b99c5183a0540d338ab
- languageName: node
- linkType: hard
-
"@babel/runtime@npm:~7.5.4":
version: 7.5.5
resolution: "@babel/runtime@npm:7.5.5"
@@ -4411,6 +4411,7 @@ __metadata:
dependencies:
"@calcom/dayjs": "*"
"@calcom/lib": "*"
+ "@calcom/trpc": "*"
"@calcom/ui": "*"
"@lexical/react": ^0.5.0
dompurify: ^2.4.1
@@ -4935,6 +4936,7 @@ __metadata:
"@stripe/stripe-js": ^1.35.0
"@tanstack/react-query": ^4.3.9
"@testing-library/react": ^13.3.0
+ "@tremor/react": ^2.0.0
"@types/accept-language-parser": 1.5.2
"@types/async": ^3.2.15
"@types/bcryptjs": ^2.4.2
@@ -6441,7 +6443,7 @@ __metadata:
languageName: node
linkType: hard
-"@floating-ui/react-dom@npm:^1.0.0":
+"@floating-ui/react-dom@npm:^1.0.0, @floating-ui/react-dom@npm:^1.3.0":
version: 1.3.0
resolution: "@floating-ui/react-dom@npm:1.3.0"
dependencies:
@@ -6453,6 +6455,20 @@ __metadata:
languageName: node
linkType: hard
+"@floating-ui/react@npm:^0.19.1":
+ version: 0.19.2
+ resolution: "@floating-ui/react@npm:0.19.2"
+ dependencies:
+ "@floating-ui/react-dom": ^1.3.0
+ aria-hidden: ^1.1.3
+ tabbable: ^6.0.1
+ peerDependencies:
+ react: ">=16.8.0"
+ react-dom: ">=16.8.0"
+ checksum: 00fd827c2dcf879fec221d89ef5b90836bbecacc236ce2acc787db32ae7311d490cd136b13a8d0b6ab12842554a2ee1110605aa832af71a45c0a7297e342072c
+ languageName: node
+ linkType: hard
+
"@formatjs/ecma402-abstract@npm:1.11.4":
version: 1.11.4
resolution: "@formatjs/ecma402-abstract@npm:1.11.4"
@@ -12068,6 +12084,21 @@ __metadata:
languageName: node
linkType: hard
+"@tremor/react@npm:^2.0.0":
+ version: 2.0.2
+ resolution: "@tremor/react@npm:2.0.2"
+ dependencies:
+ "@floating-ui/react": ^0.19.1
+ date-fns: ^2.28.0
+ react-transition-group: ^4.4.5
+ recharts: ^2.3.2
+ tailwind-merge: ^1.9.1
+ peerDependencies:
+ react: ^18.0.0
+ checksum: 4002a062a3bcdc164904187ffe53934d26edbb8d342a3f756b99c32beb0d997bf0937fdda39526d964e34cc996231b485fc68fc4a580c1d009b4a2fcb8ebdc27
+ languageName: node
+ linkType: hard
+
"@trivago/prettier-plugin-sort-imports@npm:3.2.0":
version: 3.2.0
resolution: "@trivago/prettier-plugin-sort-imports@npm:3.2.0"
@@ -12346,6 +12377,75 @@ __metadata:
languageName: node
linkType: hard
+"@types/d3-array@npm:^3.0.3":
+ version: 3.0.4
+ resolution: "@types/d3-array@npm:3.0.4"
+ checksum: b0e398365fc1f638d48442e865e036d671c731b2b18f7a92e5172db1f60f5a38d4cd992693a29ad64b38e7ba981eb8c63a2aef95fbdcfbc4bf8926a9cb9ca978
+ languageName: node
+ linkType: hard
+
+"@types/d3-color@npm:*":
+ version: 3.1.0
+ resolution: "@types/d3-color@npm:3.1.0"
+ checksum: b1856f17d6366559a68eaba0164f30727e9dc5eaf1b3a6c8844354da228860240423d19fa4de65bff9da26b4ead8843eab14b1566962665412e8fd82c3810554
+ languageName: node
+ linkType: hard
+
+"@types/d3-ease@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "@types/d3-ease@npm:3.0.0"
+ checksum: 1be7c993643b5a08332e0ee146375a3845545d8deb423db5d152e0b061524385d2345ceccf968f75f605247b940dd3f9a144335fee2e7d935cddaf187afb7095
+ languageName: node
+ linkType: hard
+
+"@types/d3-interpolate@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "@types/d3-interpolate@npm:3.0.1"
+ dependencies:
+ "@types/d3-color": "*"
+ checksum: 29ce472968b9e6611bdf0eeedaf89e8d6066190b52ced011d16d8183b8b9f8e6dd6516ca2b85242594942896299b42f37504d44e635f8fba3090c2c58594e21b
+ languageName: node
+ linkType: hard
+
+"@types/d3-path@npm:*":
+ version: 3.0.0
+ resolution: "@types/d3-path@npm:3.0.0"
+ checksum: af7f45ea912cddd794c03384baba856f11e1f9b57a49d05a66a61968dafaeb86e0e42394883118b9b8ccadce21a5f25b1f9a88ad05235e1dc6d24c3e34a379ff
+ languageName: node
+ linkType: hard
+
+"@types/d3-scale@npm:^4.0.2":
+ version: 4.0.3
+ resolution: "@types/d3-scale@npm:4.0.3"
+ dependencies:
+ "@types/d3-time": "*"
+ checksum: 76684da8519ab5f2210e647f74f96ece9c6816dea4ad5d76131121703a5268cc65687a8bc9ebbf4a44039482247336d98811ecc3fbfeb7f0122fdce4bb295547
+ languageName: node
+ linkType: hard
+
+"@types/d3-shape@npm:^3.1.0":
+ version: 3.1.1
+ resolution: "@types/d3-shape@npm:3.1.1"
+ dependencies:
+ "@types/d3-path": "*"
+ checksum: 8f1762ecdeb4833a3802be1c65363cbc7cca753d0b836a3855fde4ba12f8e6fc142dba3c5f6d669a9e89374cc6dc414464e4f2d04e72fafd4bc64819ce30bb63
+ languageName: node
+ linkType: hard
+
+"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "@types/d3-time@npm:3.0.0"
+ checksum: e76adb056daccf80107f4db190ac6deb77e8774f00362bb6c76f178e67f2f217422fe502b654edbc9ac6451f6619045b9f6f5fe0db1ec5520e2ada377af7c72e
+ languageName: node
+ linkType: hard
+
+"@types/d3-timer@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "@types/d3-timer@npm:3.0.0"
+ checksum: 1ec86b3808de6ecfa93cfdf34254761069658af0cc1d9540e8353dbcba161cdf1296a0724187bd17433b2ff16563115fd20b85fc89d5e809ff28f9b1ab134b42
+ languageName: node
+ linkType: hard
+
"@types/debounce@npm:^1.2.1":
version: 1.2.1
resolution: "@types/debounce@npm:1.2.1"
@@ -14829,6 +14929,15 @@ __metadata:
languageName: node
linkType: hard
+"aria-hidden@npm:^1.1.3":
+ version: 1.2.3
+ resolution: "aria-hidden@npm:1.2.3"
+ dependencies:
+ tslib: ^2.0.0
+ checksum: 7d7d211629eef315e94ed3b064c6823d13617e609d3f9afab1c2ed86399bb8e90405f9bdd358a85506802766f3ecb468af985c67c846045a34b973bcc0289db9
+ languageName: node
+ linkType: hard
+
"aria-query@npm:^4.2.2":
version: 4.2.2
resolution: "aria-query@npm:4.2.2"
@@ -17076,6 +17185,13 @@ __metadata:
languageName: node
linkType: hard
+"classnames@npm:^2.2.5":
+ version: 2.3.2
+ resolution: "classnames@npm:2.3.2"
+ checksum: 2c62199789618d95545c872787137262e741f9db13328e216b093eea91c85ef2bfb152c1f9e63027204e2559a006a92eb74147d46c800a9f96297ae1d9f96f4e
+ languageName: node
+ linkType: hard
+
"classnames@npm:^2.2.6, classnames@npm:^2.3.1":
version: 2.3.1
resolution: "classnames@npm:2.3.1"
@@ -18209,6 +18325,13 @@ __metadata:
languageName: node
linkType: hard
+"css-unit-converter@npm:^1.1.1":
+ version: 1.1.2
+ resolution: "css-unit-converter@npm:1.1.2"
+ checksum: 07888033346a5128f34dbe2f72884c966d24e9f29db24416dcde92860242490617ef9a178ac193a92f730834bbeea026cdc7027701d92ba9bbbe59db7a37eb2a
+ languageName: node
+ linkType: hard
+
"css-what@npm:^5.0.1":
version: 5.1.0
resolution: "css-what@npm:5.1.0"
@@ -18301,6 +18424,99 @@ __metadata:
languageName: node
linkType: hard
+"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6":
+ version: 3.2.3
+ resolution: "d3-array@npm:3.2.3"
+ dependencies:
+ internmap: 1 - 2
+ checksum: 41d6a4989b73e0d2649a880b2f29a7e7cc059db0eba36cd29a79e0118ebdf6b78922a84cde0733cd54cb4072f3442ec44f3563902e00ea42892442d60e99f961
+ languageName: node
+ linkType: hard
+
+"d3-color@npm:1 - 3":
+ version: 3.1.0
+ resolution: "d3-color@npm:3.1.0"
+ checksum: 4931fbfda5d7c4b5cfa283a13c91a954f86e3b69d75ce588d06cde6c3628cebfc3af2069ccf225e982e8987c612aa7948b3932163ce15eb3c11cd7c003f3ee3b
+ languageName: node
+ linkType: hard
+
+"d3-ease@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "d3-ease@npm:3.0.1"
+ checksum: 06e2ee5326d1e3545eab4e2c0f84046a123dcd3b612e68858219aa034da1160333d9ce3da20a1d3486d98cb5c2a06f7d233eee1bc19ce42d1533458bd85dedcd
+ languageName: node
+ linkType: hard
+
+"d3-format@npm:1 - 3":
+ version: 3.1.0
+ resolution: "d3-format@npm:3.1.0"
+ checksum: f345ec3b8ad3cab19bff5dead395bd9f5590628eb97a389b1dd89f0b204c7c4fc1d9520f13231c2c7cf14b7c9a8cf10f8ef15bde2befbab41454a569bd706ca2
+ languageName: node
+ linkType: hard
+
+"d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "d3-interpolate@npm:3.0.1"
+ dependencies:
+ d3-color: 1 - 3
+ checksum: a42ba314e295e95e5365eff0f604834e67e4a3b3c7102458781c477bd67e9b24b6bb9d8e41ff5521050a3f2c7c0c4bbbb6e187fd586daa3980943095b267e78b
+ languageName: node
+ linkType: hard
+
+"d3-path@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "d3-path@npm:3.1.0"
+ checksum: 2306f1bd9191e1eac895ec13e3064f732a85f243d6e627d242a313f9777756838a2215ea11562f0c7630c7c3b16a19ec1fe0948b1c82f3317fac55882f6ee5d8
+ languageName: node
+ linkType: hard
+
+"d3-scale@npm:^4.0.2":
+ version: 4.0.2
+ resolution: "d3-scale@npm:4.0.2"
+ 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
+ checksum: a9c770d283162c3bd11477c3d9d485d07f8db2071665f1a4ad23eec3e515e2cefbd369059ec677c9ac849877d1a765494e90e92051d4f21111aa56791c98729e
+ languageName: node
+ linkType: hard
+
+"d3-shape@npm:^3.1.0":
+ version: 3.2.0
+ resolution: "d3-shape@npm:3.2.0"
+ dependencies:
+ d3-path: ^3.1.0
+ checksum: de2af5fc9a93036a7b68581ca0bfc4aca2d5a328aa7ba7064c11aedd44d24f310c20c40157cb654359d4c15c3ef369f95ee53d71221017276e34172c7b719cfa
+ languageName: node
+ linkType: hard
+
+"d3-time-format@npm:2 - 4":
+ version: 4.1.0
+ resolution: "d3-time-format@npm:4.1.0"
+ dependencies:
+ d3-time: 1 - 3
+ checksum: 7342bce28355378152bbd4db4e275405439cabba082d9cd01946d40581140481c8328456d91740b0fe513c51ec4a467f4471ffa390c7e0e30ea30e9ec98fcdf4
+ languageName: node
+ linkType: hard
+
+"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0":
+ version: 3.1.0
+ resolution: "d3-time@npm:3.1.0"
+ dependencies:
+ d3-array: 2 - 3
+ checksum: 613b435352a78d9f31b7f68540788186d8c331b63feca60ad21c88e9db1989fe888f97f242322ebd6365e45ec3fb206a4324cd4ca0dfffa1d9b5feb856ba00a7
+ languageName: node
+ linkType: hard
+
+"d3-timer@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "d3-timer@npm:3.0.1"
+ checksum: 1cfddf86d7bca22f73f2c427f52dfa35c49f50d64e187eb788dcad6e927625c636aa18ae4edd44d084eb9d1f81d8ca4ec305dae7f733c15846a824575b789d73
+ languageName: node
+ linkType: hard
+
"d@npm:1, d@npm:^1.0.1":
version: 1.0.1
resolution: "d@npm:1.0.1"
@@ -18338,7 +18554,7 @@ __metadata:
languageName: node
linkType: hard
-"date-fns@npm:^2.29.1, date-fns@npm:^2.29.3":
+"date-fns@npm:^2.28.0, date-fns@npm:^2.29.1, date-fns@npm:^2.29.3":
version: 2.29.3
resolution: "date-fns@npm:2.29.3"
checksum: e01cf5b62af04e05dfff921bb9c9933310ed0e1ae9a81eb8653452e64dc841acf7f6e01e1a5ae5644d0337e9a7f936175fd2cb6819dc122fdd9c5e86c56be484
@@ -18457,6 +18673,13 @@ __metadata:
languageName: node
linkType: hard
+"decimal.js-light@npm:^2.4.1":
+ version: 2.5.1
+ resolution: "decimal.js-light@npm:2.5.1"
+ checksum: f5a2c7eac1c4541c8ab8a5c8abea64fc1761cefc7794bd5f8afd57a8a78d1b51785e0c4e4f85f4895a043eaa90ddca1edc3981d1263eb6ddce60f32bf5fe66c9
+ languageName: node
+ linkType: hard
+
"decimal.js@npm:^10.3.1":
version: 10.4.0
resolution: "decimal.js@npm:10.4.0"
@@ -18950,6 +19173,15 @@ __metadata:
languageName: node
linkType: hard
+"dom-helpers@npm:^3.4.0":
+ version: 3.4.0
+ resolution: "dom-helpers@npm:3.4.0"
+ dependencies:
+ "@babel/runtime": ^7.1.2
+ checksum: 58d9f1c4a96daf77eddc63ae1236b826e1cddd6db66bbf39b18d7e21896d99365b376593352d52a60969d67fa4a8dbef26adc1439fa2c1b355efa37cacbaf637
+ languageName: node
+ linkType: hard
+
"dom-helpers@npm:^5.0.1":
version: 5.2.1
resolution: "dom-helpers@npm:5.2.1"
@@ -20961,7 +21193,7 @@ __metadata:
languageName: node
linkType: hard
-"eventemitter3@npm:4.0.7, eventemitter3@npm:^4.0.7":
+"eventemitter3@npm:4.0.7, eventemitter3@npm:^4.0.1, eventemitter3@npm:^4.0.7":
version: 4.0.7
resolution: "eventemitter3@npm:4.0.7"
checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374
@@ -21316,6 +21548,13 @@ __metadata:
languageName: node
linkType: hard
+"fast-equals@npm:^4.0.3":
+ version: 4.0.3
+ resolution: "fast-equals@npm:4.0.3"
+ checksum: 3d5935b757f9f2993e59b5164a7a9eeda0de149760495375cde14a4ed725186a7e6c1c0d58f7d42d2f91deb97f3fce1e0aad5591916ef0984278199a85c87c87
+ languageName: node
+ linkType: hard
+
"fast-glob@npm:^2.2.6":
version: 2.2.7
resolution: "fast-glob@npm:2.2.7"
@@ -24158,6 +24397,13 @@ __metadata:
languageName: node
linkType: hard
+"internmap@npm:1 - 2":
+ version: 2.0.3
+ resolution: "internmap@npm:2.0.3"
+ checksum: 7ca41ec6aba8f0072fc32fa8a023450a9f44503e2d8e403583c55714b25efd6390c38a87161ec456bf42d7bc83aab62eb28f5aef34876b1ac4e60693d5e1d241
+ languageName: node
+ linkType: hard
+
"interpret@npm:^2.2.0":
version: 2.2.0
resolution: "interpret@npm:2.2.0"
@@ -31286,6 +31532,13 @@ __metadata:
languageName: node
linkType: hard
+"postcss-value-parser@npm:^3.3.0":
+ version: 3.3.1
+ resolution: "postcss-value-parser@npm:3.3.1"
+ checksum: 62cd26e1cdbcf2dcc6bcedf3d9b409c9027bc57a367ae20d31dd99da4e206f730689471fd70a2abe866332af83f54dc1fa444c589e2381bf7f8054c46209ce16
+ languageName: node
+ linkType: hard
+
"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.0.2, postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0":
version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0"
@@ -32551,7 +32804,7 @@ __metadata:
languageName: node
linkType: hard
-"react-is@npm:^16.13.1, react-is@npm:^16.7.0":
+"react-is@npm:^16.10.2, react-is@npm:^16.13.1, react-is@npm:^16.7.0":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f
@@ -32565,6 +32818,13 @@ __metadata:
languageName: node
linkType: hard
+"react-lifecycles-compat@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "react-lifecycles-compat@npm:3.0.4"
+ checksum: a904b0fc0a8eeb15a148c9feb7bc17cec7ef96e71188280061fc340043fd6d8ee3ff233381f0e8f95c1cf926210b2c4a31f38182c8f35ac55057e453d6df204f
+ languageName: node
+ linkType: hard
+
"react-live-chat-loader@npm:^2.7.3":
version: 2.7.3
resolution: "react-live-chat-loader@npm:2.7.3"
@@ -32771,6 +33031,18 @@ __metadata:
languageName: node
linkType: hard
+"react-resize-detector@npm:^8.0.4":
+ version: 8.0.4
+ resolution: "react-resize-detector@npm:8.0.4"
+ 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
+ checksum: f53a99cc5413844a6fc2a713b0b1094d23947897c14ab64481938632f4e77fadded52d91a6619055abf6240c7cacd6cc7dd492ea866639b302f81df680709d45
+ languageName: node
+ linkType: hard
+
"react-schemaorg@npm:^2.0.0":
version: 2.0.0
resolution: "react-schemaorg@npm:2.0.0"
@@ -32802,6 +33074,20 @@ __metadata:
languageName: node
linkType: hard
+"react-smooth@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "react-smooth@npm:2.0.2"
+ dependencies:
+ fast-equals: ^4.0.3
+ 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
+ checksum: 6b0a40a17314657ac6a187a3ad01fcdaa61d498979b6a07c424e20832110c99b4394c33209a0b39b897c13d113d8cb044e7a691b4965386a11b15bbfbacfba25
+ languageName: node
+ linkType: hard
+
"react-ssr-prepass@npm:^1.5.0":
version: 1.5.0
resolution: "react-ssr-prepass@npm:1.5.0"
@@ -32881,6 +33167,21 @@ __metadata:
languageName: node
linkType: hard
+"react-transition-group@npm:2.9.0":
+ version: 2.9.0
+ resolution: "react-transition-group@npm:2.9.0"
+ 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"
+ checksum: d8c9e50aabdc2cfc324e5cdb0ad1c6eecb02e1c0cd007b26d5b30ccf49015e900683dd489348c71fba4055858308d9ba7019e0d37d0e8d37bd46ed098788f670
+ languageName: node
+ linkType: hard
+
"react-transition-group@npm:^4.3.0":
version: 4.4.2
resolution: "react-transition-group@npm:4.4.2"
@@ -32896,6 +33197,21 @@ __metadata:
languageName: node
linkType: hard
+"react-transition-group@npm:^4.4.5":
+ version: 4.4.5
+ resolution: "react-transition-group@npm:4.4.5"
+ dependencies:
+ "@babel/runtime": ^7.5.5
+ dom-helpers: ^5.0.1
+ loose-envify: ^1.4.0
+ prop-types: ^15.6.2
+ peerDependencies:
+ react: ">=16.6.0"
+ react-dom: ">=16.6.0"
+ checksum: 75602840106aa9c6545149d6d7ae1502fb7b7abadcce70a6954c4b64a438ff1cd16fc77a0a1e5197cdd72da398f39eb929ea06f9005c45b132ed34e056ebdeb1
+ languageName: node
+ linkType: hard
+
"react-twemoji@npm:^0.3.0":
version: 0.3.0
resolution: "react-twemoji@npm:0.3.0"
@@ -33085,6 +33401,36 @@ __metadata:
languageName: node
linkType: hard
+"recharts-scale@npm:^0.4.4":
+ version: 0.4.5
+ resolution: "recharts-scale@npm:0.4.5"
+ dependencies:
+ decimal.js-light: ^2.4.1
+ checksum: e970377190a610e684a32c7461c7684ac3603c2e0ac0020bbba1eea9d099b38138143a8e80bf769bb49c0b7cecf22a2f5c6854885efed2d56f4540d4aa7052bd
+ languageName: node
+ linkType: hard
+
+"recharts@npm:^2.3.2":
+ version: 2.5.0
+ resolution: "recharts@npm:2.5.0"
+ 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
+ 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
+ checksum: a40d1788589926fa8a5844868a338aae75a2077a2bc2ac57fc5d61ad21fb62660aed6f00ae8d8a94948b9143255c1760db0d386ecb257ed8290dd7f164b5bd5f
+ languageName: node
+ linkType: hard
+
"redent@npm:^1.0.0":
version: 1.0.0
resolution: "redent@npm:1.0.0"
@@ -33119,6 +33465,16 @@ __metadata:
languageName: node
linkType: hard
+"reduce-css-calc@npm:^2.1.8":
+ version: 2.1.8
+ resolution: "reduce-css-calc@npm:2.1.8"
+ dependencies:
+ css-unit-converter: ^1.1.1
+ postcss-value-parser: ^3.3.0
+ checksum: 8fd27c06c4b443b84749a69a8b97d10e6ec7d142b625b41923a8807abb22b9e37e44df14e26cc606a802957be07bdce5e8ee2976a6952a7b438a7727007101e9
+ languageName: node
+ linkType: hard
+
"redux-immutable@npm:^4.0.0":
version: 4.0.0
resolution: "redux-immutable@npm:4.0.0"
@@ -36141,6 +36497,13 @@ __metadata:
languageName: node
linkType: hard
+"tabbable@npm:^6.0.1":
+ version: 6.1.1
+ resolution: "tabbable@npm:6.1.1"
+ checksum: 348639497262241ce8e0ccb0664ea582a386183107299ee8f27cf7b56bc84f36e09eaf667d3cb4201e789634012a91f7129bcbd49760abe874fbace35b4cf429
+ languageName: node
+ linkType: hard
+
"tailwind-merge@npm:^1.8.1":
version: 1.8.1
resolution: "tailwind-merge@npm:1.8.1"
@@ -36148,6 +36511,13 @@ __metadata:
languageName: node
linkType: hard
+"tailwind-merge@npm:^1.9.1":
+ version: 1.10.0
+ resolution: "tailwind-merge@npm:1.10.0"
+ checksum: 80eb30d0300ca912b4b910460497a1d5fb4e697c3aedb01513e633973328684fa7ddf9bfb8550dca28176971c93bcb7ecb7eec3097c01d9c55c191563c693aab
+ languageName: node
+ linkType: hard
+
"tailwind-scrollbar@npm:^2.0.1":
version: 2.0.1
resolution: "tailwind-scrollbar@npm:2.0.1"
@@ -38446,6 +38816,28 @@ __metadata:
languageName: node
linkType: hard
+"victory-vendor@npm:^36.6.8":
+ version: 36.6.8
+ resolution: "victory-vendor@npm:36.6.8"
+ 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
+ checksum: 6411f7c19a776cef3919946d429293cfe33c93a6e4dcfdfa2ba1edecad3a28ed2cd6b0d117169b8917ab6a7679e2bade5e7bfc1fed3fc8b464b842f21dac5f49
+ languageName: node
+ linkType: hard
+
"vite@npm:^2.9.15":
version: 2.9.15
resolution: "vite@npm:2.9.15"