Search

PDF Report

Export

Export charts in highly customized PDF reports.

PDF Report
View live example →

Select a report template and position the chart to get the view you want to export.

Then click Download to generate the sample PDF report.

You can customize the PDF output by passing your own PDFKit document in the doc property.

See also

import React, { useRef, useState } from "react";
import { createRoot } from "react-dom/client";

// Must be after the import of 'regraph/export'
import PDFDocument from "pdfkit/js/pdfkit.standalone";
import { Chart } from "regraph";

import { items, loremArray } from "./data";

import "regraph/export";

const slideIcon = "/img/slide.svg";
const reportIcon = "/img/report.svg";

// margins are specified in points, with 72 points per inch.
const margin = 72 * 0.4;
const title = "Investigative report";
const caption = "Policy 910 has two claims, each with an unusually high number of damage reports";

function report() {
  const doc = new PDFDocument({
    layout: "portrait",
    margin,
  });

  doc.font("Times-Bold").fontSize(30).text(title, { align: "center" });

  doc.font("Times-Italic").fontSize(10).text(caption, margin, 435, { align: "center" });

  doc
    .font("Times-Roman")
    .fontSize(12)
    .text(loremArray[3], margin, 480, { align: "justify", columns: 2 });

  // update pointer to position where chart should be added
  doc.x = margin;
  doc.y = 120;
  return doc;
}

function slide() {
  const doc = new PDFDocument({
    layout: "landscape",
    margin,
  });

  const { width: pageWidth } = doc.page;

  doc.font("Helvetica-Bold").fontSize(30).text(title, { align: "center" });

  // move to starting position of bulletpoints
  doc.x = 500;
  doc.y = 130;

  const bulletWidth = pageWidth - doc.x - margin;

  doc.font("Helvetica").fontSize(16);

  for (let i = 0; i < 4; i++) {
    doc.list([loremArray[4]], { width: bulletWidth });
    doc.moveDown();
  }

  doc
    .font("Helvetica-Oblique")
    .fontSize(14)
    .text(caption, margin + 30, 500, { width: 400, align: "justify" });

  // update pointer to position where chart should be added
  doc.x = margin;
  doc.y = 130;
  return doc;
}

function downloadPdf(url) {
  // Create the link to download the image
  const downloadLink = document.createElement("a");
  downloadLink.download = `ReGraph_export.pdf`;
  downloadLink.href = url;
  downloadLink.click();
  // revoke the url afterwards to free it from browser memory
  URL.revokeObjectURL(url);
}

function PdfReport() {
  const chartRef = useRef(null);

  return (
    <div className="story">
      <ExportControls chartRef={chartRef} />
      <div className="chart-wrapper">
        <Chart ref={chartRef} items={items} />
      </div>
    </div>
  );
}

function ExportControls({ chartRef }) {
  const [documentLayout, setDocumentLayout] = useState("report");
  const [exportEnabled, setExportEnabled] = useState(true);

  const createDocument = () => {
    let doc;
    let fitTo = {};
    if (documentLayout === "slide") {
      doc = slide(PDFDocument);
      fitTo = { width: 450, height: 350 };
    } else {
      doc = report(PDFDocument);
      const chartExportWidth = doc.page.width - (doc.page.margins.left + doc.page.margins.right);
      fitTo = { width: chartExportWidth, height: 300 };
    }
    const options = {
      type: "pdf",
      extents: "view",
      doc,
      fitTo,
    };

    return [doc, options];
  };

  const exportChartAndDownloadDoc = (doc, options) => {
    const docData = [];
    doc.on("data", docData.push.bind(docData));
    doc.on("end", () => {
      downloadPdf(URL.createObjectURL(new Blob(docData, { type: "application/pdf" })));
    });

    setExportEnabled(false);

    if (chartRef.current) {
      chartRef.current
        .export(options)
        .then(() => {
          doc.end();
          setExportEnabled(true);
        })
        .catch((err) => {
          console.error("Regraph Export:", err.message);
          setExportEnabled(true);
        });
    }
  };

  return (
    <div
      className="options overlay"
      style={{ flexBasis: "auto", minWidth: 400, flexWrap: "nowrap" }}
    >
      <div
        style={{
          padding: 6,
          display: "flex",
          inlineSize: "62px",
          overflowWrap: "break-word",
          textAlign: "left",
          cursor: "default",
        }}
      >
        Template:
      </div>
      <div
        className="options__group"
        style={{
          display: "flex",
          flexDirection: "column",
          justifyContent: "center",
          alignItems: "start",
        }}
      >
        <div className="options__group__subgroup">
          <button
            type="button"
            style={{ padding: 3 }}
            className={documentLayout === "report" ? "active" : ""}
            onClick={() => {
              setDocumentLayout("report");
            }}
          >
            <img
              src={reportIcon}
              alt="Report icon"
              height={60}
              width={60}
              style={{ filter: `brightness(${documentLayout === "report" ? 1 : 0})` }}
            />
          </button>
          <button
            type="button"
            style={{ padding: 3 }}
            className={documentLayout === "slide" ? "active" : ""}
            onClick={() => {
              setDocumentLayout("slide");
            }}
          >
            <img
              src={slideIcon}
              alt="Slide icon"
              height={60}
              width={60}
              style={{ filter: `brightness(${documentLayout === "slide" ? 1 : 0})` }}
            />
          </button>
        </div>
      </div>
      <span className="separator" style={{ minHeight: "60px", height: "80%" }} />
      <button
        type="button"
        style={{ margin: "3px 6px" }}
        disabled={exportEnabled}
        onClick={async () => {
          const [doc, options] = createDocument();
          exportChartAndDownloadDoc(doc, options);
        }}
      >
        Download
      </button>
    </div>
  );
}

