From 705dbd78f8c527dc947ff9e2033e3207e705a8a8 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 3 Sep 2024 13:01:36 -0700 Subject: [PATCH 01/14] pricing page updates --- .../components/templates/pricing/BaseCard.tsx | 57 +++++ .../templates/pricing/EnterpriseCard.tsx | 25 +++ .../templates/pricing/GrowthCard.tsx | 74 +++++++ .../templates/pricing/ScaleCard.tsx | 119 ++++++++++ .../components/templates/pricing/Slider.tsx | 88 ++++++++ bifrost/app/globals.css | 63 ++++++ bifrost/app/pricing/page.tsx | 204 +----------------- bifrost/app/utils/pricingUtils.ts | 34 +++ bifrost/components.json | 20 ++ .../templates/pricing/requestLogTable.tsx | 4 +- bifrost/components/ui/button.tsx | 57 +++++ bifrost/components/ui/switch.tsx | 29 +++ bifrost/components/ui/table.tsx | 120 +++++++++++ bifrost/lib/utils.ts | 6 + bifrost/package.json | 10 +- bifrost/tailwind.config.ts | 65 +++++- bifrost/yarn.lock | 125 ++++++++++- 17 files changed, 889 insertions(+), 211 deletions(-) create mode 100644 bifrost/app/components/templates/pricing/BaseCard.tsx create mode 100644 bifrost/app/components/templates/pricing/EnterpriseCard.tsx create mode 100644 bifrost/app/components/templates/pricing/GrowthCard.tsx create mode 100644 bifrost/app/components/templates/pricing/ScaleCard.tsx create mode 100644 bifrost/app/components/templates/pricing/Slider.tsx create mode 100644 bifrost/app/utils/pricingUtils.ts create mode 100644 bifrost/components.json create mode 100644 bifrost/components/ui/button.tsx create mode 100644 bifrost/components/ui/switch.tsx create mode 100644 bifrost/components/ui/table.tsx create mode 100644 bifrost/lib/utils.ts diff --git a/bifrost/app/components/templates/pricing/BaseCard.tsx b/bifrost/app/components/templates/pricing/BaseCard.tsx new file mode 100644 index 0000000000..a5f1fe7566 --- /dev/null +++ b/bifrost/app/components/templates/pricing/BaseCard.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import Link from "next/link"; +import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/16/solid"; + +interface BaseCardProps { + name: string; + + price: React.ReactNode; + features: { name: string; included: boolean }[]; + ctaText: string; + ctaLink: string; + ctaClassName?: string; + children?: React.ReactNode; +} + +const BaseCard: React.FC = ({ + name, + + price, + features, + ctaText, + ctaLink, + ctaClassName, + children, +}) => { + return ( +
+

{name}

+ +
{price}
+ {children} +
    + {features.map((feature) => ( +
  • + {feature.included ? ( + + ) : ( + + )} + {feature.name} +
  • + ))} +