const FontReadyChart = React.lazy(() =>
  document.fonts.load("24px 'Material Icons'").then(() => ({
    default: PdfReport,
  }))
);

export function Demo() {
  return (
    <React.Suspense fallback="">
      <FontReadyChart />
    </React.Suspense>
  );
}

const root = createRoot(document.getElementById("regraph"));
root.render(<Demo />);
export const items = {
  3: {
    color: "rgba(255,255,255,1)",
    data: { kind: "garage" },
    fontIcon: { color: "#006B5F", fontFamily: "Material Icons", text: "build" },
    border: { color: "rgba(0,107,95,1)" },
    label: [{ text: "Torphy - Ebert", position: "s" }],
  },
  249: {
    color: "rgba(255,255,255,1)",
    data: { kind: "address" },
    fontIcon: { color: "#A42768", fontFamily: "Material Icons", text: "home" },
    border: { color: "rgba(164,39,104,1)" },
    label: [{ text: "0065 Cordia Throughway, Vivienneton", position: "s" }],
  },
  250: {
    color: "rgba(255,255,255,1)",
    data: { kind: "telephone" },
    fontIcon: { color: "#A42768", fontFamily: "Material Icons", text: "phone" },
    border: { color: "rgba(164,39,104,1)" },
    label: [{ text: "055 9497 2435", position: "s" }],
  },
  251: {
    color: "rgba(255,255,255,1)",
    data: { kind: "vehicle" },
    fontIcon: { color: "#7FCB68", fontFamily: "Material Icons", text: "directions_car" },
    border: { color: "rgba(127,203,104,1)" },
    label: [{ text: "QWE09EE", position: "s" }],
  },
  252: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Ellen Larkin", position: "s" }],
  },
  253: {
    color: "rgba(255,255,255,1)",
    data: { kind: "policy" },
    fontIcon: { color: "#1F78B4", fontFamily: "Material Icons", text: "folder_open" },
    border: { color: "rgba(31,120,180,1)" },
    label: [{ text: "Policy 910", position: "s" }],
  },
  290: {
    color: "rgba(255,255,255,1)",
    data: { kind: "address" },
    fontIcon: { color: "#A42768", fontFamily: "Material Icons", text: "home" },
    border: { color: "rgba(164,39,104,1)" },
    label: [{ text: "2253 Desiree Drive, Lake Cadeside", position: "s" }],
  },
  291: {
    color: "rgba(255,255,255,1)",
    data: { kind: "telephone" },
    fontIcon: { color: "#A42768", fontFamily: "Material Icons", text: "phone" },
    border: { color: "rgba(164,39,104,1)" },
    label: [{ text: "0313 652 3599", position: "s" }],
  },
  292: {
    color: "rgba(255,255,255,1)",
    data: { kind: "vehicle" },
    fontIcon: { color: "#7FCB68", fontFamily: "Material Icons", text: "directions_car" },
    border: { color: "rgba(127,203,104,1)" },
    label: [{ text: "ASD984R", position: "s" }],
  },
  293: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Ahmad Lemke", position: "s" }],
  },
  294: {
    color: "rgba(255,255,255,1)",
    data: { kind: "policy" },
    fontIcon: { color: "#1F78B4", fontFamily: "Material Icons", text: "folder_open" },
    border: { color: "rgba(31,120,180,1)" },
    label: [{ text: "Policy 961", position: "s" }],
  },
  437: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "August Fay DVM", position: "s" }],
  },
  441: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Lora Nitzsche", position: "s" }],
  },
  444: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Yesenia Schinner", position: "s" }],
  },
  445: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 129", position: "s" }],
  },
  446: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 294", position: "s" }],
  },
  447: {
    color: "rgba(255,255,255,1)",
    data: { kind: "claim" },
    fontIcon: { color: "#FF2F3F", fontFamily: "Material Icons", text: "receipt" },
    border: { color: "rgba(255,47,63,1)" },
    label: [{ text: "Claim 451", position: "s" }],
  },
  460: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Nya Reilly", position: "s" }],
  },
  464: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Linda Kub", position: "s" }],
  },
  468: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Lori Lueilwitz", position: "s" }],
  },
  469: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 468", position: "s" }],
  },
  470: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 586", position: "s" }],
  },
  471: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 638", position: "s" }],
  },
  472: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 581", position: "s" }],
  },
  473: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 602", position: "s" }],
  },
  474: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 771", position: "s" }],
  },
  475: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 927", position: "s" }],
  },
  476: {
    color: "rgba(255,255,255,1)",
    data: { kind: "claim" },
    fontIcon: { color: "#FF2F3F", fontFamily: "Material Icons", text: "receipt" },
    border: { color: "rgba(255,47,63,1)" },
    label: [{ text: "Claim 503", position: "s" }],
  },
  654: {
    color: "rgba(255,255,255,1)",
    data: { kind: "person" },
    fontIcon: { color: "#A674BA", fontFamily: "Material Icons", text: "person" },
    border: { color: "rgba(166,116,186,1)" },
    label: [{ text: "Marietta Turner Jr.", position: "s" }],
  },
  655: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 712", position: "s" }],
  },
  656: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 708", position: "s" }],
  },
  657: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 233", position: "s" }],
  },
  658: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 912", position: "s" }],
  },
  659: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 500", position: "s" }],
  },
  660: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 120", position: "s" }],
  },
  661: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 855", position: "s" }],
  },
  662: {
    color: "rgba(255,255,255,1)",
    data: { kind: "damage" },
    fontIcon: {
      color: "#FF8615",
      fontFamily: "Material Icons",
      text: "directions_car",
    },
    border: { color: "rgba(255,134,21,1)" },
    label: [{ text: "Damage 280", position: "s" }],
  },
  663: {
    color: "rgba(255,255,255,1)",
    data: { kind: "claim" },
    fontIcon: { color: "#FF2F3F", fontFamily: "Material Icons", text: "receipt" },
    border: { color: "rgba(255,47,63,1)" },
    label: [{ text: "Claim 411", position: "s" }],
  },
  "252-250": { id1: "252", id2: "250", width: 3 },
  "293-291": { id1: "293", id2: "291", width: 3 },
  "252-249": { id1: "252", id2: "249", width: 3 },
  "293-290": { id1: "293", id2: "290", width: 3 },
  "253-252": { id1: "253", id2: "252", width: 3 },
  "294-293": { id1: "294", id2: "293", width: 3 },
  "447-294": { id1: "447", id2: "294", width: 3 },
  "476-253": { id1: "476", id2: "253", width: 3 },
  "663-253": { id1: "663", id2: "253", width: 3 },
  "447-3": { id1: "447", id2: "3", width: 3 },
  "476-3": { id1: "476", id2: "3", width: 3 },
  "663-3": { id1: "663", id2: "3", width: 3 },
  "445-447": { id1: "445", id2: "447", width: 3 },
  "446-447": { id1: "446", id2: "447", width: 3 },
  "469-476": { id1: "469", id2: "476", width: 3 },
  "470-476": { id1: "470", id2: "476", width: 3 },
  "471-476": { id1: "471", id2: "476", width: 3 },
  "472-476": { id1: "472", id2: "476", width: 3 },
  "473-476": { id1: "473", id2: "476", width: 3 },
  "474-476": { id1: "474", id2: "476", width: 3 },
  "475-476": { id1: "475", id2: "476", width: 3 },
  "655-663": { id1: "655", id2: "663", width: 3 },
  "656-663": { id1: "656", id2: "663", width: 3 },
  "657-663": { id1: "657", id2: "663", width: 3 },
  "658-663": { id1: "658", id2: "663", width: 3 },
  "659-663": { id1: "659", id2: "663", width: 3 },
  "660-663": { id1: "660", id2: "663", width: 3 },
  "661-663": { id1: "661", id2: "663", width: 3 },
  "662-663": { id1: "662", id2: "663", width: 3 },
  "447-292": { id1: "447", id2: "292", width: 3 },
  "476-251": { id1: "476", id2: "251", width: 3 },
  "663-251": { id1: "663", id2: "251", width: 3 },
  "447-437": { id1: "447", id2: "437", width: 3 },
  "476-460": { id1: "476", id2: "460", width: 3 },
  "476-464": { id1: "476", id2: "464", width: 3 },
  "663-654": { id1: "663", id2: "654", width: 3 },
  "447-441": { id1: "447", id2: "441", width: 3 },
  "447-444": { id1: "447", id2: "444", width: 3 },
  "476-468": { id1: "476", id2: "468", width: 3 },
  "garage-damages-3-445": {
    id1: "3",
    id2: "445",
    width: 3,
  },
  "garage-damages-3-446": {
    id1: "3",
    id2: "446",
    width: 3,
  },
  "garage-damages-3-469": {
    id1: "3",
    id2: "469",
    width: 3,
  },
  "garage-damages-3-470": {
    id1: "3",
    id2: "470",
    width: 3,
  },
  "garage-damages-3-471": {
    id1: "3",
    id2: "471",
    width: 3,
  },
  "garage-damages-3-472": {
    id1: "3",
    id2: "472",
    width: 3,
  },
  "garage-damages-3-473": {
    id1: "3",
    id2: "473",
    width: 3,
  },
  "garage-damages-3-474": {
    id1: "3",
    id2: "474",
    width: 3,
  },
  "garage-damages-3-475": {
    id1: "3",
    id2: "475",
    width: 3,
  },
  "garage-damages-3-655": {
    id1: "3",
    id2: "655",
    width: 3,
  },
  "garage-damages-3-656": {
    id1: "3",
    id2: "656",
    width: 3,
  },
  "garage-damages-3-657": {
    id1: "3",
    id2: "657",
    width: 3,
  },
  "garage-damages-3-658": {
    id1: "3",
    id2: "658",
    width: 3,
  },
  "garage-damages-3-659": {
    id1: "3",
    id2: "659",
    width: 3,
  },
  "garage-damages-3-660": {
    id1: "3",
    id2: "660",
    width: 3,
  },
  "garage-damages-3-661": {
    id1: "3",
    id2: "661",
    width: 3,
  },
  "garage-damages-3-662": {
    id1: "3",
    id2: "662",
    width: 3,
  },
  "people-252-460": {
    id1: "252",
    id2: "460",
    width: 3,
  },
  "people-252-464": {
    id1: "252",
    id2: "464",
    width: 3,
  },
  "people-252-468": {
    id1: "252",
    id2: "468",
    width: 3,
  },
  "people-252-654": {
    id1: "252",
    id2: "654",
    width: 3,
  },
  "people-293-437": {
    id1: "293",
    id2: "437",
    width: 3,
  },
  "people-293-441": {
    id1: "293",
    id2: "441",
    width: 3,
  },
  "people-293-444": {
    id1: "293",
    id2: "444",
    width: 3,
  },
  "people-437-441": {
    id1: "437",
    id2: "441",
    width: 3,
  },
  "people-437-444": {
    id1: "437",
    id2: "444",
    width: 3,
  },
  "people-441-444": {
    id1: "441",
    id2: "444",
    width: 3,
  },
  "people-460-464": {
    id1: "460",
    id2: "464",
    width: 3,
  },
  "people-460-468": {
    id1: "460",
    id2: "468",
    width: 3,
  },
  "people-464-468": {
    id1: "464",
    id2: "468",
    width: 3,
  },
  "person-garage-3-252": {
    id1: "3",
    id2: "252",
    width: 3,
  },
  "person-garage-3-293": {
    id1: "3",
    id2: "293",
    width: 3,
  },
};