+ + {ctaText} + +
+ ); +}; + +export default BaseCard; diff --git a/bifrost/app/components/templates/pricing/EnterpriseCard.tsx b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx new file mode 100644 index 0000000000..a07b7fb7fd --- /dev/null +++ b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx @@ -0,0 +1,25 @@ +import BaseCard from "./BaseCard"; + +const EnterpriseCard: React.FC = () => { + const features = [ + { name: "Observability and Analytics", included: true }, + { name: "Feature-Rich Tooling", included: true }, + { name: "Prompt Templates", included: true }, + { name: "Prompt Experiments", included: true }, + { name: "SOC-2 Compliance", included: true }, + { name: "On-Prem Deployment", included: true }, + ]; + + return ( + Get in touch

} + features={features} + ctaText="Get in touch" + ctaLink="/contact" + /> + ); +}; + +export default EnterpriseCard; diff --git a/bifrost/app/components/templates/pricing/GrowthCard.tsx b/bifrost/app/components/templates/pricing/GrowthCard.tsx new file mode 100644 index 0000000000..4d4af35a50 --- /dev/null +++ b/bifrost/app/components/templates/pricing/GrowthCard.tsx @@ -0,0 +1,74 @@ +import { useState } from "react"; +import BaseCard from "./BaseCard"; +import Slider from "./Slider"; +import { renderLogCost } from "@/app/utils/pricingUtils"; + +const GrowthCard: React.FC = () => { + const [requestLogs, setRequestLogs] = useState(0); + + const handleRequestLogChange = (newValue: number) => { + setRequestLogs(newValue); + }; + + const features = [ + { name: "Observability and Analytics", included: true }, + { name: "10,000 requests", included: true }, + { name: "Core Tooling", included: true }, + { name: "1 month retention", included: true }, + { name: "No credit card required", included: true }, + { name: "Prompts", included: false }, + { name: "Experiments", included: false }, + { name: "Playground", included: false }, + { name: "Cache Stats", included: false }, + { name: "Rate Limit Stats", included: false }, + { name: "API Access", included: false }, + { name: "Evals", included: false }, + { name: "Connections", included: false }, + { name: "SOC-2 Compliance", included: false }, + { name: "On-Prem Deployment", included: false }, + ]; + + return ( + +

{renderLogCost(requestLogs)}

+

/month

+ + } + features={features} + ctaText="Start building for free" + ctaLink="https://us.helicone.ai/signup" + ctaClassName="bg-sky-500 hover:bg-sky-600 border-2 border-sky-700 whitespace-nowrap rounded-md px-4 py-1.5 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-500 w-full flex items-center justify-center gap-2" + > +
+
+

+ {new Intl.NumberFormat("us", { + minimumFractionDigits: 0, + maximumFractionDigits: 0, + }).format(requestLogs)} + requests / month +

+ +
+
+
+ ); +}; + +export default GrowthCard; diff --git a/bifrost/app/components/templates/pricing/ScaleCard.tsx b/bifrost/app/components/templates/pricing/ScaleCard.tsx new file mode 100644 index 0000000000..523bd34eb0 --- /dev/null +++ b/bifrost/app/components/templates/pricing/ScaleCard.tsx @@ -0,0 +1,119 @@ +import { useState } from "react"; +import BaseCard from "./BaseCard"; +import Slider from "./Slider"; +import { renderLogCost } from "@/app/utils/pricingUtils"; +import { Col } from "@/components/common/col"; +import { Button } from "@/components/ui/button"; + +import { Switch } from "@/components/ui/switch"; + +import { + Table, + TableBody, + TableCaption, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; + +const ScaleCard: React.FC = () => { + const [requestLogs, setRequestLogs] = useState(0); + const [promptCount, setPromptCount] = useState(0); + + const handleRequestLogChange = (newValue: number) => { + setRequestLogs(newValue); + }; + + const handlePromptCountChange = (newValue: number) => { + setPromptCount(newValue); + }; + + const calculatePromptCost = (count: number) => { + if (count <= 3) return 0; + return (count - 3) * 25; + }; + + const features = [ + { name: "Observability and Analytics", included: true }, + { name: "Feature-Rich Tooling", included: true }, + { name: "Prompt Templates", included: true }, + { name: "Prompt Experiments", included: true }, + { name: "SOC-2 Compliance", included: false }, + { name: "On-Prem Deployment", included: false }, + ]; + + const totalCost = + parseFloat(renderLogCost(requestLogs).replace(/[^0-9.-]+/g, "")) + + calculatePromptCost(promptCount); + + return ( + +

${totalCost.toFixed(2)}

+

/month

+ + } + features={features} + ctaText="Get started for free" + ctaLink="https://us.helicone.ai/signup" + > +
+ +

Scale

+ +

Enable scaling

+ +
+

+ {new Intl.NumberFormat("us", { + minimumFractionDigits: 0, + maximumFractionDigits: 0, + }).format(requestLogs)} + requests / month +

+ +
+ +
+

+ {promptCount}{" "} + prompts +

+ +

+ First 3 prompts free, then $25/prompt +

+
+
+
+ ); +}; + +export default ScaleCard; diff --git a/bifrost/app/components/templates/pricing/Slider.tsx b/bifrost/app/components/templates/pricing/Slider.tsx new file mode 100644 index 0000000000..07155670bd --- /dev/null +++ b/bifrost/app/components/templates/pricing/Slider.tsx @@ -0,0 +1,88 @@ +import { useState } from "react"; +import { clsx } from "@/components/shared/utils"; + +interface SliderProps { + min: number; + max: number; + exponent: number; + onChange: (value: number) => void; + color?: string; + labels?: Record; +} + +const Slider: React.FC = ({ + min, + max, + exponent, + onChange, + color = "purple", + labels, +}) => { + // This function converts the slider's linear value to an exponential value. + const toExponentialValue = (linearValue: number) => { + return Math.pow(linearValue / max, exponent) * (max - min) + min; + }; + + // This function converts an exponential value to the slider's linear value. + const toLinearValue = (exponentialValue: number) => { + return Math.pow((exponentialValue - min) / (max - min), 1 / exponent) * max; + }; + + // Initialize the slider's value using the inverse transformation function. + const [sliderValue, setSliderValue] = useState(toLinearValue(min)); + + const handleSliderChange = (e: React.ChangeEvent) => { + const linearValue = Number(e.target.value); + setSliderValue(linearValue); + const expValue = toExponentialValue(linearValue); + onChange(expValue); + }; + + // Calculate the offset for a label based on its value + const calculateOffset = (value: number) => { + const linearValue = toLinearValue(value); + const percentage = ((linearValue - min) / (max - min)) * 100; + return `${percentage}%`; + }; + + return ( +
+ + {labels && ( +
+ {Object.entries(labels).map(([key, text], idx) => ( + + ))} +
+ )} +
+ ); +}; + +export default Slider; diff --git a/bifrost/app/globals.css b/bifrost/app/globals.css index b5c61c9567..89b55f84f0 100644 --- a/bifrost/app/globals.css +++ b/bifrost/app/globals.css @@ -1,3 +1,66 @@ @tailwind base; @tailwind components; @tailwind utilities; +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 10% 3.9%; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --radius: 0.5rem + } + .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55% + } +} +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/bifrost/app/pricing/page.tsx b/bifrost/app/pricing/page.tsx index 16047d38a8..3384f55828 100644 --- a/bifrost/app/pricing/page.tsx +++ b/bifrost/app/pricing/page.tsx @@ -19,6 +19,11 @@ import RequestLogTable, { HELICONE_LOG_PRICING, } from "@/components/templates/pricing/requestLogTable"; import FeatureTable from "@/components/templates/pricing/featureTable"; +import ScaleCard from "../components/templates/pricing/ScaleCard"; +import GrowthCard from "../components/templates/pricing/GrowthCard"; +import EnterpriseCard from "../components/templates/pricing/EnterpriseCard"; + +import { renderLogCost } from "@/app/utils/pricingUtils"; const Slider = ({ min, @@ -102,100 +107,9 @@ const Slider = ({ ); }; -const TIERS: { - name: string; - ctaCopy: string; - features: { - name: string; - included: boolean | string; - }[]; - href: string; -}[] = [ - { - name: "Free", - ctaCopy: "Start building for free", - features: [ - { name: "Observability and Analytics", included: true }, - { name: "Core Tooling", included: true }, - { name: "Prompt Templates", included: true }, - { name: "Limited Prompt Experiments", included: true }, - { name: "SOC-2 Compliance", included: false }, - { name: "On-Prem Deployment", included: false }, - ], - href: "https://us.helicone.ai/signup", - }, - { - name: "Growth", - ctaCopy: "Get started for free", - features: [ - { name: "Observability and Analytics", included: true }, - { name: "Feature-Rich Tooling", included: true }, - { name: "Prompt Templates", included: true }, - { name: "Prompt Experiments", included: true }, - { name: "SOC-2 Compliance", included: false }, - { name: "On-Prem Deployment", included: false }, - ], - href: "https://us.helicone.ai/signup", - }, - { - name: "Enterprise", - ctaCopy: "Get in touch", - features: [ - { name: "Observability and Analytics", included: true }, - { name: "Feature-Rich Tooling", included: true }, - { name: "Prompt Templates", included: true }, - { name: "Prompt Experiments", included: true }, - { name: "SOC-2 Compliance", included: true }, - { name: "On-Prem Deployment", included: true }, - ], - href: "/contact", - }, -]; - export default function Example() { - const [requestLogs, setRequestLogs] = useState(0); const [showPlans, setShowPlans] = useState(false); - const handleRequestLogChange = (newValue: any) => { - setRequestLogs(newValue); - }; - - const handleLogCostCalculation = (currentLogValue: number) => { - // calculate the estimated cost for the `currentValue` using tax brackets - const calculateCost = (currentValue: number) => { - let cost = 0; - let remainingValue = currentValue; - for (const pricing of HELICONE_LOG_PRICING) { - const logCount = Math.min( - pricing.upper - pricing.lower, - remainingValue - ); - cost += logCount * pricing.rate; - remainingValue -= logCount; - if (remainingValue <= 0) { - break; - } - } - return cost; - }; - - return calculateCost(currentLogValue); - }; - - const renderLogCost = () => { - if (requestLogs <= 100_000) { - return "$0.00"; - } - if (requestLogs >= 50_000_000) { - return "Contact us for pricing"; - } - - return new Intl.NumberFormat("us", { - style: "currency", - currency: "USD", - }).format(handleLogCostCalculation(requestLogs)); - }; - return (
@@ -236,111 +150,9 @@ export default function Example() {
- {/* map over an array of 3 */} - {TIERS.map((tier, index) => ( -
-

{tier.name}

-
- {tier.name === "Free" && ( - <> -

$0.00

-

/month

- - )} - {tier.name === "Growth" && ( - <> -

- {renderLogCost()} -

-

/month

- - )} - {tier.name === "Enterprise" && ( - <> -

Get in touch

- - )} -
- {tier.name === "Free" && ( -
-

- Free for up to 100k requests per month -

-
- )} - {tier.name === "Growth" && ( -
-
-

- {new Intl.NumberFormat("us", { - minimumFractionDigits: 0, - maximumFractionDigits: 0, - }).format(requestLogs)} - - {" "} - requests / month - -

- -
-
- )} - {tier.name === "Enterprise" && ( -
-

- Contact us for a tailored plan for your business -

-
- )} - -
    - {tier.features.map((feature) => ( -
  • - {feature.included === true ? ( - - ) : ( - - )} - - {feature.name}{" "} - {typeof feature.included === "string" && - `(${feature.included})`} - -
  • - ))} -
- - - {tier.ctaCopy} - -
- ))} + + +
+ ); +} diff --git a/bifrost/app/pricing/page.tsx b/bifrost/app/pricing/page.tsx index 7d0beb28e5..9dc1ba0b82 100644 --- a/bifrost/app/pricing/page.tsx +++ b/bifrost/app/pricing/page.tsx @@ -1,132 +1,29 @@ "use client"; -import { Fragment, useState } from "react"; import { AcademicCapIcon, - CheckCircleIcon, CheckIcon, - ChevronDownIcon, - ChevronUpIcon, CodeBracketIcon, - XCircleIcon, } from "@heroicons/react/20/solid"; -import Link from "next/link"; import Image from "next/image"; +import Link from "next/link"; import { HomeModernIcon } from "@heroicons/react/24/solid"; -import { useRouter } from "next/navigation"; -import { clsx } from "@/components/shared/utils"; -import RequestLogTable, { - HELICONE_LOG_PRICING, -} from "@/components/templates/pricing/requestLogTable"; -import FeatureTable from "@/components/templates/pricing/featureTable"; -import ScaleCard from "../components/templates/pricing/ScaleCard"; -import FreeCard from "../components/templates/pricing/FreeCard"; import EnterpriseCard from "../components/templates/pricing/EnterpriseCard"; +import FreeCard from "../components/templates/pricing/FreeCard"; import PricingComparisonTable from "../components/templates/pricing/PricingComparisonTable"; +import ScaleCard from "../components/templates/pricing/ScaleCard"; +import ProductComparisonTable from "../components/templates/pricing/ProductComparisonTable"; -import { renderLogCost } from "@/app/utils/pricingUtils"; import { Col } from "@/components/common/col"; import { Row } from "@/components/common/row"; import { Button } from "@/components/ui/button"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { - Card, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { Switch } from "@/components/ui/switch"; -import { LockClosedIcon, LockOpenIcon } from "@heroicons/react/24/outline"; - -const Slider = ({ - min, - max, - exponent, - onChange, - color = "purple", - labels, -}: { - min: number; - max: number; - exponent: number; - onChange: (value: number) => void; - color?: string; - labels?: Record; -}) => { - // This function converts the slider's linear value to an exponential value. - const toExponentialValue = (linearValue: number) => { - return Math.pow(linearValue / max, exponent) * (max - min) + min; - }; - - // This function converts an exponential value to the slider's linear value. - const toLinearValue = (exponentialValue: number) => { - return Math.pow((exponentialValue - min) / (max - min), 1 / exponent) * max; - }; - - // Initialize the slider's value using the inverse transformation function. - const [sliderValue, setSliderValue] = useState(toLinearValue(min)); - - const handleSliderChange = (e: any) => { - const linearValue = e.target.value; - setSliderValue(linearValue); - const expValue = toExponentialValue(linearValue); - onChange(expValue); - }; - - // Calculate the offset for a label based on its value - const calculateOffset = (value: number) => { - const linearValue = toLinearValue(value); - const percentage = ((linearValue - min) / (max - min)) * 100; - return `${percentage}%`; - }; - return ( -
- - {labels && ( -
- {/* Map through the labels and create a div for each */} - {Object.entries(labels).map(([key, text], idx) => ( - - ))} -
- )} -
- ); -}; +import { XMarkIcon } from "@heroicons/react/24/outline"; export default function Example() { - const [showPlans, setShowPlans] = useState(false); - return ( -
-
+
+
-

Pricing that's simple

@@ -214,72 +110,96 @@ export default function Example() {
- + -
-

- Available discounts -

-
    -
  • -
    - +
    +
    + Also included +
    +
    + {[ + "Playground", + "SOC-2", + "Cache stats", + "3 month log retention", + "Rate limit stats", + "10 API calls per minute", + ].map((item) => ( +
    + + {item}
    -
    -

    Startups

    -

    - For most startups under two years old, we offer 50% off for - the first year. + ))} +

    +
    + +
    + + + Available
    + discounts +
    + + + + +
    +
    +
    +

    + Startups +

    +

    + 50% + + {" "} + off first year +

    -
    -
  • {" "} -
  • -
    - -
    -
    -

    Non-Profits

    -

    - For most non-profits, we offer large discounts depending on - organization size. +

    + For most startups under 2 years old.

    -
  • -
  • -
    - -
    -
    -

    - Open-Source Companies +
    +

    + Non-profits

    -

    - For fellow open-source companies, we offer a $5,000 credit - for the first year. +

    Discounts

    +

    + Depending on your org size.

    -

  • {" "} -
  • -
    - +
    +

    + Open-source companies +

    +

    + $5,000 + + {" "} + credit + +

    +

    + For the first year. +

    -
    -

    Students

    -

    - For most students and educators, we provide Helicone free of - charge. +

    +

    + Students +

    +

    Free

    +

    + For most students and educators.

    -
  • {" "} -
-
- - Get in touch - +
From 3bc6d899e872fadb8cb43f1dc55d9fefc6a8a322 Mon Sep 17 00:00:00 2001 From: Justin Date: Sun, 8 Sep 2024 17:42:00 -0600 Subject: [PATCH 05/14] ... --- .../pricing/ProductComparisonTable.tsx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx index 8920f918a7..fc2c278029 100644 --- a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx @@ -1,3 +1,4 @@ +import { clsx } from "@/utils/clsx"; import { CheckIcon, XMarkIcon } from "@heroicons/react/20/solid"; const products = [ @@ -29,14 +30,10 @@ export default function ProductComparisonTable() { - {products.map((product, index) => ( + {products.map((product) => ( ( {supported ? ( From a3f57035ca17b30d044ea4a16293116aa61dde03 Mon Sep 17 00:00:00 2001 From: Justin Date: Sun, 8 Sep 2024 18:52:43 -0600 Subject: [PATCH 06/14] pricing page mostly done --- .../pricing/PricingComparisonTable.tsx | 7 +- .../pricing/ProductComparisonTable.tsx | 61 +++++--- bifrost/app/pricing/page.tsx | 138 +++++++++++++++++- bifrost/components/ui/accordion.tsx | 57 ++++++++ bifrost/package.json | 1 + bifrost/public/static/other-logos/arize.png | Bin 0 -> 4042 bytes .../public/static/other-logos/decipher.png | Bin 0 -> 12352 bytes .../public/static/other-logos/greptile.png | Bin 0 -> 30893 bytes .../public/static/other-logos/helicone.png | Bin 0 -> 1824 bytes .../public/static/other-logos/honeyhive.png | Bin 0 -> 2141 bytes .../public/static/other-logos/langfuse.png | Bin 0 -> 17556 bytes .../public/static/other-logos/langsmith.png | Bin 0 -> 5739 bytes bifrost/public/static/other-logos/qawolf.png | Bin 0 -> 14643 bytes bifrost/tailwind.config.ts | 22 +++ bifrost/yarn.lock | 29 ++++ 15 files changed, 288 insertions(+), 27 deletions(-) create mode 100644 bifrost/components/ui/accordion.tsx create mode 100644 bifrost/public/static/other-logos/arize.png create mode 100644 bifrost/public/static/other-logos/decipher.png create mode 100644 bifrost/public/static/other-logos/greptile.png create mode 100644 bifrost/public/static/other-logos/helicone.png create mode 100644 bifrost/public/static/other-logos/honeyhive.png create mode 100644 bifrost/public/static/other-logos/langfuse.png create mode 100644 bifrost/public/static/other-logos/langsmith.png create mode 100644 bifrost/public/static/other-logos/qawolf.png diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx index 863396f9c3..c9b02c152d 100644 --- a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx @@ -32,10 +32,7 @@ const FeatureRow: React.FC = ({ }) => ( <> @@ -202,7 +199,7 @@ export default function PricingComparisonTable() {
-
+
diff --git a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx index fc2c278029..a488bd6ceb 100644 --- a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx @@ -1,12 +1,13 @@ import { clsx } from "@/utils/clsx"; import { CheckIcon, XMarkIcon } from "@heroicons/react/20/solid"; +import { useEffect, useRef } from "react"; const products = [ - { name: "langsmith", logo: "/path-to-langsmith-logo.png" }, - { name: "arize ai", logo: "/path-to-arize-ai-logo.png" }, - { name: "honeyhive", logo: "/path-to-honeyhive-logo.png" }, - { name: "langfuse", logo: "/path-to-langfuse-logo.png" }, - { name: "helicone", logo: "/path-to-helicone-logo.png" }, + { name: "langsmith", logo: "/static/other-logos/langsmith.png" }, + { name: "arize ai", logo: "/static/other-logos/arize.png" }, + { name: "honeyhive", logo: "/static/other-logos/honeyhive.png" }, + { name: "langfuse", logo: "/static/other-logos/langfuse.png" }, + { name: "helicone", logo: "/static/other-logos/helicone.png" }, ]; const featureMatrix = [ @@ -22,22 +23,47 @@ const featureMatrix = [ ]; export default function ProductComparisonTable() { + const tableRef = useRef(null); + const overlayRef = useRef(null); + + useEffect(() => { + const updateOverlayWidth = () => { + if (tableRef.current && overlayRef.current) { + const lastColumn = tableRef.current.querySelector( + "tr:first-child th:last-child" + ); + if (lastColumn) { + overlayRef.current.style.width = `${lastColumn.clientWidth}px`; + } + } + }; + + updateOverlayWidth(); + window.addEventListener("resize", updateOverlayWidth); + + return () => window.removeEventListener("resize", updateOverlayWidth); + }, []); + return (

Compare to similar products

-
- +
+
+
- + {products.map((product) => ( - + {feature.support.map((supported, i) => ( -
LOGO
+
+ +

386 hours saved by using cached responses.

@@ -82,7 +95,14 @@ export default function Example() {
-
LOGO
+
+ +

2 days saved combing through requests.

@@ -98,7 +118,15 @@ export default function Example() {
-
LOGO
+
+ {" "} + +

Critical bug detected, saved agent runtime by 30%.

@@ -111,7 +139,6 @@ export default function Example() { -
@@ -136,6 +163,7 @@ export default function Example() { ))}
+
@@ -202,6 +230,106 @@ export default function Example() { + +
+

+ Frequently asked questions +

+ + + + Which Helicone plan is right for me? + + + Yes. It's right for you. + + + + + + What are the limits for each plan? + + + For the Developer plan, you have access to 10k free requests + and dashboard analytics. For the Team plan, you have access to + all features, such as Playground, Prompts, Exports, Evals and + more. For each feature, you will pay as you go. + + + + + + I went over my limits. What can I do? + + + You can switch to the Team plan. If you are already on the + Team plan, you will be automatically charged for your usage. + + + + + + Am I eligible for any discounts? + + + If you are a startup under 2 years old, a non-profit, an + open-source company or a student, you may be eligible for + discounts.{" "} + + Apply here + + . + + + +
+ +
+
+
+
+

+ Understand your AI + + performance bottleneck + + with Helicone. +

+
+
+ + + +
+
+
+
+
+

+ Helicone or LangSmith? +

+

+ More provider flexibility, cost-effective and transparent + (open-source). +

+
+ + + +
+ + + + + diff --git a/bifrost/components/ui/accordion.tsx b/bifrost/components/ui/accordion.tsx new file mode 100644 index 0000000000..8dcf9b6fa5 --- /dev/null +++ b/bifrost/components/ui/accordion.tsx @@ -0,0 +1,57 @@ +"use client" + +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDownIcon } from "@radix-ui/react-icons" + +import { cn } from "@/lib/utils" + +const Accordion = AccordionPrimitive.Root + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AccordionItem.displayName = "AccordionItem" + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + +)) +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)) +AccordionContent.displayName = AccordionPrimitive.Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/bifrost/package.json b/bifrost/package.json index 1482b98c3a..8a574e4bee 100644 --- a/bifrost/package.json +++ b/bifrost/package.json @@ -15,6 +15,7 @@ "@headlessui/react": "^2.0.4", "@heroicons/react": "^2.1.3", "@mintlify/mdx": "^0.0.44", + "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-switch": "^1.1.0", diff --git a/bifrost/public/static/other-logos/arize.png b/bifrost/public/static/other-logos/arize.png new file mode 100644 index 0000000000000000000000000000000000000000..b13bbd357d11613cf48cae03de863b9becaa0d3f GIT binary patch literal 4042 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 uAT$CMW*1aF?7zM0)cE3{;er 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 K;#HzXe*Xh%f$9hV literal 0 HcmV?d00001 diff --git a/bifrost/public/static/other-logos/helicone.png b/bifrost/public/static/other-logos/helicone.png new file mode 100644 index 0000000000000000000000000000000000000000..01433fadfcd90cec6d288045ab807dd0d7d75ed7 GIT binary patch literal 1824 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 T?Z@Ti00000NkvXXu0mjf#aIfG literal 0 HcmV?d00001 diff --git a/bifrost/public/static/other-logos/langfuse.png b/bifrost/public/static/other-logos/langfuse.png new file mode 100644 index 0000000000000000000000000000000000000000..7bd02728f405f60b5b4bc5aa2a2b68b5cbdf4836 GIT binary patch literal 17556 zcmbrEQ)4AevxQ^Zwr$(CZQGgH#!hx@+n!jHWG53$Y}=WM^}XjeoQvw}?yIi8>DBA0 zI5ibnWCQ{PFfcG=c{wSK|8n|&0fdA3Z_L^wZ1^w1yUFQ$f`O6q{a=7fXR@39w+Zg4 zAu9paI7@W?-vY{3Tv;3ptR)5U!yFn6Op0D!N?gki{5l9e-&i{5R`+zP;`zpj%1NFq z3=SL$D-sXaXpIQM$~LL^-T$1u~K_5&D)9g|&iNqkx!z_H@^D);y7%H4sdI^`vN1YIIzshAN&UE1qzYXhB94dcsuH764=e>nw25poTJcjR z_^R3TX2RvG4cUTPXw+fk3d5 z!f|9#=^mnE_VwR;6_HBJbg(6TD92X72x{r#R7>F+!pldz!&%H89gA-kvkm37LBwPI z9KIPbe^F4cx=q7RyXjLWQ*F1)tOa z$wc4TT56?pyHm|cwJ;@7=xf)>|4z-&GlHZ~g;fhqc%TH@c6LgbN!zT{>pMHHHhyBD z>?XFxK$T$Gk}~dxxuS784`gSm#L)s^2-K>|Z}sDJx9FFvTmW{91T9pGR_Li05@gFk ztqJD3l#AIMXo84tLO!h0uZ$*{qq8MZfe))u;ru0Psaa7aNAreZ&U3#dEimH5@p%rE z6T-~8fQlZj+zN#?+T+{GV{g;~$I}@K*6jKqyvL=Vfa5;IUa4{t%p+>i@1}~ohc0;~ zgs}wo5Qg_FvRJW}P_>MhCKZcjX?gnP=grMcQ9(YwNz7iU#x3U5xJgUYA&O>xjN=48 z0d}#xE68&Gjx~zY_V!7k$6i9y1y#YwQ*$WJH7qbE`hvJXNqb&@IZJ}(CJZ;f#LCykqJVY(#Yj67!hZ*l!00e z0AqB_agKqMJ#(!%%X)q~2rRbme(mSJfRu!bTVlys?P+fs;P~tqxIW(>vO504wP4zkdv}@ml^6@s9 z8HDQQaDx@QNa}P8YztE=m{K9u`xEo@WnaOti$|2H+^Kqi{qomc{#vpKiW?z5rjWX4 zbQZt|Ys~>~c5yxgkV4%p|G(K)h2Cb5&3v6!y`+|co=@O)KK`uo> zPd!IHr-h9EOq;ZSmjI_Q*gaS;zAh-yiJrsAg;A{!6CC5skwJg)S7Qw8Cst6H%RH1V zHdk&mM}LSe?cEeR;w=A7zaJ4j*mD08wkgNaclNtTQ)Jn{e^wVUK~h@H>J>OvyuLI0fK5e4n2$L@LN;V428MY&5&v$})qe6G-!_mtPaEei**n@XcTxu|Qp z8S~$eQW4?91$he_dmydL(2(8;SZze!_QBO(hkuzk3b2y+WMZj)Q=r+S`bJH?Ou0lV z;w1hZY!2>>47yURC@7Ke&^G6LMUKDBbh3%5VUVVJlsVa;}z? zv2&2vTa&6)?pU24v8RRMq~@ZW29(Bhmo2CMP2GG5#u_oYL(#yAn)ZiukZfT-q4D5h zj&2nqjt=_|Gz9q^kpL_1q;Hs9+rd>u>m?b0mYqkWuSS<7(wsB2uI%`(OWtojZz3}x z%~(-*0!p_k@^i15q40|XDYgrA7xWz?YMg-rot}s6IUTcUaI_T2$aVZX&p?H5KN2jc zuo(>yizp8&Ex-T8PLIi|g)<&=M+AtSC_}5c&$A(BYOwu?!8##HsXDDbS05kH(a?qC zLi&5--)!(*+^cCb(OYP!r5?s;X8VJ2Z9`J59L*tQS{_%v`L2FjW@v|pOg8MdlUu_Q z$!iYKJi>yptZX#uRpN%T;QAr2k;UKB#$%nM@3FxZTQ-LyP#xh|v+CYp+M=jji1RRg zNW=58q3eQM>iO@c>L-Md6>LgvX20WdgvQVJ%^KAy0aInMk|*D7O|ql-i47lQA^4m# z%m~TmXh~biC`8zNiYUt+O80pRR{d(^5ve=E8lfKzRBj}i#(d~9yMqyCpBrqp$0ffz z1bUD5%NblRw#QITmgT~di5y#ACK!880j`2r`?`0XIl zP-R51Und&+qyHb;l#fP*=|M~|MTX-JV+L$6leo3qtP3;fwo*B)s6sgzmLe){-6jr8 z&Ps3Xly%_6f|6wk{@`#*$!9cgXeAPLe^e}EW+V!+LW^N)C9oJ9albd-#Bam_|JKDd zY9+JnW1C8_C~AJ{J%DUZ*X%sF4}rU69>U=t%oMRlCsl)R4y>PS7-<*qCI>*82Fy)i zO&(`?AnTuAV!&9q@4c8y3x(8LWdT6ll(?vUrIV`-!V+vi#4~zZ`fLum+-&t^?)`gw zq(1X?oT838;HS+NLas5HpINWNSDeacGq}Bpf_?c<>jZX3ft_YsOp(dh&$CM! zkQv1wn%G*GO*JN)A3ikz&(1f?I}ccDoDHtG2<06hL9yy@Ckht%21S^V*Puu-8aqQ8 zIaqHD?S--otP-d93LyQ^HRp&J3MQWFuBh+~Xfpx^7&B~dTZ;IwCj)I1^FElZvi!T*h(=pot!2n^D)hw( z14F@?ZsMFE9`Q4Q-q?5fDEYTCj2NGuEw-2&Van%+r$BnmtA$$aItVf?BnnJ0S_?G1 z9Ck~Y=pW^!WvNrP?qedk5PMARTJrhE=7+zM@`zDBTHfHQF$De{W#Z_|4YRvr*u2@~ zFqy@OV2?jIRzHgpvP}Ol@K~P`{!4{g<>eJr-c()(Ew$XF|Rmu5V6l@d9LAIRUh(vg!pwmp z1oe@NdNrLmC>st^cMw_UNpVurijc-BV{1oN-euUHXN4}B?Q+nQW0!=AyJqXrxkkvp zt^ELUF6QoiAhS_V2*K*AHun)=Q|l0!BP_I!r|6Dxel_Z zSV{?`D9_H$nxCi-zxUMx18%zkBBGEzz zQ`I0(-(8z#zD(^_sY+WeR*od7L~UFo4Z}-VlzoXpMI6peW0R$|3_J83idvvgDa|VK zAm)>6ydIu1QCve`UrZDbqcx8LFK!?xuZ}|9zcus_72f;zYdzAiot>Sj_$uq_romv5 z=m7nVMl6PsoeU0<0#*-Et|oGS!Hz1Rgchr{=BC~9Au}~htlU0j&5`64o`Xr@yg8ki z=7#vX#Gj-sNwHK+^e$-vHwTfBCy~)wBP3$l2XE3bnD~U>BZ+S&n^5GgZ<-XXkGETS z2QD89S#o3!i{ZzvZW0|l%`{p{NUvWc?MA9xw&(_#H|0lF%K~lf>?Y~Z!BN%>m+X|2 zRGgI~)%%sLC_2UO6vT2cDwHC>zJlM?`ou`ZBHw60n-v0B88;t4mu_A=Klhi-++XDn z1l!d@a3r3PUnYy4O^|Z z?rqD8R+QD(&*lk&6-~MgySc0z?|wS z`)>I1rz?V=ng)i3lBs<{e)hu!1Mtr#U=^J@VWi0!LMSE|R%w27t_<2eHr?T>VBsY0 zBH7Pht(>8cypVMjA2F(m$T0F7(F%60?~ZZaIJb?(FPtP4?j+>2tDj)Opss(eY11&U zNB%F5X$J*nMz&70_@; z%zQRSRH|PX&mm}=BDrs<@XU1?apDw=>R-q=Xdd??CANxu-&ABlWP%(kbl$pB7@{5> zz~FcFmyt}5;!hft16L8#x+RfTd$BK<#o{g44E|1Xk;j!ZV`LqI&VQpln*~vYSYN7Y zu`C1()B2x~59eX#YiAS`==vLiY9cW4?IwTfnV(Mf_st^)I)j=PE9@Lg=Vn8wLkQD3 z&?iy%Q`+8}S>d!L9~aRl74J(CnsIJ?=)ockJ$ts8{bcwsAN~vsk1_A`y=##DF$i=+ znVsL-cg-RuY5q0wEX;hoYf6)66(Q`>M*sP(VD-wNqah~>W!O$ z(iWf;KtUH!#?B=pS`XG5Li#XIC>Aw)y-6j?ka5J{o%ayHG$g$wbgRD`kK%Uu&{By+69f~Ob#y?-BOZbtc$W(Cm>?-y)c_)cCxcA!>j6oQ;L2}wJp~A$SpiCH}haD8w%q`}hjN|||W38-_VO=bNI;8)h#+`PY z8p0#f;&}{}c9}!@8e~fEzjmZF7ku6)`uv9GjOfo6TYAJ6xXBS{2m!LXl_K4o)@mmo z;u2%@vuUPnH1b~7p3=Klav-psQ81F%(qdlS7-gzg2VMzclTS0 zX}H6;xPU~-$)Vtg3GYM2UnKrim=rnhQn7|>e1^%`j8{|LrqsFepc|HWBjU%R;~Ipd z(}J~|d|A%Y4QB6PbIX22wt)*|s;zLUH8$NYgVX9^S`s@pgk{n%E={~_6%Wo+h3-`V z#*Bax1RWFmrUC)daKkPvsg&T3ify7xZW8W$MIh zWQxu=UKBG*Oc0Z4Pl{?&xIMbGL_P=4y+$uzPN2qB#C6AWS?f3=7$F0_ z1jTzAk?R+F8kLvy3zkWo(L0p@&9c}Jf?U+q>t-xiLkm)Vp@pmMBX>;-^QmxweK@Dp(J_N z)wv!HkO=l%!wVh7!Z{fdq}u0&E(s%}>v)PG-A4iG%TypCA>~z7Q<4ZmT^p0z7q5Tq zb+?qlaQGrXGsEq}9}cYJk!|DgvD?;D%_`>aU?j8sC*+kog2e7`q9#QO3&$u3 z{z8%X6=XRz-hZM{R1;i!8(eilJ6+F5rs{_~i5<1FbKe;MNZBcJ$A5PE{`r&DMJ&Aj z9(%uUx8LvgPaQ?e$gTIs?Ja@vnrW5L*g8zkOsMr@R<#IAzqse%1TC#TJDlP;xO@ik zs&JYtx3_d&a?f_b@u+Kq;s*Gn{3I2jR5+WdLP?T@@uQZTG>T11QSs^LTsjYQ5uPY^ zOHzx~;wva*UZ*RvfE{v`1LDn}++>+L^SOd-f2tq=Ph+mmH-SfJEG}EVbJWVoT$BtR}6A+owyIq`%B%qe^Rb!WZ zy(RgJU4ZV=?A8xQ4+gpMA14Mng|9LcRYaPVp2gMX?p6!)7dv2_TxC08tG5h>3in&! z+2otgeeN$h%YBG!j!jZJvoQzyT{F3aDI<40S?AclVFn2Rr@KWM2()zMm(Ji+u9kFz zRb~h?aSubLs?-CIs<@Y;$QKfS`iemtOWlZZe%6klK!F(+h7OW>_C9FItuGnB1nYWi ziYqTPu#>gY3Vrq~aDHC5lOo`u>AHD?o5bm{mHu%xyTD|Dh(1SdS}!;040+rdC3m(= z?y;M_JVhRGgc`~Ya>B&A!m5c2jdP4w$Ikt+metN2{@3bOrf9P>tPe}{^(Z}aQcMQ~ zH|Gb)#CfU9?u>Kjc%Xwl6=6h&*JM$&(D*F9GYgqUgwx51_OnaNPiP{d3Px~p^NvNcyTxCYB zvkoujUwftLMq)5-iS0O(V_hM$R7}1i~RN-6-vno$!<)`G@!#9TuhC;^Yf);B zcsk4Qh@wXG5c`-$BbslP#uKnxf8yI1Bb(c%(S_@w-`r0R)37KOAV?j`NIliH8O9N8SQ3OaeMac#ECpkJU>Yk57@gn3lOCoV z!hYN4uq0mVYDO(X)oSCFN0dJ|1t|7|UEqZ^J=W4Y=l`s+ z)35+UM~~?Cm@=Fsau4% zGA_jWE)+`g%ucwq3p6*m%WR}rkUmd&HDrtb9=9*xhZE)6Pa|fQvkKQFD~3+A(3C7MKk<)Vtk~efSTY z4R0M%&35Svs$8QMWj=rc&YJircmF)lK?fsIMdxXe&#D#ImFzY=!I#I|&G_hpeFEok zew8bME@IV?wvQq0?#qFyRu-XHzc0OFe;U$7YR2kK`3jlT<&;ye-x!&cgTsbO3n4h9 z{W}0iRk{~uI4$#Y-t^~R6V3#8Fhe)iwg&>VGIyBVZ$Y{c&>_%A<}1B(mWuiblt%?G zH;VQuf;6V7DZW0FC2a48|2fD$>o-Dj==@_ReE+r`4HEur>ZCf>arcm1y@h?9Rs^2v zjtd2L9Od*`?!aqobcge1h6jG>SB)tus1qHhTKi)_!o zFM;WGGc_zj9f}TpEBz{9aI*V@tUai-L9_7+f&$)|yBEQq2i5BHg~Fc~=0w{q?&F6- zS04!xWtV*t@b)zt$>gtzyJM3OxWZCX{nqdFX|%X>7JHh50a3yV^iC`$3&W|r28rFo zj%dME1VHjt1FYWfNy$dRKW*Sv-q%t{S$0vpI0>B|9j7!kUH~EzrIsf zBzGZ9tCKJeOT}CZk#o*sgpD6=EL0w*8q35D5jPO?ode+<-nXB4UiDSGh>&X?q65Z% zqvwTx<;}(_>_GTWd5~ZrgA}>oU!oO6Y12{jGScW-)jeo?4~=TxZ+cV8=Ty+EB+-t7 z2OVk@cBjYfmNdyZR1r5TbMQPSCAi+idF-6u&0uzV@OZMZE5P9s3M`)Z^n7@zw0fQe zBs|(s0DjvXlbZcH{Cp_68~J2tZOikQ%lYaaU%=Z#Do7Eksy}JU zr?Y&}(2++Pf$7$T zUd8U}1{ymrXP1O=^xxuh{?U^tOH%C?HdvRm%M*KQ3IoT-0j3A8)?LS0Y8j$`&c}zR zAZmB>_`<8239|l0SS>Q7&DrCoV#R)Mi5C+ktwE<#j(0`(2ZX#OSK|oIdoBcSl-q+U z_DHro5)C*ZAY;NV$P%~5m!2TcX=ouTzZD&qa?F#%>o=_GZL<5Ja2_Hvjy* zOE;nZf}`rQbLGkNY?&5rry!9ftup-5yHe};DQ0&Ul-!wFkmuZfG$!K=Tlm_M?306g zVy+Qr6z%#F3l+rpXUKoOC-rPMC?(^7K1+emIpjQw{h?G@(!*sp)CktmYy1pqp`jo@ zXCoS~grHZVi4-v%cbw+a**4G#yt4*TyhLP2p0wTA{Zc5}dC}}Qn+pNcHUc!qPF5nk ziHO@Fl)Gc!SPhz1{NJ;Ih|jLB!F^Af9Dlo$i>~z_rvIIy@w=G_4E!Vd28Dh}RdpAI z?QW6kVP84I0~fu0o<@32J{(d7$3Bmt7lk4&^TVJvq(>!f7?(MGZj`qOeE;c;4K_<* z=SQXeMK!7BuaoUS0vCX+<2e?!N_@FHAmO|Gt4j;UUNYc`jg+SI{p3%LX4~B*cu$`f zwV;idaO~}mzc2)@>5fA?vz|-z5FF!3$^@=G3BRMy>0PO04#>yUAlu%mkDx{L>dq1& zsd=p%>m$Xl*tur+F*7|edL<50*en{WkB+8CNB=zUrHl!=_hUJoY%Lc1V_Tm>8qxTL zxO~N74A1N9zX|HY5YA>fa65iiO8T-0gxng@EjAa)ZX%Up>Oh8N4#&tH#TDdPkI8e% zEZSh=gVwRH-B$bhQqvE^nybL3Y+%!~8rLDC^YK86|A9SBWd_wEXO7nJ@e}4ff~#_| zS}EmZ^S*rBSuL-;7%`8(Cae|j1GK9^Mh`#5IwhD?rU6D%pf05Q09Z-j!krBL?spM} z*yi-$l^6Ue33FwDDDQX3X{d9>0Tw)}u3?JHd z5bM6U?C|6}%48PpF~T0yML-ds8%JEZI=M_4<3z;$7QN49rSN)?^6rcqlERD97dJ`s z{s^QgE6mcNK;TtCd;^DV>lu5YCm5(}bHkc_Z7RbJbIa%^{XtSR^Ju?Fq0yEH&A}AD zk~P(BWf;SZ^kxH~ho56~S7b~4=dWtChDR$FBP2#s2*PaNW15ozwR#O}1)GsiDfWZ& zJBbC^80_MyJOr~I{)(Q6Op(s<*+uj>+Xh_GTQn`Tf&U<|#CS)&aibNrdM_^?8c#cc z!ik59m zn+{Ve8mZ2isd@S*N(_Db%D5@1zl}4w>^H%j(aLlgB%?rB*rM-7Ke3LMX%D-$-mq^H zBfhvbZP4x8&OwSRF!mqg?rl1F$zFA)bZo`s+kb+85`tKnprq1!!J!u;uNhW14tl`x zcX8_vlItRP3vpQqi`JLpUx!-@L=1o>)|Lkd0K#}PmH+4)Vq)`mIYMGGW z`*s=w`>zx#oL!06O&Rbl*u_DG=-@}yc}~k$W#1~}X!D7%7XI|Y(O#U0h7Wj&>(7i_ zAw=Xlf+_=a+YcDcr;HDgrtn|>!0dC_8?DUlvf-s@Dw8MJ|5$&Llnyx>Ka|c5tGCZo z*bilb^4|4RKM20RnO~nXIh^?R_zMjXIXRA1Yhe7`W)A;`PAHfmDgHbhPq(eWXj_zO z)!qJVUjMD5@bd{c5=N_dd$>C7J4C`7v2i{@s?6dq*MHm=#^p)onm_fSCQbQSeQmic z=K}4q9WB7L*(?E4Lz)>C#nilNmCM-tmP-7WHF$*1IMorye}-f)4A)9nt#v$HG+A~> zl>f6ub!WjKHN@F5qmyr)MzWPgdfcTLleaq29xRmAH09aoy^h6q_*?~e(K7>`ZpFdd z?u0GKlO}paB#8QTFiGWbN!>K1)Ak)ry(H#L6FWb!fQFEE8z;)O6&%$gQPX9tx4eDgH zoXs(Rp${e^wN4m}B*OGYz@2I-xMTmCTS{WPVz>@Xz@6YbROH_KdZJCl4mK;TDjLY*#Q6=@ zaO&}rAH2Lwf9v9$VXv+ans!Os{|`(Y?*>Vvo!)lQ=b6^3K^`~Me{uTq(#Zcq?fCCf zU7A0-{yj}wQ@`L_{}oTn#mb0`7G!xZ?;9iJ!X{tjZ8Gd)F%z+) zA;@AzUgyx8JYckXIZ2?t2}<6&Cdt2km+Z;?fHJ^cgx-X9I3TXlbzUG!O|&zB9fk8l z*V|V%iz2~k4*Wmq zMo5s!`OZ7#kske+3>|#q3sPA+Ge&W94EdL-li}`Zz$4aaghz^W%RaTUhWjuF>Mi%$ zhOKy*TxRQA=JUM{l*e@YVg}s}B4-}q&bOC3<@R2o;Y|Sad{xq8Y7@D!k0B;Cd3}AS zR(m&(;p`;ubE!4nt|zE|{$)&+=;}i_YlIPWCi=BlVkkoCZk-DGR3wHRoIQP<{ASF5){580OVVNBZEz3Hq)dMVNon^8-9nsE{gTxU(!?}ySFO(@+ zN6lvF?EJiihc-<>qxNUOYx70((#=ae(ym9&*k|3Ve!?BNtAx1|pC|oxwC5@6Q2TpL zn0Qa&e*fEJFFqUGD-vH;$igzY>GegXi-6fahdF^QXS0uNau|HXuo=m~r{Z~dOk5y} z2TRWgk?RU455GZyX!65r$IJeoF!0ysee#+STfI0)Zqn)?`JcVL*QXk2v|SW+l-8gf z`(Ne?8hOHt}HXL4%hwH7yzk zk0u2S*(LkE@3dIa6#eG! zj^r&)x%Fq=aC9|NBjBtvBBwp+3Gekbg67Gy{h3Qywmd7qaC7Y}OYr_(P%J5P zOOs{lP&?QEn3is}`-o;8LTM&aqPQSVPG)^Wq@F!|xJTm(T8ah;hKKhv#+}fkacgKO zGpNGo1)us&m%(Bf|@DW z)nRNI9TAEl029hHiDm?~?i@6WOzfyHU+=f1rvKr$8Fe++b}f)p@T7kIQI-^i8Fkdn zymbSrcu+T$@ZvC*df2Jkjs1fr1ulcm&}$zb(tP~lr-aTF^Ui2__B91R-DyG;gEpykLqNHh&t%0bbT1+S+5 z{64IU5+9(eQp0RY^)O;e#WcdS*^$+TGF{GWnz?afF;9&5-0cLeIe z;x3sUtp?UK8WVU59P~$YpHf`~fpM=_LEFwbI;a0Nuh?0QkdJLz*LMGy%*LW=v{5a!{FA#V9$+vuNM|Rq~5&w{Dgw7Da zVUJ^v&=_GC1H0e!)1#ZJOP7%&J9irP4%VRRn(kyd5c*>6KtOJg`u?IWZd|S-In@h? zZSj&#zb9Lw>Zo!q%k7sqPwl3bCSA#y$4#A z+SoGhYosX2(4yVdO`UKh$1TM$ArTWv)ONu|!k!RoL?sJA7c!jZ5x08lwC~Gz0Fi&J zzQk5|mpVN%kbRjRo|fet#KP<0+YOTHZq7irnzFD4j1vDz-ZV6(LnyJx9%so^?*5YY zn$^U6RTV4ouf>_F>bnLak z2(i26hhuxr3vE zi1^GQZj2*}5UoO`dU%jMI181nl^SVv($B0-@4~b7papHyVVN+JLuo#%bWV{pjwSiC zeIDj#;coSlJ?M3t{EGZbO|;13JGeBR5In1VD7;!&m6}gD1-WCM1-!E&W7V}icq6~( z;_SUuulU(MjpF~0uT15DI?a3hgv2cKm`P}LIn0M9OP=ML(H<=6l_t;92J^(qf+>AE zFb$weGjG*MVZkPvM*r3q2@_XTnNsu42Z2?x1&hhS@XND2F_~d~?1n_z>|oZsS!+W) zQ@*wX?Ma58DC>&VsB1hMvIZrfK#{u(x6A>JxD9;swAna~aH_39olyA6id@v!*Roan zdyPwo@o7gC0Z4q_zw@OxW%9ZEG1eUCYa9)SVh$v*S8xt6p+|imR(|f>t^I-F{gLb1_+F6AwuN%^{KD6&cOqOuAZ) zNeYnqQ***HYH$aQIOUsu&}7K3Qp|N2YO1r@H) z-&Kd&qXl1PZaI|`AOppOI_K?d@6x*y2+yDTEHQ(B*aolyOf-4x!b_a1A6I{Jh(=Hp z@7&I&Sh()o)0IEa0i;P%3dUz?tN`%Nc@5dc;|-))-Chwtm-2+G5-zg=&=7Vh@k0l8 z7_rM#Vi!{WaYhM1csT5oJZD{H$c>?Tu=GIoMHa?-QdLPB-K%Fo@!kP4c0Cd*pxV-Fv__SpKwX0Lo4WOBGUj47Vv;*yd;j~U3FyQBi4LN{peQH z3{I|!HrmNIhmM!nqfUJkx6feR5DG0S$}7#f3aynY56k7jWDWtJlT-Gt*u&~LX^wW+ z--%4dC9Mt0I8F4})Y!VMos{7yl`1=lf7Ep#D8^kDBmzP zxkD5sy?b*bpMPTccaSKM7cd<)g%-nEcf~86rA!Lzww-xY(7cOfQL_XzX*T20qY1{B zd+6E7m?t;0jOGo@(JX<|1@4J z45A=9nkkCvWlH@aW8EX_>5F}4KgW^QfQ zsXiGw6N01-a0l|S3q6MVfLktb1;sd%UPQC8qI`B+m<`MV_NQ`pRQ~-p9c{u%e$xCwI_n0YApH{ z0d)8RGGai3Ihd@SV}%qzQwVrLO|pqQJ6qYL9M;1$wIV0f%@M|lj1F*OakG7_%#zv^ zz855mh`ypNU2*H;sFa52vUWm@s0jacevp4ZZLOy-9z>Fi3`lZZ>3NQnVh~75_oDXb z)!-+Hahl^xV)H7Hz_BB`oYsrB?NtyW*E`Og3EB%O)NQp~mCw1JAx{C3JP840SL-vh zVy!jSkO2NySjb7AExYn7*LvOk$+`7aMoY`O&&%1>iYpf&U|KxkKxf5cd_fqyPC7C@ z+A5+|HXK%EESAi208BSJUf$6yrW_HUsD{kiz;F90AGg;YCwD|)+f_WvU(z&}_sg-0 zGU)U7(>*6kOV!)=eF%qGWBT9?sfC`{RY@QbT&&-GQf;xv?IU1ia_AtEGIa^wjmP|q zhNb$wDY~3t%_vjYoKU5^D4S=)f?jc%R62JbTw`R8_auVUbZ|>m$kts|{)MKLvUVAO zBDVnwhB3>ied`~(h@M@HxoW%JliVhQjJC%qBMcbnn%%fNyH?-_cBpxLry8@j|r}Nd4X2o_PV2yQ@ZloSPr}t6ilY4 zOTo^V0vkWp^Atu-j&4}k8B2tMjPVc&WV38^H&p(;L^(yNfMx_mx=(D=CqD1N<&vA> z{St($5XcIP-U}J4D5@ubLmwndCaikoPPy~-%PUaja>05dXq=+1Z19#&_eAH9_Xpf; zB1JLXy^xL{8i|FI`5N!Bi>l zp+%clQTHBL6wha6pWB-E(C+Zz;-gTzHi=if-@A43MxP(I2i54b&azRwW#Pl47*B!D zI9cqeJ9U+vt@>35O!NS=P4GC0SQE!A59_r*hFEob%C`&v$y~XD1dOI+db&z`h|!X* zsTvPCz_$%)Sug2i!&;&7mkY~4G35ww9rziL($D8zUIk9*adKxz5_P{Z_G7g+qGxZ? z@mZ&M{xeRXeo-&|nf1`IzYKEInp^?oW;6xym*l*HTb$@nM7h^cS;i>g0P<%n!;EBw zu;zj3TegGmla+P++#}tLSZ9r~C*BIfigc{O10-5A22$_}0HbJ=(TozKU|OBnGJ!j~ zY~=2Pw1P7#8BdQB#Zrl%={2!tUNw4B4|=gpX$iJu%YXvzWLbA9*&Y-qTGzFxdVQkl zJ-JifjRh4S@s%q9fa8rmCVWDxvkx6M>TLLlWkIX?v;7>oho4Ql(vIg-Pd#&iIv`d$ zp_%kcB}bzQXU z<#qjzw@sout+@lO-xbR}sRAr1B0w>L)53aU%T|xJB7}mZbHxJ`Ws;B0O#@#UpCHrh zAhLQ{?4SUi=00KPS9kEE5*o%y8^2rnHj(jZElOEyD|p#h^&w*$w!C@5=uhGaJc*|B zFaCi#kc4K8W{Tsirpj_otugHuB?vEFU7iYs7(=DJJm{g3BcpoyYX<#|*c6X4Bm+wRtLBTJ)Hpkca8t+!M4V?c=@eDN{= za#8Bpd*y#yS6{2FbhCJq=z~L*Ta}JYesFaCoZV$1sefOGF1Wtddry|&AyTm7DMHKWppMNz=B=Gw~WwTs)YOf!8c zRj_KNrT)J4rI9X|9M^JJn17pHU6-cr^{Tk|>e^dVDkL8rYhLTLY~ulAMU#2gp99-T zt6rDPwOo_NUT#$o)%KP}X{uY6nqDQ-Q(?2ZM`s($_p@7V;*_~NrSwX}DP7i(dxs~U z<4fjPHOt@%+vb@Q=bdcb_rNQFH$3%_+Y=?z$K@Yx=1s_uj$F`s^QprohZaTCFLm49 zyn~MHd}+0FQR(CNey=x4O+RH9`DO8S`&Fm%b#r)`er~vX!bGrO>J|=nuBQU0uC?@#q*71CN>z!3N|IKbW!;CY)ZFF zYxvcIib=B1XZlt6++P-I^+UERrcU}p1L ze0knB&WYRDx2ZI|H%OSFzJId3U!(tD8<9Jfr*0%WCn;mmWt*=D`>57hp)i#z-?{Z6{8f(=xT^kHo-NkEa{RXW|FotD6a7R#F~u$lek$N;>ge6- zu~LS6qfyhcpMvHR8Y#O4b3z={tRK919;Sb-I`r8>A6Nbz`}}QAEf(o~U^2&Qr!#Bt z``K@f|9Cz(=EO^fu$KjHE{|_aoaK9DC!K zs+4WY!8(p3r!o(2yvr2%qT_Mlyx;%w_qf0R&VB#j^VebbZ)@D~e-eG{ms(x_zU%9o z|JSW7zi9GHdG>~_52XB$z2b4zyIam7_QI}vw;H$hxA&jl=hyUyx6ZwnD7VxwS=KyJ zC}EG_JNe&>@3;%y{PQBO?9%`B4^DF=Z(Oj}_Bs`g+VE`o&;5ZZc=!I#&ldm>5n=Fj L^>bP0l+XkK1%kM1 literal 0 HcmV?d00001 diff --git a/bifrost/public/static/other-logos/langsmith.png b/bifrost/public/static/other-logos/langsmith.png new file mode 100644 index 0000000000000000000000000000000000000000..e43e0eb852d855bc01da8f319f0a3f372ddc4ca9 GIT binary patch literal 5739 zcmV-x7L@6UP)002@51^@s6)0N*p00009a7bBm001mY z001mY0i`{bsQ>@~0drDELIAGL9O(c600d`2O+f$vv5yP@8{+U_A#UNCH+yOznptMS>sC2p*|g>kaRhUe58TZN+QVTD+WUEj_k) zsYk?mj+cTQ11w24fI{`qM-fCJn}mQ|!zG*S&dh(_Zv!;IOtPEIgk9M8c{VdUm(1)x z?|lDv`@dgM0$}uv8J_Ly)@AFuK7^zkE)*qGO4(ZokwGbR3BojWQ;2P(D2<9~Zo;Oo z(Z2OV6{Xhi_v>_&A?PUJw8@jxLye7Nq-jntr92xqaSA>sfpmRI2!&E`4U$Ml1MkCf zJHD<_6lJ9pVo`5h|8#92u!p)C-A2GsN+B801odaOs;V!8h@X;+aE*XNN=ha`r@IrY z6DftHg(AdTAjz+5Dl7j^F2HdD4lXS{*N8-(hB)_83dah<=%On<9?$g~7B8+L2jLh2 zhnAKOhQ#|f7#261L!gVVY!MtpKm;t|B0_Tl)^C& z=!a_*!??btx_TLP5nUo6^t^t0B=Qh^Of$g5G)m!k!d{T)*|hZZhu1Gy&_bO=rwN#q zpMScds{e)6?@$WIEkL0EfuV9MjFblI1Uf~)?Be2lVHj^=HH%V6foQej@%%8jWXWd~ zC*mexUQtmIyy)-X^DRmtg?}Ol%X3Pws%lj{C&gv0!l^tVMZOelkcTMO{9KB3!u&cXW$Yw8HbJU+Aql^Z<=~hI zIN0YKYMAC~te!ybAp}3uuWHAQn?*BcnpOv7m6V*U==#sFdL2FkDTPEu4fW}BZr#F# zJ32bBLjn%=dNXw?7vsRw$vx~)q`V>+2z(gJ!5Lof0FRV^fRy|JrI45qqT=4{?P7<%C(N`aw+U<=SQ%o?U?RkjJI)269;n>U|kN_jQD-A*p4R?wsF$n$zX z4pvsaWp|8i7o1a4GMsdsQ*ru`doa*guhdsnT}Pb+>!+q^F2nyBM8_{A9%Qvtlw0a5 zD*h4Ai37{Z2K5Mse}UC&@glqNtQ(}JomcPo*IDhf?t<}#^xd=PWvq=P7lB5bGbj|g zxuK!Kq)wu-re;^)+}vG|q?74*gb>YW$A<=nLN~5mzC7+|#J&w1_CcLlfHwR@C`th~ z^(SYM4r2G-6Ab>%YNw?H%=7uKfmE48E&>7VIklCQ*OCK3OuA>pFxJ3|9zw?#IC1oP zwBsA(064s=s_H!SCTEee2*EWo8LpWl^uZ$>(ZkO_zppgSJIP(tq=mzGkwe(%_c!B* zJV?hEn(&)%af*D5P0N;jL8^M46k;Pei(csBe!)iV;X97l(BkpjDcR}kCWLr?{fZU4 z$w3TL)z{YR`ona5q=Yr0yPO`ZsCd`z08Wz|;`3#oXE;w)l(X?nHFS4DP0GNAKwz!i zd9_QIew^j?-i>4bo19HpF8<0ereb->3vbG=W`L*98J^+Z_PQ^GsN{{4%op>~IS=0s*j67{(K|)zwU3Y4tyHi;CXG zj!Vc%NVyDF&V_A9-yPBgH#Ik3EZx_m_L#c9g*8Z_%SS;9XBjQezU3`;y!*sy5P7Nym%WzeyQXt&#*&X?=;UV(@FCL~uTb&MV`+8$|aXt>X6XMG^B z9AuwQ4#SZ0mbRonNWfhupIqpI^Ji;ibmx6eDCF5aKUJH`yALgvZUmMnKNg0 zdQ3?$Gjjc7ZH$ z@X+gG6x~jMl~7LC`L^X=u4SU@d3DQ{g{YJ0KX&Yiy_=i;BFTpg;F-LDNYU+NV=S=b zi;}Nv;j|q+Baxw2o(UKuyKvzX$yt0}S5*}aazrKIpUTS%x{-Vg4upT(cCVBtE2?@U zbpboe%Nt?om0{I!YrESZMBS;H#{N=k@)Z?L0Qq=aPFG{O{X!m(Wg#eBxKm?2I=~sH z6cy$1N|b=m*srDp0}P^@sEdFE-JuKdeXLee5(28q{dNfjQOQTdU8EB=b`)I9F44G| zoQDVtacS#?DcTR8M~Mb0&qO1iN?imGpauyqgEaYsk_A$-mtchZ+^%IuCB7_Kt;a%=&umnC$F%2e$F=s;{no6b}BCt*iV?W}GaC{0u-b<%{&I2=5Pl;R{Fp>0V7e;hC~_F<@vu!z zyA+N8IUPkr$){=8ZCbUeDVF2)oSa@DMVheD*BFq5pK`4p9^Tr~|C2(@LHzt-t9^Mz zMW>M4wH<{xnY*`yPG#2-I42jtDdLEhOrtoYg_GcPrzrXS{+PSWv`7S@RLP&b(+Uf1 z2NgjtB*1b!@LQ?-GH4bK427<;BOhlC=lXoF z8m4LKn}yV9jqIRZgrdwtsO+bfS78UXlrPd@zYFKQP*+xVj~)3y{0vA>_A$Ed89}?J zDM>IbLS|k=!(eg|^<&5W1?@14Tn6iWgF>Mxt88>WPKjG@81LZ8TnXdQQuPo$dp=HW z^7KHK-{yF|mSM}D>FF;+%G4e_SBMvDOH1#tt2~iiQj(+V`v2mAHlbYs<=RYma=2uD_1ev#I-_Bt}Ak2C^;!ng0WZ$=!D3J7w(H z6NO=LBCBJL{}{m~S>$F)aNr)NSt;dCqqe&GD?Bhq$CL=pCNYd@Uze9RTJ1kGKmS{h ze5?XYIBZu>ocmLu0~a5!cVn1c`W>KS6S|Z zG^?wsdc8%{xOaF9&(Ts(ZZD@Y%je4#x<2=4kS_`;w=2{-fnB1*gSX|!)C~w$RqaHV z|7g2Dv{-=#?$N8)Y^z(GLN!O;0QqvoiQkHP96`vEsna)9skDOQ-N8vyb52zAvU(KO2u zY++rW4t8Eev11erg!kbf{w^J+6J}j<3D3WGKE;?|!O}FMs^xh4=g?6GMD{ubR)}k^ z2d9CD@ZE58Gtb22T872}Y^tg%$3>P?=Mm~VV8A+y?c7)1MsWha{S17TW)&9xEN{}J zg9U_?UArE@qCcd`U)npLheE<>eH(t$;;6(-0GK^`d?K<&kM1pc^=fo2^VNB9#mx($ zfcwd1?4Rj#33UdDSit%$Jbd#oDE=*`xt_WZX~47EfW`0Ntd2m1dK~2Q=b7fzWflep z4|8pdM0mXL9U$IWi4u5V?*QCMSqf)jKv&s7$paox{pZ|*0!P!dtPmx+5S^Ni3Zw{H zZI77dY1G9q7bM|Oj(|u-d78K=rN?uZ75R8b!){$)j^DtB(5OU;dddBnNYNWYW5raP zIZ*)XX$TsBF_d{X>sCi0O!IN-1mGyP9L$4zcdQyIq)3Y@#07PJ|9Z;(;Bz`C0$L7{2dTwX>AI8;$8x;rJwA@ssSn44Ev=w9Y-YxwGq6emDHOScIW*e{4H zTy+ghzDw$DGMS@MBVB(G_t1|L5O^^@+vxXik{U zM0=iPRgiJZ`0?AYZzXje+aN5;?8wJ3B9ULp*6LV^2_X*FxH+hl>Ov$d0U0Ngi`Z0N z&IU!i)^LxnB9S9QT#%@ysy;}q)_mNzA{6B^Sl6~bKh6(?o_QZ7E}C`IJXl`tAOX`< zbp@EYj*cZj0y&k$fNtY8iWiD6@70l#9=u*>uM4Vq2J5Gog#sgM6*#BCanR$<*sz1b6 zo@du;NWc!kQ<7;~S#2O-8=GeGnWp(1C1`lNkekNVT`KW{l z1m?Eg24cMklHJ602x*A|(@#ix5r(`&X)0v?ivvC`1A)g6r&P8RY})CDSTt*xwlvF*kq z2spH?Y*3`7C4g1eBMpv1h}CdCj5(11HfsF%K08984g0f6D&ZKulvAzRo&ti_ORHJm zIr`!8OsiYG*mB5bPJVtisVaBJF%?h3HP*n_I;p0j!qJG+ew~lI-9#rJ6O9MWk3T#= z@rck&w9ayCg>^~E1Sv!+Koo6$J_iq#RxS18HSW|GD}Mx8C=Dx0;Ko9Cky!)&@Y~}N{+RR4W?&h@vyv) zDY*~^DT1uaK{8Y#40TW2osjeUbd!-B?bAQ9?jiURb~0Y+A7_ME{sIHHGsFRTk`MP z18#B)8vGMT=08go<*IrT#CaLEmw*5#azP%Us!!DV{VREn4B6^b-v!bQIxO|*^}4F6 zE2EV~Tc+i z?dDB3aZkn|bg${Esz-++?gx*#XpxfV%w-qT!rrF&OmvcznKPA~^77w9V)773O>%Ce zlYA&eJxdR;|@?Yt)K{}>*nuj@Q{ovQ)=b|Gaw=e7%;J4J{|gU&c(&8pe6*>@(R z#nl%rnt}V9j^m1mrJj^eowR4qbE{Xc-p8kN4V5NEDKJ6c`VJm+3%Y1r>1YJ-Yw-I5 z_#GT^X@S8cpfe7NmL-vL47R0F5(3X_R()C7zuFB4Wpwy9WuJH6Nuoy&wu(=qqYONd zXYfEcx$<==ZyP|WyJZ_|9bNQ&hN6tXzBdN;>sPsD$Bx@@&iy=VIGnhg1}}$CoY=Qz z@7`a6sMiqBWlQv?qG=1Iu1`f{T!Zf!l!6oZhZzcu>8SEoOyWGp=Q~@NreC&B^`0!? zw~mLMe%V`93)1)OY1-1K&je|jFADdnex}fh8Z^EShDWfY17p@Fvc29iNSL=l!oHMD zkn$aLX-lBXPGL)wQg9biZuclk>4tU^CfXt{g*KIOI^R}RRi|*J z)>zMp+oEC;?$77yj%mG8NFHp3E*%&77@acdv%KDORk$~jt~*Y_EwHEJqPiHn-L~k| zD5(d3-Iyn&hPvO{x5Su}qAH%oG)l|EbwBlG;CnrDu zY{X-K1OHE15>;79A%4t8SNBA)s_JWU0FK8M2NxGlGz^1B>>u^WNeT`^%8x;oTWbS> zu8inA0`3I15u?prwCHm93ppL#_38yFxCkK@gCx(@R#v()1HIds6#`+r>9Cl2+`~oP zaJ>|q0ngg`1|nZ`gEo15PNCZf!Nr86qD;aCxr)KaL>;w%yaGn#X7pHV5Y2ekqpEZ4 zW>9kcy43v;L&l65tgC7ve)Wa8fiv-=2jj>0OBpZSh7bt1lPh>(xz;qz`8}ode^p)m z4RtdTqDvf5Qj*al5*dQV$b^M80G4!r!SUtYN+qRvFZQGdGwv#8etuOEQ=l;J{_jc7eeNI<3YNM<7 z>b)Z5WyN5ju%Li|fM6xWg%yE-fGvK$10leE-obGkoj(<%y|{)G5D+2ze-E%oDuez{ zBe0XAm>^KiG|uVI52%@di~tZ&eH`?M!EYcS_E8C80cCgKOCNB5oS~E_wXGyJb2UUl zgmFa32$Fv%^sKC4xv;Clko%*4J&is+PHp#VZmh#*`~Ns_pVr8tjO+T0N$AO-lH-Hr zry=sIrno#x&iz!Dc(}MWc(^*b8o7`jBTU>(Jv%BZD|Ne{yVb6NvHnl-0eAY^&GN(l z-xie+Z^Ehk|B8YNecu1p&9j1_V&$}c|R@S{+?I)ZGael#PcN#ZQC`+&y81g7-wNvyTnASoXE)Hi0z1-H zPuQX2z^AGHv+87g5TyB2XEe5tB1}0RyWDfq$aR z2WFbQ+&*5aHw?-Nra2pt1*a3cdu-dKb}mYgv+W&a%JItxsY8L(&0|ovYjY9B1bkg%h$xbWcx3y#+Nwzt6 zso@dsR&fB9Fyh75hJWqnguoy`7#AUKDnhUf4MO*`{dm3p1dfk}4Ai-0bZ%TypJb8C z(D!3^of!^Cn!~K0;gDeI$IvVv6vQWH!MYwK$*2? zWYu6F{592Gua92l;zo5w2cEo0U17I`l%z2D-V91n9=OF`e@xdL2FC|sKD7u$v55Zb zx|UM{<8_WLCSe2p!2Ll1IgV$WOlU0>3y`zE&iFE8hc8Nn93LfrT2~GJHXXVm^s?Y% zQ>4RGE%u*+U`e4Z%Iy;A-?r>B?N7vcy0844!NTBs+vmcnHwrK;!@b_-;0ssX^3WK? z3-z8wu0-x)w|hq8j#8!F#0r1>Y#3-3oN&tiMjuCx2baWVZjj$&#dtkT?~^;$n2L)8 zt2sOfYz{e&dp;1A+S}Q!2Ur1BFenz0?{gQ#p}9TG%IC*vjdm%ruLuM>j3J8%u;?+0 z@^-qa;aWH6x5Xm!xe)@e!(z!CHmZ5KzBJ5xL82xR%-nD24um&z1OM}L4*3jaBH-*P zdK%qCehq?C|EiDAe;_bgErT`!JnC31e>Xb)J_az>xdPjt#{<-9qQmecsAO~+7k>5x z5Mf9`O_Or&%^C*q^}b<}Q4(o~PL9{nOdBKORz%f;*W|Xi z*Sy4V5<~mnlp+!t4|@ZY*6Z41X{N|-e;6H_D3uh#uoGDCKG?o%K)~Ua@)e;2S9k9} zoGdi`8-BK^SqunI)On(Sc`GZ$QFUNtq%mQj)*U1zF04xuvBMzFbn)aSBQdZz+9N7* zv0{F-5$al!gfSRyC{ZDy{mYodi`&1t4Z>v5$|##8BP0VQG7Kp}87X?q0 ziteSF_xe?rB@b(3A&xcWla*?XZu7JG{N|5$p<=^;&7>-l5Yv_SHon6k5)3#TCoZ@8 zFWG8ru?TR#n;F_Pu2!%qS_@}aMiRhc3B_#st~fadBPLlUDU})~nV3vCF%E;g)`Yy? zwUCVrn5q9>#K5bZ`MkUCQlBtEb;$scSB}izaA^v9I`IC^+OtDU>Aohj>oIpwkEt8>;y2g+C~C) zw}G}f*#Zmwz*OCQJD2j*O8zO=jQ*^6B?GzlC!=Yn*AzLkUZ1Ax$klPu8SY zaQ5?}$BcA%hAI#bJb0KKr=6@wulHwq8Oai7$pOVN%)MJ(Io4d&hB#hujEgKKu(=MI z`-_H(57TdYOI3RlNVC5yLt?PUFyQFKPgu*mvgju-(~bD}>mqIelP7!=5W1DqxLzG7 z2H<-#Ocf6|+DO63aa-&S{Y5gjft%|@T+^FZpgvP(%rSEaZ!o9KVs80eIyJF79tS@# zs3cf6=#4OQ%k@1M*j&4U@_>5&%Eq$Wjou8{*unf$Ijh#>#*y?30KQ{2be=h&uLEVg z?V=I@u=692jM~vsGISDtZHMdX>RRUQx{)e~WEvo^u^dM4WydLY;pC{)yZ*QGog#|I zc3%;Fl)Ezs&Nmxu=j~KA!qEYZ%3$hhEvJ8*gxU2Wi3Sc2m4H}MD6B#z6_c(V$XGlZ zQS$bA$^Pk#jIJ|i|MhApfZ8l8ll)fIMlmEN__out9g53!4$XVXDP|-@{&i<>EPu4p z{mi<*yfIL--)P3?_PzP(LOIevl)(%;IS>|2h(a$b=tEu%F6OIt07Ic#M!b=0|Ja&> z%`Ie)?mQL*Zqbi`dxf1y0AKtYk~Xh=t>4afEB09LW}(y2@YQid{IV|daCIruFkrJa zx2fbaFCwF#^zZP^s}&Iji=eTPa)yo_mM$f`Cy9uxW$$F{DmFE#WIe53sz@YrrvATj zc|BWpEP_XP$O(;7Om~~Y*<08RBFf;17;Gf>9WNBMqsogjP`E)sMYGBfc z!{gS)5yyICvKmQ}A@$xI19vGng`sSFQhJbk+31T41(s`)Ds(f_S;509G>G!QHZFZn z^%xIn5K_dbEgpAW>yIXWV zP;U%1C&c?RW;3gAFb~=u=C7*W+ea0liac{r?c<=yj@gBK zCtZTN+Oibqo|vD^i*|UiTzwt$9RrwTvWmaiZr;C12rgRp1Yt^>c!jFrJ7}=5mtS;nzafygWi*!n8R5qp zp5+lgwJ(ln^qHleEh|f>%kDLYq25mE;nL{dJ0N*@sB4z#Qf=k6#^u=xVbyq-4xFOQv}DR zox{Z@q3i9_G<2z=FK0^=N}u4%_3BuZI4d+V+3W1=>Vki22vwfq%eL=^K|@Di6ML`% zb46uo#nmTs*^aLI897x+$bn>rxiU0WcI}~$ZNPTNosInOF{iA}A^=sJ6wXKqx`k*?krZ!l`!T%ybO~Bz_ zN&Y^?^e-C&cF(;SCWC>e$1aUQ&PHdn&!ysKfu;>c`(E15)| zz-I7}vXs2Su5FAImBA{mV{yjx=?R$^KHvA-oDd<+u7s`${a;PlTAM|{t`j?2>I@Aw zU(QLk^!j6gPG*9qk#uRgKd!@<hXP#huzbHo zXFeJ~VglGZ`S*3;is;^P)w>l#&Y;!INi0gt=d^6;UGs9uJBV3XYg2|}q;i3|Ag?h6 zE>A7$MB!>nH-p@UgI%^kk;8Vog7=lvV;Xlco-BPr8lz$90lw|&;JS)Ixq?HS6C~mL zhg8<&GX`WmXEK~ijd0fFD@zaW9M0>pdQbG;gkGTYSvhu@^fy#Hi;*ZO%O0y{TGt72 zD38}kjv*Qm;y~rtYBN)DFrj3cmNZQVqV@J_gwqT*m>M{qviso`o43eOWk9Hbf^-_a zHfo~jv>Pp@T8?HGK}S&y`m1zc2%K&mLFkNk3EqNf@JX{xkivJXizD~TF&Xz`5k7bv z=%G4I(_nkGMb!0{o82$`t}48}S^Z118kDT*NdUB7xY2x(3$MO0R^Esy6 z1|}-Qt1fpd6loS~$N;^Uq9mr}^L|{^Nd~~CqILq%xq`)hUX`FYine|;a7N?()kti= z20q{R^(NcZp-CewI@1#Vt%RMS8M^m+T-YW&n2J5(OT;)w>U0EV|K^RjqSKRbBH_l2 zPwFc*C~67Jqd#aEq>`NKzK(HomZ2OVI@F0fFc|4419hA&mJz>aO;3TNT!Mr9x2qOU z%_s7aO874=xh}^VdZWs1`h>1TAD3I(r8rH&c0_!?$pp%=-YH5`zcSym_d-u9HjIRU z^|qxL?ZXLFvx50K>qr4raqZ%#-KIJEz)c;y>lG1r&8qv+I_Kk-TX*O3kreJ9jSu5u z)TZxvwF_pYBd$3;y;rJ{bhF@Om6LuRshQ9|dcz`kz7GWu1ww^(q)xE_r}V-vI(Si1 zA4hHotTp0En?JBHIf9&M*c~r`eb@>*@IpS!3%fc~UgodclmIm-xGmMl+$X7MXYro>>G^b~YQ4ya7ESQ<=0y ziQB1jM=@uu_Z?g??f0%vIHr8(+_Y(EIc8rOdG)*ZZ7rm1NnPL9OztxxEJZh1Pe-J= z=W~&N9|;AcXIp!=fJ`}k=I+(!#&x)e%x!sxCngWMfE3p)h=LsUJuN2y={0^^UIF_p z*MNqJbMwhG3eq=G#<|JC!3f_hRyLIfYKsZ6C@&bzY4-uGq}cVKfD|_scQ1iQ9nKU| z*op>Op<~BRR}-LZr64CbeVUlHQZSpC3gxMV!8K^m<4h{gMQpDI#>vXXPVa+!I8E{o z`<>#E;$hDt4X{7nt>|iJ;ck4ox*5WUGNui*;R`(H)|QQXXetFYJL^dQY>|dTE)&|7 zS|G8C=ma&h)r7UGb+hfeMGQnP)=yP-W#_1vOc~R|s}L|14WF-r%&c46Hb)WBN@Nv` zLQ~r6m^Mybw%dDj%_%~Iz`+b`aRzQKZj}|KVL~mX8$BiinnIKt?jH3AlPs_8clyr> zP$mrz%H~6YGpq?@Cc$&*w4D2Kd6Vn+{k`y+1e0`o=GBC27^AVWhl3#z9hHCYu_--u zUa8k7ZgAjH)ym9d0c$O|*?BMD87+;sosVR)-Vo)x4T+7eFJY=t7Z=kCp-CXdX4bH| zwRkBUJjJ5Sp91nT$YUnfBdXqF(;Gh-7ppKbGUDK6I~0Gy*|BKGq}a#ZwEU1WuDPUB z>BA&$NP~6E{Tczy3Kq1${GL=4RZUp}^Z2}n)osJDUYAH8oUUhK{$J-SBNF>Gi9){u zkHp7LQRH4V)vi;NE7)cQxyFwT*A81_ z2=VA_^Sih9D2tddMqfQ+RMzslxMQH82x@at%Hg#9_sV+;+Su7k%b8XwerB}tw8hE?z9HC+@6(q9k z1My>EDQC{Z#nWW88lGY~!ExTVCH1d$pXmhzkY&=73CS&Bbj3@8R(qN|`H^S59><$H z?EXrSP(bPBfhd)rNpNUiILx_$4lU&VNx`euC1*|Q#Er8!c*MV-v|RObKfW4uW$--= zfiRZ)K})%A<-X&G)Os`e`a`mB(#HfC-IYz*@zZC}X`}%YdV4RWbS4hdzpy@3D~Kdy zhK#4-3P3VFdIo@4WSUEU^wJgAf0AF}H_5<5?vmln{z=QRE89?m1@do#O zQi7gqQxL$?79meF#o2iw8zBA5Ow}&(&HJPfODdId`@Vy1ZUY}rGm$Doob(74tf}&Q z?VGxtrMsw1uj4BK1oC3dq=Euyg*3$AiAL&@NEseNsT6)7ZBESoMZEgB-R;8I+-Abi z-RN}e@EzO{@6XL%1bL&Q!pSYA+U-Ur8#%pe)xftCpfJQAwJA80NYYHr)m;MI|| ztbHPa%}&*)EEskR)u#W={RdEktsFfpF$>lbQ!Fszu_n5EO z`@LZzrdBt?qwdBVe>lczXG~LByfIOFWjntl1L4Kt?Tg`z^!%(riVimfd1UA&rj|6mUXq$_k-W}w4kNS% z7BD`;Lwpw)tli|vvK;K{@a6Hu8oFsvf-5A+jB z;NMED^Eh}Ve~61Yx5D6SKXf`S>xfB})66mxm!BjIlPN1v3Q<@g#ygLry?8_vY%R1{ zZkcyt%Fb3xb5dDOUNz(au9cX&f3d^znrR3WvH5`zO=Z;I#fMudY2MDKC+4rc?{>O^ z9I48_@lu!aHi_Lrdrz~F`>81 zT9oXndrvloiJj+~hA?7+l+qa(0mJ(KkDuf_bVtC~%Ei2Tm@Isu{(Pa-e7eL!9-FRh zkW+*>rX*#=6ka(R?`Ua<#I{N7BE7Ate?SM!c=e(T1`_p6G%3>hE*C+A20GNJ2Mc=5 zvYFedde;ix{+X1vwiJ)u zs&J1wY(}6B$H8~t6!uR}^R%LoMXleK@erDa#|V1}8>Pf~SYwz1ijpGHF}FLGz!7?V-`p`tS4YIqephoX#sax%sLky^4JeP7;YlpbCu5O>k` z;&6;c0MzS=0=%ve*QUKa^eBSJU{MW;qO?5mQc}3$QYB*wOQie!c(fX9bu3V1nZY#X z$0!QRDHMZhbh%)@?-y9TpVvLPAh$LGn3NIcW_XpN&lDc7w;gnWa9&x^z3^PN1(7S4 zJ>w7(T%B0vT&}&@s9<6}?uRfO0L9SjLaFN9h{FJK5mP}v?R%da8dKS4H?Gp~sth6T z)^Jj{YBBNDwKo??9A3-OLGi5i1>8o{;-w?}noq(Y;9HEEZ^(fzB`a+=zYd|Lp19zw z+s%6~4#@gzex%-)koYSRSH(wU!})4Io~3wUNyFp z20fl;iXUyf>$HRh;z%5!H}ea1h-Noa)Dpo0+@^_R%LETB?UK!=EL?=D*;AT%x&QYpa?0-Dt0$$D1(zqGI_lVC%`wH%&nOTbKj;COB zwUYXiR+_S2x1u&^n(r0~TfDi($SMZ+lLl7X0#jE>ufRG%At&&441YJPr+~yo={3*byQv zR4J$>HiW=*DzM`S%^^;N+jaop^xF6%R>c(5d2KO(f889ljV4V-Xc)Fc=J1M2>HS~? zOH%gfDCI#Y%SkEBm&GmS&Fjf#~+7nJb@zv8B3;MS$f{>m(Cz2eIky!+{8P61{eMm z-lo0nm1Z-FV9o@js2PL*?YG@0i%nfF^UUsb<@{?jE#*jmP1{1Pa`c|0V%d=HnTEQ$ zSG!J(Weiy4DBxBR)opZksIWB!2tNll^Wu+8Vgl3XjlJXC*&vGXnlN&p9s-oTW#2&r zlaN)-38yUhfE1k#9Uia+5l^Q$;X`1QV;wO;ofl9&8-PGWWF=|XxdMvm-Y%h2I|l|| z8xEqO0i`Qux5w{V^bVG2J4QX>Iw8z*F_ph!JE`V*bOC<($QCc%N>Yq4yFJQr z?q$}gPqWpPV@8j1uPHU;z~$YHIOIK2IgKP>+vs^n@%({G|GcUXcTbIe3CPe;3c@0H zx{2LfEV!t@DI#26vf!c7V~*s*^n3?Fqz4zRLDgs;QBWKTL;@cVL>M#rUU#f(GiKQC zs6274uLr7kFh`f>RE%7)S(-SKFVUhBM7J{@jpWSADo;Qp;}RXYR%um8WhxyMEGi<@ zR>weoq7|2$3nob=)k&@6lu3PW*k!Y;%Cu~n66UKQ_ui4b5(f_?qemnwG}%yMsi2!I zdM)^<*B5O1hU7pb{AMt-1*@7-q!ED=?4`|vCKlp9M&Vg|4t@zuAj;XGv8Vt&xhoXy zpmm@A+sN)d8&?>133WmmG@+&Wp3&PzLRjthG3HaxzwJ93^Wb0<`0`3;H7ac>ma5Vd zDPEgb+H!+yF`0{<7}(8si5Ta5h5`bO7A_9-9Brjjc0q=WIVLcj<)*`*+GiI!H)y|6 z$6%kuy8~Z~n=*-JOGGl+AX(ia0N}RT-3x1U6l}-OpXRaY=zXW1qmh|&TdBb;pcmS! z)6EiO)UiM$XuFojFLaTP#!K&8#AJyKqgy>8O6^#XtsJ-+?xAHg%w{)m&cLZGCRITi z$@R)fs_A=#u#^UhC65u8 z`X5!qylhr6^qaKKC}K(FO7P7wc!Kc3Xl|m0PM< z+J}GpL!@;?L_Xua-j%XxEGY?tXI-xZ6lR3HLxPVX_WIoj{5GyH(iD*z76*5ZQJUtD zzfhBA6mD{KQ-T;xdan@dNRRUQpIb%*1z<8VxdwfY?aJ{BpM`6|m(1v;maYsM zCD4zdMhD7>7Z=4*{eJU5nwcS_q@Fhww>niX$mT3xkmsjH@2pXkNh@$yP$7JF9aBBE--ql*sgLaA1iGH5^KCRq zC5hL6`2r=vu?I$x!mJIy^)w`mB%{MH8#kXpSHVZWoa`>V%*^St8)QH=|`4L*S|K%e6gx^FjQya&%}Z~!4>Iceyo zPlSjT5ZF>hp?H}Nhrw5air#xIj56G2w}v#L_3nKG*9~$;OsV~i3=)uchWM8NyiEka zkvf+kBuwZ-C#7~Xx-`ki?oQ#~ZC5-hpwiBbMnrV7s5ErnEUD#RO+qG9K}qDlRKVop z2?5-QOG&MqNXYKcgg0>p6<6f@72JCB4hlR4=tGK{D`3;<+Q>L=q%L>->5PO@i~#7~FE^1HzZ-5r&?7_>g?{`Udm< z%F$fq={1Wy@P~4gCV+94!hL3!FO-5XnXwt{i^d&Ol|H32^ zW}sv_2OvJ74ab6r#yUF+cu_+qga;^*Ia=?W+Uz-!2gXdZI54wgc|sMocDq{ zZ26fPPh**pplD0X=}M!h!tKTA{JYXYJP;d_s!7)pS*LojMouDg21HU1C(D<$usK7T zG}~_Yq+20TUp9Y|HTvkMOFxqEpJU-Jwhe$&!EXHcB<08YHjv{-_9hN zXg_{aiQyYQh#l(rrl--yP=wF*5NVE&_oWPylS2NA#-Y94#;rx+$5 zewb}S5SZb@74=acCNx%?;AWli zOm%M;zU2fUPbb22F@uS^x)@x_H6H?ypXoag@bOfvdU88DqZ!FTNd&z1!H2`5VZtmE zJ0ycGlzpIz?9I*i=ELE?8w=7}o9u08FUfw;g;dtY?k%Xr#UnDmt~X$OXt9nsoWvWI zwadBN7Sp?3@egNV;g{wT7I`l-wRYQk+iU>_ma7XMQq>Hr0|rQF?*iSPOw%1G)68a= z<8$LmR_B<^I1y2=?60)sxfV()>>g2NS&HcVT-bS^>Z@e1lj%_Yu08W~)#LJgX{2RM z8cQ%<$0!JaYdID&8Wr)4&fyB$X0exiY$SujHBU!$LG%xLn*2TqliI_A!B5~Sp`oT$ z$}gF39v>URb?OERjaWE}cd$d=ER=%?cm?dP-I;ye2lg2@$uH(N$S23IYJL>cEfeEx z#&uqW6HEx2q&X6i3*+d0_-San4pC@ei$N7Voy^z27YvDq;`iEb9tK$t^21`B$%#HLJM3^h&pJn>}5JwnHWTWn!S>6&@3~3HL5?O^un7tyUk<}=lUQz|c6~~2Z#sx$>5NF&4EH=8oxrkB%Op|3S z8*MvdE=T$|M2#~mbF|-HKU8V7aUNd81Y3*$s2f2#2v{if7YOfjdwttyjb@gQs-|NJ zoZG5bg>`3P+q`JdqTX@#PV9#GuHIL^Xo}wuX^!sZ@f~VOMe^k=SuDY{M%yC#v9ZmB zx4sXZdD8v#^YNtjBXg&oT$A6DB&vfV$3leBbU7j5_W@>+;H6nDt=c{&A)opchtoTpk+RpY-jDh!|jNh&q2^JuJ_R)(_(dsmJk z9$|jtMi8z=M0k=oyw7A>>3_26H!C8t2kQKa{E#!=mD=xzwwg^LYwVR*O&f*da0Yq5%##AA%}b3+5)XaG<$vy#~}y!!Coj)B2olLa%;X#gu1 z##Nd0QfMOtXW|V-c0Ik(^fqttxuN~~(@2J8I^&TbMc3zk^|IMM#N8;oLpr;JekgDy zjW!dGi|+n<2>Ny2DWRTDP{DF4VIX$j&rcTi;ljzAIT&&+4dDB70_{g6ZvFZ=>|_0S zTj>jIR4wU7gFK1To{OmUc8RXQnFg!ZvnkbFsT(Iqx!X(4%y9V5@#t2)-XKsQDl&H+x#-DW zgL@#Ni{jCv5(3d-iXT4Kp>r)!?@J&&(6y@ zkJ+CkDS(ef9&HD4B-ho$SP}b(AfnWqXhMzx3{Y`%I4Ye)&~PHxUd@{`Y>6x!g>4Mw zrKqy-_k)VeYG>{IM_m`zH2YS+oLw35R32v;iNP1&hdfO0N3ob!S_XyQH+ZW@igC{lVVBX)H+tT(U9w0g3fvav1Vn0*A=|y`S&biomDQZs^g6`$BPS()o0=q}t=TFp7lxr|wg<3-2DuV)?E|nhqsN=?Lbgku* z(o3qzj}->;{nm^SsB-XEW!%MX>?W=hk`)6322cg{FS+OhisS0;_roNn(x;^EsXnQ% zuCB(Kl6AcNeL};l3KErzOLp6N9Pbd8JqW3LMkr`W!audIcErbKn%Xw29)_~ugjpC7 z_MO5wx7}E-4=N^kQrh2S;{wGu&9&t8zTW2cl(F0LcOT``W;G1S`X1jie$VbmqaXqz zEEd4cNN?d%Z~ZI-MZ~vPoq`pN_1Sej>+$uLHv{LKH+|GFley@Gc8<^59f3kf31GF| z%K`6KQig{OSe^EbUL}Ed{zk?^P<(F|2n(f4@lU!wsF|He59l=?IxzYy)zny6c48a8qREkWyT4rI4l*AQmg*12dEHT`-nLVW0H}{kR3}GN;t#X z-|&M`|0Q?WMSwKZg;p6{fP|+mjdvYKWr*f$hh6z@!z0h-j%VMM>`&~Z!&DQ>^P-~& zOAQx=1ZCdJ&u2)cu*Z1{wx{n?9MZ=3Yl3y#vD%##z;|zUO!0sYp9f#6VQ#KohFq(Z zHc*@+_azR6*9Oyel7Y3f^2tH<4?_c#Yl;sCz+xBFHIz`NkXp{jWMlD@D8^)FF*9%D z{p7wM3*pRTHrn6g$L`LFeU54(W?oM{->4$r*_9(LhIV7DIwTQ`lHS>M z9$+_XtV&y=Kl=v;QbHs2~XQItXi%?5_lBRo3JN*?sFQyiH9|cncCQ zzTW(UM(-kLqZ$rBccAp!uQlPD9A+39jsFo_V8)4yE^S(=;(*A3vxlYV25ms)$p~@k45XfukZTI^?ja2r9oHAjii<^xMUgZ;O?$;T9mJVwrFS{wgpvZ3xK5D_A* zLy?`K869n8M^)`dT$Z9DAx&&;o4^!`czE0tj8Z0bR&HQgY-aWc;qaYqW(l&d#q!|y zkE_8{$P{BxLp(F*gM3_uT~=J36>DY)wVUkRKUhgR247!)@|dr5=GDlHlJ~*Ky_Af` z5UZM94bsmXt?;4J;#`dJ6NaUxww>)SDPusLJLV%_K4fsXl7+7nLQahm+HOd Date: Tue, 10 Sep 2024 11:32:02 -0700 Subject: [PATCH 07/14] updated styling of pricing page --- .../templates/pricing/EnterpriseCard.tsx | 15 ++- .../templates/pricing/FeaturedItem.tsx | 2 +- .../components/templates/pricing/FreeCard.tsx | 10 +- .../pricing/PricingComparisonTable.tsx | 4 +- .../pricing/ProductComparisonTable.tsx | 5 +- .../templates/pricing/ScaleCard.tsx | 19 +-- bifrost/app/pricing/page.tsx | 108 +++++++++--------- 7 files changed, 86 insertions(+), 77 deletions(-) diff --git a/bifrost/app/components/templates/pricing/EnterpriseCard.tsx b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx index 69a27d3cd6..cebe1b6d99 100644 --- a/bifrost/app/components/templates/pricing/EnterpriseCard.tsx +++ b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx @@ -9,13 +9,16 @@ const EnterpriseCard: React.FC = () => {
-
+
Enterprise
-

Contact us

-

- Everything to kickstart your AI project. +

Contact us

+

+ For companies looking to scale. +

+

+ Everything in Team, plus:

@@ -30,8 +33,8 @@ const EnterpriseCard: React.FC = () => { /> - diff --git a/bifrost/app/components/templates/pricing/FeaturedItem.tsx b/bifrost/app/components/templates/pricing/FeaturedItem.tsx index eb55961a4a..c072db8319 100644 --- a/bifrost/app/components/templates/pricing/FeaturedItem.tsx +++ b/bifrost/app/components/templates/pricing/FeaturedItem.tsx @@ -7,7 +7,7 @@ export const FeatureItem: React.FC<{ title: string; description: string }> = ({ description, }) => ( - +

{title}

{description}

diff --git a/bifrost/app/components/templates/pricing/FreeCard.tsx b/bifrost/app/components/templates/pricing/FreeCard.tsx index 468c0f15ef..7cefdbc81f 100644 --- a/bifrost/app/components/templates/pricing/FreeCard.tsx +++ b/bifrost/app/components/templates/pricing/FreeCard.tsx @@ -9,17 +9,17 @@ const FreeCard: React.FC = () => { -
+
Developer
-

Free

-

+

Free

+

Everything to kickstart your AI project.

-
+ { description="No credit card required." /> - diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx index c9b02c152d..42154b0f8c 100644 --- a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx @@ -107,9 +107,7 @@ export default function PricingComparisonTable() { return (
-

- Compare plans -

+

Compare plans

-

Compare to similar products

+
+

Compare to similar products

+
{
-

Recommended

-

- for production AI applications +

Recommended

+

+ for production AI apps

@@ -21,22 +21,23 @@ const ScaleCard: React.FC = () => { Team
- - + + $40 - /mo - $50/mo -

- Everything to kickstart your AI project. +

+ All features for the entire team. +

+

+ Everything in Developer, plus:

diff --git a/bifrost/app/pricing/page.tsx b/bifrost/app/pricing/page.tsx index 1a67111927..49c5625b43 100644 --- a/bifrost/app/pricing/page.tsx +++ b/bifrost/app/pricing/page.tsx @@ -57,14 +57,15 @@ export default function Example() { {" "} that scales with your business when you need it.

-
+ {/*
Get a demo -
+
*/} +
@@ -166,7 +167,7 @@ export default function Example() {
-
+ Available
discounts @@ -231,57 +232,62 @@ export default function Example() { -
-

- Frequently asked questions -

- - - - Which Helicone plan is right for me? - - - Yes. It's right for you. - - +
+
+

+ Frequently
+ asked
+ questions

+
+
+ + + + Which Helicone plan is right for me? + + + Yes. It's right for you. + + - - - What are the limits for each plan? - - - For the Developer plan, you have access to 10k free requests - and dashboard analytics. For the Team plan, you have access to - all features, such as Playground, Prompts, Exports, Evals and - more. For each feature, you will pay as you go. - - + + + What are the limits for each plan? + + + For the Developer plan, you have access to 10k free requests + and dashboard analytics. For the Team plan, you have access to + all features, such as Playground, Prompts, Exports, Evals and + more. For each feature, you will pay as you go. + + - - - I went over my limits. What can I do? - - - You can switch to the Team plan. If you are already on the - Team plan, you will be automatically charged for your usage. - - + + + I went over my limits. What can I do? + + + You can switch to the Team plan. If you are already on the + Team plan, you will be automatically charged for your usage. + + - - - Am I eligible for any discounts? - - - If you are a startup under 2 years old, a non-profit, an - open-source company or a student, you may be eligible for - discounts.{" "} - - Apply here - - . - - - + + + Am I eligible for any discounts? + + + If you are a startup under 2 years old, a non-profit, an + open-source company or a student, you may be eligible for + discounts.{" "} + + Apply here + + . + + + +
From 32c5aa6978bb8a4b29156409a7e39c1e90dbcbd3 Mon Sep 17 00:00:00 2001 From: LinaLam Date: Tue, 10 Sep 2024 12:02:42 -0700 Subject: [PATCH 08/14] minor ui improvement --- .../pricing/PricingComparisonTable.tsx | 12 +++---- .../pricing/ProductComparisonTable.tsx | 32 +++++++++---------- bifrost/app/pricing/page.tsx | 6 ++-- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx index 42154b0f8c..2593c86612 100644 --- a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx @@ -79,9 +79,9 @@ const FeatureRow: React.FC = ({ )} > {isAvailable ? ( - + ) : ( - + )} {amount && (
@@ -206,12 +206,12 @@ export default function PricingComparisonTable() { {isAnnual ? "$50/mo" : ""} - + - $ - {isAnnual ? "40" : "50"} + $ + {isAnnual ? "40" : "50"} - /mo + /mo diff --git a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx index d33f528b76..ce6b4bba16 100644 --- a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx @@ -11,15 +11,15 @@ const products = [ ]; const featureMatrix = [ - { name: "Built for Scale", support: [false, false, false, false, true] }, + { name: "Built for scale", support: [false, false, false, false, true] }, { name: "1 line integration", support: [false, false, false, false, true] }, - { name: "Flexible Pricing", support: [false, false, false, false, true] }, - { name: "Open-source", support: [false, false, false, true, true] }, - { name: "Prompts", support: [false, false, false, false, true] }, - { name: "Evaluation", support: [false, true, false, false, true] }, - { name: "Tracing", support: [false, false, false, false, true] }, - { name: "Use tracking", support: [false, false, false, false, true] }, - { name: "Exports", support: [false, false, false, false, true] }, + { name: "Flexible pricing", support: [false, false, false, true, true] }, + { name: "Open-source", support: [false, true, false, true, true] }, + { name: "Prompts", support: [true, true, true, true, true] }, + { name: "Evaluation", support: [true, true, false, false, true] }, + { name: "Tracing", support: [true, true, true, true, true] }, + { name: "Use tracking", support: [true, false, true, true, true] }, + { name: "Exports", support: [true, true, true, true, true] }, ]; export default function ProductComparisonTable() { @@ -53,19 +53,19 @@ export default function ProductComparisonTable() { ref={overlayRef} className="absolute top-0 right-0 h-full rounded-r-lg border-[#0CA5EA] border-2" >
-
{product.name} {product.name} @@ -49,17 +75,18 @@ export default function ProductComparisonTable() { {featureMatrix.map((feature, index) => (
{feature.name} + {feature.name} + {supported ? ( diff --git a/bifrost/app/pricing/page.tsx b/bifrost/app/pricing/page.tsx index 9dc1ba0b82..1a67111927 100644 --- a/bifrost/app/pricing/page.tsx +++ b/bifrost/app/pricing/page.tsx @@ -18,7 +18,13 @@ import ProductComparisonTable from "../components/templates/pricing/ProductCompa import { Col } from "@/components/common/col"; import { Row } from "@/components/common/row"; import { Button } from "@/components/ui/button"; -import { XMarkIcon } from "@heroicons/react/24/outline"; +import { BookOpenIcon, XMarkIcon } from "@heroicons/react/24/outline"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion"; export default function Example() { return ( @@ -68,7 +74,14 @@ export default function Example() {
+
- - + + {products.map((product) => ( @@ -77,17 +77,17 @@ export default function ProductComparisonTable() { - {feature.support.map((supported, i) => ( Available
@@ -232,7 +232,7 @@ export default function Example() { -
+

Frequently
@@ -294,7 +294,7 @@ export default function Example() {
-

+

Understand your AI performance bottleneck From cbef495a0428dc51a7f1345b58c0cd6b921394d1 Mon Sep 17 00:00:00 2001 From: Kavin Valli Date: Mon, 16 Sep 2024 17:43:22 -0700 Subject: [PATCH 09/14] pricing page changes --- .../templates/pricing/AddOnsTable.tsx | 84 +++++ .../templates/pricing/EnterpriseCard.tsx | 29 +- .../templates/pricing/FeaturedItem.tsx | 16 +- .../components/templates/pricing/FreeCard.tsx | 15 +- .../templates/pricing/PlansTable.tsx | 90 ++++++ .../pricing/PricingComparisonTable.tsx | 304 ++++++++---------- .../pricing/PricingComparisonTableV2.tsx | 144 +++++++++ .../pricing/ProductComparisonTable.tsx | 59 ++-- .../templates/pricing/ScaleCard.tsx | 60 ++-- bifrost/app/pricing/page.tsx | 267 +++++++-------- .../templates/pricing/ScaleCard.tsx | 4 +- bifrost/tailwind.config.ts | 156 ++++----- 12 files changed, 749 insertions(+), 479 deletions(-) create mode 100644 bifrost/app/components/templates/pricing/AddOnsTable.tsx create mode 100644 bifrost/app/components/templates/pricing/PlansTable.tsx create mode 100644 bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx diff --git a/bifrost/app/components/templates/pricing/AddOnsTable.tsx b/bifrost/app/components/templates/pricing/AddOnsTable.tsx new file mode 100644 index 0000000000..43c0c72da2 --- /dev/null +++ b/bifrost/app/components/templates/pricing/AddOnsTable.tsx @@ -0,0 +1,84 @@ +import { Col } from "@/components/common/col"; +import PlansTable, { FeatureRowProps } from "./PlansTable"; +import { Row } from "@/components/common/row"; +import { XMarkIcon } from "@heroicons/react/24/outline"; + +const rows: FeatureRowProps[] = [ + { + title: "Prompts + Experiments", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: ( + <> + +

+ Upgrade to Pro to enable Prompts + Experiments. +

+ + ), + pro: ( + <> + +

$30

+

/mo

+
+

+ Unlimited prompts and versions. +

+ + ), + enterprise: ( + <> +

Included

+

+ Unlimited prompts and versions. +

+ + ), + }, + { + title: "Alerts (Slack + Email)", + description: <>Include 10,000 free requests every month!, + free: ( + <> + +

+ Upgrade to Pro to enable Alerts. +

+ + ), + pro: ( + <> + +

$15

+

/mo

+
+

+ Unlimited alerts. +

+ + ), + enterprise: ( + <> +

Included

+

+ Unlimited alerts. +

+ + ), + }, +]; + +export default function AddOnsTable() { + return ( +
+

+

Add-ons

+

+ Specialized features are now available as add-ons, so you never pay + what you don’t need. +

+ + + + ); +} diff --git a/bifrost/app/components/templates/pricing/EnterpriseCard.tsx b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx index cebe1b6d99..ceaace7bbf 100644 --- a/bifrost/app/components/templates/pricing/EnterpriseCard.tsx +++ b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx @@ -6,34 +6,29 @@ import { FeatureItem } from "./FeaturedItem"; const EnterpriseCard: React.FC = () => { return ( - +
-
+
Enterprise
-

Contact us

-

- For companies looking to scale. +

Contact us

+

+ For companies{" "} + looking to scale.

-

- Everything in Team, plus: +

+ Everything in Pro, plus:

- - - + + + - diff --git a/bifrost/app/components/templates/pricing/FeaturedItem.tsx b/bifrost/app/components/templates/pricing/FeaturedItem.tsx index c072db8319..979de2aab9 100644 --- a/bifrost/app/components/templates/pricing/FeaturedItem.tsx +++ b/bifrost/app/components/templates/pricing/FeaturedItem.tsx @@ -2,15 +2,19 @@ import { Col } from "@/components/common/col"; import { Row } from "@/components/common/row"; import { CheckIcon } from "@heroicons/react/24/outline"; -export const FeatureItem: React.FC<{ title: string; description: string }> = ({ - title, - description, -}) => ( +export const FeatureItem: React.FC<{ + title: string; + description?: string | React.ReactNode; +}> = ({ title, description }) => ( -

{title}

-

{description}

+

+ {title} +

+ {description && ( +

{description}

+ )} ); diff --git a/bifrost/app/components/templates/pricing/FreeCard.tsx b/bifrost/app/components/templates/pricing/FreeCard.tsx index 7cefdbc81f..10722703ee 100644 --- a/bifrost/app/components/templates/pricing/FreeCard.tsx +++ b/bifrost/app/components/templates/pricing/FreeCard.tsx @@ -6,16 +6,17 @@ import { FeatureItem } from "./FeaturedItem"; const FreeCard: React.FC = () => { return ( - +
-
- Developer +
+ Free

Free

-

- Everything to kickstart your AI project. +

+ Everything to{" "} + kickstart your AI project.

@@ -33,8 +34,8 @@ const FreeCard: React.FC = () => { description="No credit card required." /> - diff --git a/bifrost/app/components/templates/pricing/PlansTable.tsx b/bifrost/app/components/templates/pricing/PlansTable.tsx new file mode 100644 index 0000000000..af3c73cea6 --- /dev/null +++ b/bifrost/app/components/templates/pricing/PlansTable.tsx @@ -0,0 +1,90 @@ +import { Col } from "@/components/common/col"; +import { Card } from "@/components/ui/card"; +import { clsx } from "@/utils/clsx"; + +export interface FeatureRowProps { + title: string; + description: string | React.ReactNode; + free: React.ReactNode; + pro: React.ReactNode; + enterprise: React.ReactNode; +} + +const FeatureRow: React.FC = ({ + title, + description, + free, + pro, + enterprise, +}) => ( + <> +
+ +

+ {title} +

+ {title === "Requests" ? ( // doing this check to avoid hydration errors (div inside p) + description + ) : ( +

{description}

+ )} + + +
+ {free} +
+
+ {pro} +
+
+ {enterprise} +
+ +); + +export default function PlansTable({ + rows, + isMain = false, +}: { + rows: FeatureRowProps[]; + isMain?: boolean; +}) { + return ( +
+
+
+
+
+
+ Free +
+
+ Pro + {isMain && ( + +

+ Recommended +

+
+ )} +
+
+ Enterprise +
+ {rows.map((row) => ( + + ))} +
+
+
+
+ ); +} diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx index 2593c86612..02bca7e236 100644 --- a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx @@ -9,7 +9,6 @@ import { XMarkIcon, } from "@heroicons/react/20/solid"; import { LockClosedIcon, LockOpenIcon } from "@heroicons/react/24/outline"; -import { useState } from "react"; interface FeatureRowProps { title: string; @@ -45,7 +44,7 @@ const FeatureRow: React.FC = ({
full access @@ -65,9 +64,9 @@ const FeatureRow: React.FC = ({ ))} -

{description}

+

{description}

- +
How we calculate this
@@ -84,7 +83,7 @@ const FeatureRow: React.FC = ({ )} {amount && ( -
+

{amount} {unit}

@@ -101,176 +100,149 @@ const FeatureRow: React.FC = ({ ); export default function PricingComparisonTable() { - const [isAnnual, setIsAnnual] = useState(true); - - const [selectedPlan, setSelectedPlan] = useState("developer"); - return (

Compare plans

- - - - - Developer - Team - - {selectedPlan === "team" ? ( -
- Monthly - +
+
+ +

Developer plan

+
Free
+
+
+ + + + + + - Annual - (Save $120)
- ) : null} - - -
-
-
- -

Developer plan

-
Free
+ + + +
+
+
+ +

Team plan

+ + + "$50/mo" -
- - - - - - -
- - - - - -
-
-
- -

Team plan

- - - {isAnnual ? "$50/mo" : ""} - - - - $ - {isAnnual ? "40" : "50"} - - /mo - + + + + $ + + {"50"} + + /mo + -
- - - - - - -
- +
+
+
+ + + + + +
- - - + + + ); } diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx new file mode 100644 index 0000000000..27d8b44d9f --- /dev/null +++ b/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx @@ -0,0 +1,144 @@ +import { Row } from "@/components/common/row"; +import { CheckIcon, XMarkIcon } from "@heroicons/react/20/solid"; +import { ChevronDownIcon } from "@radix-ui/react-icons"; +import Link from "next/link"; +import PlansTable, { FeatureRowProps } from "./PlansTable"; + +const rows: FeatureRowProps[] = [ + { + title: "Dashboard", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, + { + title: "Requests", + description: ( + <> +

+ Include 10,000 free requests every month! +

+ +
How we calculate this
+ +
+ + ), + free: ( + <> + +

10k

+

/mo

+
+

+ For more requests, upgrade to Pro. +

+ + ), + pro: ( + <> + +

100k

+

/mo

+
+

+ Starting at $0.32/1k requests after. +

+ + ), + enterprise: ( + <> +

Unlimited

+

+ At bulk discounted rate. +

+ + ), + }, + { + title: "Log retention", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free:

1 month

, + pro:

3 months

, + enterprise:

Forever

, + }, + { + title: "Playground", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, + { + title: "Cache", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, + { + title: "Rate limits", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, + { + title: "Sessions", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, + { + title: "User tracking", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, + { + title: "Datasets", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, + { + title: "API access", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: ( + +

60 calls

+

/min

+
+ ), + enterprise: ( + +

1k calls

+

/min

+
+ ), + }, + { + title: "SOC-2 Type II Compliance", + description: "Visualize your LLM analytics, and watch your AI app improve.", + free: , + pro: , + enterprise: , + }, +]; + +export default function PricingComparisonTableV2() { + return ( +
+

Compare plans

+ +
+ ); +} diff --git a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx index ce6b4bba16..7f776fb5de 100644 --- a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx @@ -26,41 +26,24 @@ export default function ProductComparisonTable() { const tableRef = useRef(null); const overlayRef = useRef(null); - useEffect(() => { - const updateOverlayWidth = () => { - if (tableRef.current && overlayRef.current) { - const lastColumn = tableRef.current.querySelector( - "tr:first-child th:last-child" - ); - if (lastColumn) { - overlayRef.current.style.width = `${lastColumn.clientWidth}px`; - } - } - }; - - updateOverlayWidth(); - window.addEventListener("resize", updateOverlayWidth); - - return () => window.removeEventListener("resize", updateOverlayWidth); - }, []); - return (
-

Compare to similar products

+

+ Compare to similar products +

-
-
-
{product.logo} {product.name}
+ {feature.name} {supported ? ( diff --git a/bifrost/app/pricing/page.tsx b/bifrost/app/pricing/page.tsx index 49c5625b43..44676b5839 100644 --- a/bifrost/app/pricing/page.tsx +++ b/bifrost/app/pricing/page.tsx @@ -166,7 +166,7 @@ export default function Example() { -
+
- +
+
+ - + {products.map((product) => ( {feature.support.map((supported, i) => ( -

Recommended

-

+ + +

+

Recommended

+

for production AI apps

-
- Team +
+ Pro
- - - - $40 - - /mo + + + $20 + /user - - $50/mo + + per month -

- All features for the entire team. +

+ All features{" "} + for the entire team.

-

- Everything in Developer, plus: +

+ Everything in Free, plus:

+ Only pay for what you use after the free limit.{" "} + + See more. + + + } /> - diff --git a/bifrost/app/pricing/page.tsx b/bifrost/app/pricing/page.tsx index 44676b5839..8c80be6792 100644 --- a/bifrost/app/pricing/page.tsx +++ b/bifrost/app/pricing/page.tsx @@ -1,80 +1,71 @@ "use client"; -import { - AcademicCapIcon, - CheckIcon, - CodeBracketIcon, -} from "@heroicons/react/20/solid"; import Image from "next/image"; import Link from "next/link"; -import { HomeModernIcon } from "@heroicons/react/24/solid"; import EnterpriseCard from "../components/templates/pricing/EnterpriseCard"; import FreeCard from "../components/templates/pricing/FreeCard"; -import PricingComparisonTable from "../components/templates/pricing/PricingComparisonTable"; import ScaleCard from "../components/templates/pricing/ScaleCard"; import ProductComparisonTable from "../components/templates/pricing/ProductComparisonTable"; import { Col } from "@/components/common/col"; import { Row } from "@/components/common/row"; import { Button } from "@/components/ui/button"; -import { BookOpenIcon, XMarkIcon } from "@heroicons/react/24/outline"; +import { BookOpenIcon } from "@heroicons/react/24/outline"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion"; +import PricingComparisonTableV2 from "../components/templates/pricing/PricingComparisonTableV2"; +import AddOnsTable from "../components/templates/pricing/AddOnsTable"; export default function Example() { return ( -
-
+
+
- - - - - - -

- Pricing that's simple -

-

- Only pay for what you use. We offer{" "} - - usage-based pricing - {" "} - that scales with your business when you need it. -

- {/*
- - Get a demo - -
*/} +
+ + + + + + +

+ Find a plan that accelerates your business +

+

+ Pricing that scales with you. Only pay for what you use. +

+ -
+
-
-
+
+
- + +

+ 386 hours saved by using cached responses. +

-

- 386 hours saved by using cached responses. -

- - Developer + + Free -
+
- + +

+ 2 days saved combing through requests. +

-

- 2 days saved combing through requests. -

- - Scale - -
+
- + +

+ Critical bug detected, saved agent runtime by 30%. +

- {" "}
-

- Critical bug detected, saved agent runtime by 30%. -

- + Enterprise - - -
-
- Also included -
-
- {[ - "Playground", - "SOC-2", - "Cache stats", - "3 month log retention", - "Rate limit stats", - "10 API calls per minute", - ].map((item) => ( -
- - {item} -
- ))} -
-
+ + -
+
- + Available
discounts
- - - +
-
-
-

+
+
+

Startups

-

+

50% - + {" "} off first year

-

+

For most startups under 2 years old.

-
-

+
+

Non-profits

-

Discounts

-

+

+ Discounts +

+

Depending on your org size.

-
-

+
+

Open-source companies

-

- $5,000 - +

+ $100 + {" "} credit @@ -219,12 +187,14 @@ export default function Example() { For the first year.

-
-

+
+

Students

-

Free

-

+

+ Free +

+

For most students and educators.

@@ -232,17 +202,18 @@ export default function Example() {

-
-
-

+
+
+

Frequently
asked
- questions

+ questions +

-
+
- + Which Helicone plan is right for me? @@ -251,19 +222,19 @@ export default function Example() { - + What are the limits for each plan? For the Developer plan, you have access to 10k free requests - and dashboard analytics. For the Team plan, you have access to - all features, such as Playground, Prompts, Exports, Evals and - more. For each feature, you will pay as you go. + and dashboard analytics. For the Team plan, you have access + to all features, such as Playground, Prompts, Exports, Evals + and more. For each feature, you will pay as you go. - + I went over my limits. What can I do? @@ -273,14 +244,17 @@ export default function Example() { - + Am I eligible for any discounts? If you are a startup under 2 years old, a non-profit, an open-source company or a student, you may be eligible for discounts.{" "} - + Apply here . @@ -292,11 +266,11 @@ export default function Example() {
-
-
-

+
+
+

Understand your AI - + performance bottleneck with Helicone. @@ -304,7 +278,7 @@ export default function Example() {
- @@ -313,23 +287,24 @@ export default function Example() {

-

+

Helicone or LangSmith?

-

+

More provider flexibility, cost-effective and transparent (open-source).

- - - + +
diff --git a/bifrost/components/templates/pricing/ScaleCard.tsx b/bifrost/components/templates/pricing/ScaleCard.tsx index 71fc86e0c6..a2245f2ac3 100644 --- a/bifrost/components/templates/pricing/ScaleCard.tsx +++ b/bifrost/components/templates/pricing/ScaleCard.tsx @@ -4,7 +4,7 @@ import { Row } from "@/components/common/row"; const ScaleCard = () => { return ( -
+

@@ -14,7 +14,7 @@ const ScaleCard = () => { Scale - + diff --git a/bifrost/tailwind.config.ts b/bifrost/tailwind.config.ts index bb3badc86b..bc834425c9 100644 --- a/bifrost/tailwind.config.ts +++ b/bifrost/tailwind.config.ts @@ -1,88 +1,90 @@ import type { Config } from "tailwindcss"; const config: Config = { - darkMode: ["class"], - content: [ + darkMode: ["class"], + content: [ "./pages/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./app/**/*.{js,ts,jsx,tsx,mdx}", ], theme: { - extend: { - backgroundImage: { - 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', - 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))' - }, - borderRadius: { - lg: 'var(--radius)', - md: 'calc(var(--radius) - 2px)', - sm: 'calc(var(--radius) - 4px)' - }, - colors: { - background: 'hsl(var(--background))', - foreground: 'hsl(var(--foreground))', - card: { - DEFAULT: 'hsl(var(--card))', - foreground: 'hsl(var(--card-foreground))' - }, - popover: { - DEFAULT: 'hsl(var(--popover))', - foreground: 'hsl(var(--popover-foreground))' - }, - primary: { - DEFAULT: 'hsl(var(--primary))', - foreground: 'hsl(var(--primary-foreground))' - }, - secondary: { - DEFAULT: 'hsl(var(--secondary))', - foreground: 'hsl(var(--secondary-foreground))' - }, - muted: { - DEFAULT: 'hsl(var(--muted))', - foreground: 'hsl(var(--muted-foreground))' - }, - accent: { - DEFAULT: 'hsl(var(--accent))', - foreground: 'hsl(var(--accent-foreground))' - }, - destructive: { - DEFAULT: 'hsl(var(--destructive))', - foreground: 'hsl(var(--destructive-foreground))' - }, - border: 'hsl(var(--border))', - input: 'hsl(var(--input))', - ring: 'hsl(var(--ring))', - chart: { - '1': 'hsl(var(--chart-1))', - '2': 'hsl(var(--chart-2))', - '3': 'hsl(var(--chart-3))', - '4': 'hsl(var(--chart-4))', - '5': 'hsl(var(--chart-5))' - } - }, - keyframes: { - 'accordion-down': { - from: { - height: '0' - }, - to: { - height: 'var(--radix-accordion-content-height)' - } - }, - 'accordion-up': { - from: { - height: 'var(--radix-accordion-content-height)' - }, - to: { - height: '0' - } - } - }, - animation: { - 'accordion-down': 'accordion-down 0.2s ease-out', - 'accordion-up': 'accordion-up 0.2s ease-out' - } - } + extend: { + backgroundImage: { + "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", + "gradient-conic": + "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + colors: { + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + brand: "#0CA5EA", + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + chart: { + "1": "hsl(var(--chart-1))", + "2": "hsl(var(--chart-2))", + "3": "hsl(var(--chart-3))", + "4": "hsl(var(--chart-4))", + "5": "hsl(var(--chart-5))", + }, + }, + keyframes: { + "accordion-down": { + from: { + height: "0", + }, + to: { + height: "var(--radix-accordion-content-height)", + }, + }, + "accordion-up": { + from: { + height: "var(--radix-accordion-content-height)", + }, + to: { + height: "0", + }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, }, plugins: [require("@tailwindcss/typography"), require("tailwindcss-animate")], }; From 992509a44eca4b4c22136d1351da3c5fd1071e13 Mon Sep 17 00:00:00 2001 From: Kavin Valli Date: Mon, 16 Sep 2024 17:51:45 -0700 Subject: [PATCH 10/14] fix build issue - eslint --- .../app/components/templates/pricing/PricingComparisonTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx index 02bca7e236..ada896dd49 100644 --- a/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/PricingComparisonTable.tsx @@ -171,7 +171,7 @@ export default function PricingComparisonTable() {

Team plan

- "$50/mo" + $50/mo From 7613a0d8aa46dbdeeb7f7f9eb51217b12cdf8955 Mon Sep 17 00:00:00 2001 From: Kavin Valli Date: Mon, 16 Sep 2024 19:46:40 -0700 Subject: [PATCH 11/14] fix Compare plans heading color --- .../components/templates/pricing/PricingComparisonTableV2.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx index 27d8b44d9f..af8acede85 100644 --- a/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx +++ b/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx @@ -137,7 +137,7 @@ export default function PricingComparisonTableV2() { className="flex flex-col max-w-6xl mx-auto pt-16 pb-2 w-full" id="compare-plans" > -

Compare plans

+

Compare plans

); From 66d0dab2e0aa73c239c3ee049ae35404dc3a6c21 Mon Sep 17 00:00:00 2001 From: Kavin Valli Date: Tue, 17 Sep 2024 09:52:30 -0700 Subject: [PATCH 12/14] more design changes to pricing page --- .../templates/pricing/EnterpriseCard.tsx | 16 ++++++++------ .../templates/pricing/FeaturedItem.tsx | 6 ++++- .../pricing/ProductComparisonTable.tsx | 2 +- .../templates/pricing/ScaleCard.tsx | 22 ++++++++++++------- bifrost/app/pricing/page.tsx | 12 +++++----- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/bifrost/app/components/templates/pricing/EnterpriseCard.tsx b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx index ceaace7bbf..2d35b657a4 100644 --- a/bifrost/app/components/templates/pricing/EnterpriseCard.tsx +++ b/bifrost/app/components/templates/pricing/EnterpriseCard.tsx @@ -14,13 +14,15 @@ const EnterpriseCard: React.FC = () => {

Contact us

-

- For companies{" "} - looking to scale. -

-

- Everything in Pro, plus: -

+
+

+ For companies{" "} + looking to scale. +

+

+ Everything in Pro, plus: +

+
diff --git a/bifrost/app/components/templates/pricing/FeaturedItem.tsx b/bifrost/app/components/templates/pricing/FeaturedItem.tsx index 979de2aab9..dcfd720b34 100644 --- a/bifrost/app/components/templates/pricing/FeaturedItem.tsx +++ b/bifrost/app/components/templates/pricing/FeaturedItem.tsx @@ -7,7 +7,11 @@ export const FeatureItem: React.FC<{ description?: string | React.ReactNode; }> = ({ title, description }) => ( - +

{title} diff --git a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx index 7f776fb5de..eb1ed74efc 100644 --- a/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx +++ b/bifrost/app/components/templates/pricing/ProductComparisonTable.tsx @@ -67,7 +67,7 @@ export default function ProductComparisonTable() {

Recommended

@@ -31,13 +31,15 @@ const ScaleCard: React.FC = () => { -

- All features{" "} - for the entire team. -

-

- Everything in Free, plus: -

+
+

+ All features{" "} + for the entire team. +

+

+ Everything in Free, plus: +

+
@@ -45,6 +47,10 @@ const ScaleCard: React.FC = () => { title="Every feature you need" description="From Playground, Prompts, Exports, Evals and more." /> + {/* */}
@@ -60,7 +60,7 @@ export default function Example() {
-
+

@@ -81,7 +81,7 @@ export default function Example() { -

+

@@ -96,7 +96,7 @@ export default function Example() { /> - + Pro

@@ -300,7 +300,7 @@ export default function Example() { variant="outline" className="text-slate-900 hover:text-brand" > - + Read about key differences From 23b579c82b99aeb0b448e1cb67ceb1f44e8baca1 Mon Sep 17 00:00:00 2001 From: Kavin Valli Date: Tue, 17 Sep 2024 14:09:34 -0700 Subject: [PATCH 13/14] copy changes in new pricing page --- .../templates/pricing/AddOnsTable.tsx | 6 +- .../templates/pricing/PlansTable.tsx | 2 +- .../pricing/PricingComparisonTableV2.tsx | 56 ++++++++++--- .../templates/pricing/RequestLogTableV2.tsx | 80 +++++++++++++++++++ bifrost/app/pricing/page.tsx | 47 +++++++---- bifrost/components/ui/accordion.tsx | 28 +++---- 6 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 bifrost/app/components/templates/pricing/RequestLogTableV2.tsx diff --git a/bifrost/app/components/templates/pricing/AddOnsTable.tsx b/bifrost/app/components/templates/pricing/AddOnsTable.tsx index 43c0c72da2..6ae437cf31 100644 --- a/bifrost/app/components/templates/pricing/AddOnsTable.tsx +++ b/bifrost/app/components/templates/pricing/AddOnsTable.tsx @@ -6,7 +6,8 @@ import { XMarkIcon } from "@heroicons/react/24/outline"; const rows: FeatureRowProps[] = [ { title: "Prompts + Experiments", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: + "Version prompts, create templates, and run experiments to improve LLM outputs.", free: ( <> @@ -37,7 +38,8 @@ const rows: FeatureRowProps[] = [ }, { title: "Alerts (Slack + Email)", - description: <>Include 10,000 free requests every month!, + description: + "Receive real-time alerts to Slack or email and stay on top of critical issues.", free: ( <> diff --git a/bifrost/app/components/templates/pricing/PlansTable.tsx b/bifrost/app/components/templates/pricing/PlansTable.tsx index af3c73cea6..22db456000 100644 --- a/bifrost/app/components/templates/pricing/PlansTable.tsx +++ b/bifrost/app/components/templates/pricing/PlansTable.tsx @@ -31,7 +31,7 @@ const FeatureRow: React.FC = ({

{title}

- {title === "Requests" ? ( // doing this check to avoid hydration errors (div inside p) + {title === "Requests" || title === "API access" ? ( // doing this check to avoid hydration errors (div inside p) description ) : (

{description}

diff --git a/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx b/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx index af8acede85..eff2db8b7b 100644 --- a/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx +++ b/bifrost/app/components/templates/pricing/PricingComparisonTableV2.tsx @@ -3,6 +3,13 @@ import { CheckIcon, XMarkIcon } from "@heroicons/react/20/solid"; import { ChevronDownIcon } from "@radix-ui/react-icons"; import Link from "next/link"; import PlansTable, { FeatureRowProps } from "./PlansTable"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion"; +import RequestLogTableV2 from "./RequestLogTableV2"; const rows: FeatureRowProps[] = [ { @@ -19,10 +26,20 @@ const rows: FeatureRowProps[] = [

Include 10,000 free requests every month!

- + + + + Which Helicone plan is right for me? + + + + + + + {/*
How we calculate this
-
+
*/} ), free: ( @@ -58,56 +75,73 @@ const rows: FeatureRowProps[] = [ }, { title: "Log retention", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: + "Access your logs and analytics so you can track performance over time. ", free:

1 month

, pro:

3 months

, enterprise:

Forever

, }, { title: "Playground", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: + "Tweak prompts and model parameters in Helicone and see how different models responds to the changes.", free: , pro: , enterprise: , }, { title: "Cache", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: + "Reduce latency and save costs on LLM calls by caching responses on the edge. ", free: , pro: , enterprise: , }, { title: "Rate limits", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: "Enforce custom API usage restrictions. ", free: , pro: , enterprise: , }, { title: "Sessions", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: "Group and visualize multi-step LLM interactions. ", free: , pro: , enterprise: , }, { title: "User tracking", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: "Track per-user request volumes, costs, and usage patterns. ", free: , pro: , enterprise: , }, { title: "Datasets", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: + "Organize your requests into datasets for model training or fine-tuning. ", free: , pro: , enterprise: , }, { title: "API access", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: ( + <> +

+ Use our{" "} + + expansive API + + . +

+ + ), free: , pro: ( @@ -124,7 +158,7 @@ const rows: FeatureRowProps[] = [ }, { title: "SOC-2 Type II Compliance", - description: "Visualize your LLM analytics, and watch your AI app improve.", + description: "", free: , pro: , enterprise: , diff --git a/bifrost/app/components/templates/pricing/RequestLogTableV2.tsx b/bifrost/app/components/templates/pricing/RequestLogTableV2.tsx new file mode 100644 index 0000000000..92ea351078 --- /dev/null +++ b/bifrost/app/components/templates/pricing/RequestLogTableV2.tsx @@ -0,0 +1,80 @@ +interface RequestLogTableProps {} + +const BASE_LOG_PRICING: { + lower: number; + upper: number; + rate: number; +}[] = [ + { + lower: 0, + upper: 10_000, + rate: 0, + }, + { + lower: 10_000, + upper: 2_000_000, + rate: 0.000248, + }, + { + lower: 2_000_000, + upper: 15_000_000, + rate: 0.000104, + }, + { + lower: 15_000_000, + upper: 50_000_000, + rate: 0.0000655, + }, + { + lower: 50_000_000, + upper: 100_000_000, + rate: 0.0000364, + }, + { + lower: 100_000_000, + upper: Number.MAX_SAFE_INTEGER, + rate: 0.0000187, + }, +]; + +const MULTIPLIER = 1.3; + +export const HELICONE_LOG_PRICING = BASE_LOG_PRICING.map((pricing) => ({ + ...pricing, + rate: pricing.rate * MULTIPLIER, +})); + +const RequestLogTableV2 = (props: RequestLogTableProps) => { + const {} = props; + + return ( +

- + {feature.name} {supported ? ( diff --git a/bifrost/app/components/templates/pricing/ScaleCard.tsx b/bifrost/app/components/templates/pricing/ScaleCard.tsx index 2eeb36abf9..76df0bb919 100644 --- a/bifrost/app/components/templates/pricing/ScaleCard.tsx +++ b/bifrost/app/components/templates/pricing/ScaleCard.tsx @@ -1,61 +1,67 @@ import { Card } from "@/components/ui/card"; import { Col } from "@/components/common/col"; import { Row } from "@/components/common/row"; -import { CheckIcon } from "@heroicons/react/24/outline"; import { FeatureItem } from "./FeaturedItem"; +import Link from "next/link"; const ScaleCard: React.FC = () => { return ( - - -
{ return ( - +
+ + + + + + + + + {HELICONE_LOG_PRICING.map((pricing, index) => ( + + + + + + ))} + +
Lower BandUpper BandRate per log
+ {new Intl.NumberFormat("us").format(pricing.lower).toString()} + + {pricing.upper === Number.MAX_SAFE_INTEGER + ? "∞" + : new Intl.NumberFormat("us").format(pricing.upper).toString()} + + {pricing.lower === 0 ? "Free" : `$${pricing.rate.toFixed(7)}`} +
+ ); +}; + +export default RequestLogTableV2; diff --git a/bifrost/app/pricing/page.tsx b/bifrost/app/pricing/page.tsx index 0619bd25ff..e5dfe5fbb8 100644 --- a/bifrost/app/pricing/page.tsx +++ b/bifrost/app/pricing/page.tsx @@ -217,7 +217,15 @@ export default function Example() { Which Helicone plan is right for me? - Yes. It's right for you. + If you have a production ready application and you are + looking to improve the quality and looking for an all-in-one + observability platform; choose the Pro plan. Exploring or + building a side project, the Free plan is a great start + before it grows into a larger project. +
+
+ Security, on-prem, or extremely high usage, contact us for + custom Enterprise pricing.
@@ -226,20 +234,29 @@ export default function Example() { What are the limits for each plan? - For the Developer plan, you have access to 10k free requests - and dashboard analytics. For the Team plan, you have access - to all features, such as Playground, Prompts, Exports, Evals - and more. For each feature, you will pay as you go. + For the Pro plan, you have access to 100k requests per month + and all features such as Playground, Cache, Exports, Evals + and more. You will also be able to enable Prompts and Alerts + as add-ons. +
+
+ For the Free plan, you have access to 10k requests per month + for free and dashboard analytics.
- - I went over my limits. What can I do? + + I need more requests on the Free plan. What can I do? - You can switch to the Team plan. If you are already on the - Team plan, you will be automatically charged for your usage. + You can switch to the Pro plan to keep logging after 10k + requests per month. Don’t worry, we are still logging all + your incoming requests, upgrade to Pro to view them.
+
+ If you are already on the Pro plan, you will be + automatically charged for your usage over 100k requests per + month.
@@ -251,12 +268,12 @@ export default function Example() { If you are a startup under 2 years old, a non-profit, an open-source company or a student, you may be eligible for discounts.{" "} - - Apply here - + Contact us + . @@ -267,7 +284,7 @@ export default function Example() {
-
+

Understand your AI @@ -294,7 +311,7 @@ export default function Example() { More provider flexibility, cost-effective and transparent (open-source).

-
+