const lorem =
  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";

export const loremArray = [
  lorem,
  `${lorem}\n\n${lorem}`,
  `${lorem}\n\n${lorem}\n\n${lorem}`,
  `${lorem}\n\n${lorem}\n\n${lorem}\n\n${lorem}`,
  lorem.slice(0, 100),
];
<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div id="regraph" style="height: 100vh"></div>
    <script type="module" src="./code.jsx"></script>
  </body>
</html>
/* Import for Google's Material Icons */
@import url("https://fonts.googleapis.com/icon?family=Material+Icons");

Terms of use

These terms do not alter or supersede any existing agreements between you (or your employer) and us.

By accessing or using any Content you agree to be bound by these Terms of Use. Please review these terms carefully before using the website.

The contents of this website, including but not limited to any text, code samples, API references, schemas, interactive tools, and other materials (collectively, the 'Content'), are made available for informational and internal evaluation purposes only. All intellectual property rights in the Content are reserved. No licence is granted to use the Content for any commercial purpose, or to copy, distribute, modify, reverse-engineer, or incorporate any part of the Content into any product or service, without our prior written consent.

This Content is provided “as is” and “as available,” without any representations, warranties, or guarantees of any kind, whether express or implied, including but not limited to implied warranties of merchantability, fitness for a particular purpose, non-infringement, or accuracy. To the fullest extent permitted by applicable law, we expressly exclude and disclaim all implied warranties, conditions, and other terms that might otherwise be implied.

We disclaim all liability for any loss or damage, whether direct, indirect, incidental, consequential, or otherwise, arising from any reliance placed on the Content or from your use of it, to the fullest extent permitted by applicable law. By continuing to access or use the Content, you acknowledge and agree to these terms.