UNPKG

dpkit

Version:

Fast TypeScript data management framework built on top of the Data Package standard and Polars DataFrames

157 lines 20.6 kB
import { useApp, useInput } from "ink"; import { Box, Text } from "ink"; import pc from "picocolors"; import { useEffect, useState } from "react"; import React from "react"; import { DataGrid } from "./DataGrid.js"; const PAGE_SIZE = 10; export function TableGrid(props) { const { table, schema, borderColor } = props; const { exit } = useApp(); const [col, setCol] = useState(0); const [row, setRow] = useState(0); const [page, setPage] = useState(1); const [order, setOrder] = useState(); const [records, setRecords] = useState(); const handleColChange = async (newCol) => { if (newCol <= 0) return; if (newCol > table.columns.length) return; setCol(newCol); }; const handleRowChange = async (row) => { if (row > PAGE_SIZE) { handlePageChange(page + 1); row = 1; } else if (row < 1) { if (page === 1) return; handlePageChange(page - 1); row = 10; } else if (records && row > records.length) { return; } setRow(row); }; const handleOrderChange = async (order) => { setOrder(order); if (order) { handlePageChange(1, order); } }; const handlePageChange = async (page, newOrder) => { const thisOrder = newOrder ?? order; if (page === 0) return; let ldf = table; if (thisOrder) { const name = table.columns[thisOrder.col - 1]; if (name) { ldf = ldf.sort(name, thisOrder.dir === "desc"); } } const offset = (page - 1) * PAGE_SIZE; const df = await ldf.slice(offset, PAGE_SIZE).collect(); const records = df.toRecords(); if (records.length) { setPage(page); setRecords(records); } }; useEffect(() => { handlePageChange(1); }, [table]); useEffect(() => { if (records && props.quit) exit(); }, [records]); useInput((input, key) => { if (key.escape || input === "q") { exit(); } if (key.pageUp || input === "p") { handlePageChange(page - 1); } if (key.pageDown || input === "n") { handlePageChange(page + 1); } if (key.downArrow || input === "j") { handleRowChange(row + 1); } if (key.upArrow || input === "k") { handleRowChange(row - 1); } if (key.leftArrow || input === "h") { handleColChange(col - 1); } if (key.rightArrow || input === "l") { handleColChange(col + 1); } if (key.return || input === "o") { let nextOrder = { col, dir: "desc" }; if (order?.col === col) { if (order?.dir === "desc") nextOrder = { col, dir: "asc" }; if (order?.dir === "asc") nextOrder = undefined; } handleOrderChange(nextOrder); } }); if (!records) { return null; } return (React.createElement(Box, { flexDirection: "column" }, React.createElement(DataGrid, { records: records, schema: schema, col: col, row: row, order: order, rowHeight: 2, borderColor: borderColor, withTypes: props.withTypes }), React.createElement(Help, { page: page }))); } function Help(props) { const { exit } = useApp(); const [isOpen, setIsOpen] = useState(false); useInput((input, key) => { if (key.escape || input === "q") { exit(); } if (input === "d") { setIsOpen(!isOpen); } }); if (!isOpen) { return (React.createElement(Box, { paddingLeft: 1 }, React.createElement(PageItem, { page: props.page }), React.createElement(Text, null, ", "), React.createElement(HelpItem, { button: "d", description: "to toggle docs" }), React.createElement(Text, null, ", "), React.createElement(HelpItem, { button: "q", description: "to quit" }))); } return (React.createElement(Box, { flexDirection: "column", paddingLeft: 1 }, React.createElement(Text, { bold: true }, "Table Usage"), React.createElement(HelpItem, { button: "p, pgUp", description: "for prev page" }), React.createElement(HelpItem, { button: "n, pgDown", description: "for next page" }), React.createElement(HelpItem, { button: "k, up", description: "for prev row" }), React.createElement(HelpItem, { button: "j, down", description: "for next row" }), React.createElement(HelpItem, { button: "h, left", description: "for prev column" }), React.createElement(HelpItem, { button: "l, right", description: "for next column" }), React.createElement(HelpItem, { button: "o, enter", description: "for order" }), React.createElement(HelpItem, { button: "q, esc", description: "for quit" }))); } // It has weird Text.dimColor bug so we use picocolors here function PageItem(props) { return (React.createElement(Text, null, React.createElement(Text, null, pc.dim("page"), " "), React.createElement(Text, { bold: true }, props.page))); } function HelpItem(props) { return (React.createElement(Text, null, React.createElement(Text, { dimColor: true }, "press"), " ", React.createElement(Text, { bold: true }, props.button), " ", React.createElement(Text, { dimColor: true }, props.description))); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGFibGVHcmlkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vY29tcG9uZW50cy9UYWJsZUdyaWQudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBQ3RDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBQy9CLE9BQU8sRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUMzQixPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUMzQyxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUE7QUFFekIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWdCLENBQUE7QUFFekMsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFBO0FBRXBCLE1BQU0sVUFBVSxTQUFTLENBQUMsS0FNekI7SUFDQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxLQUFLLENBQUE7SUFFNUMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFBO0lBQ3pCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2pDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2pDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ25DLE1BQU0sQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEdBQUcsUUFBUSxFQUFTLENBQUE7SUFDM0MsTUFBTSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsR0FBRyxRQUFRLEVBQWdCLENBQUE7SUFFdEQsTUFBTSxlQUFlLEdBQUcsS0FBSyxFQUFFLE1BQWMsRUFBRSxFQUFF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USxFQUFDLFdBQVcsRUFBQyxVQUFVLEdBQUcsQ0FDL0MsQ0FDUCxDQUFBO0FBQ0gsQ0FBQztBQUVELDJEQUEyRDtBQUMzRCxTQUFTLFFBQVEsQ0FBQyxLQUF1QjtJQUN2QyxPQUFPLENBQ0wsb0JBQUMsSUFBSTtRQUNILG9CQUFDLElBQUk7WUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztnQkFBUztRQUM5QixvQkFBQyxJQUFJLElBQUMsSUFBSSxVQUFFLEtBQUssQ0FBQyxJQUFJLENBQVEsQ0FDekIsQ0FDUixDQUFBO0FBQ0gsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFDLEtBQThDO0lBQzlELE9BQU8sQ0FDTCxvQkFBQyxJQUFJO1FBQ0gsb0JBQUMsSUFBSSxJQUFDLFFBQVEsa0JBQWE7O1FBQUMsb0JBQUMsSUFBSSxJQUFDLElBQUksVUFBRSxLQUFLLENBQUMsTUFBTSxDQUFRO1FBQUMsR0FBRztRQUNoRSxvQkFBQyxJQUFJLElBQUMsUUFBUSxVQUFFLEtBQUssQ0FBQyxXQUFXLENBQVEsQ0FDcEMsQ0FDUixDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRGF0YVJlY29yZCwgU2NoZW1hLCBUYWJsZSB9IGZyb20gXCJAZHBraXQvYWxsXCJcbmltcG9ydCB7IHVzZUFwcCwgdXNlSW5wdXQgfSBmcm9tIFwiaW5rXCJcbmltcG9ydCB7IEJveCwgVGV4dCB9IGZyb20gXCJpbmtcIlxuaW1wb3J0IHBjIGZyb20gXCJwaWNvY29sb3JzXCJcbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlU3RhdGUgfSBmcm9tIFwicmVhY3RcIlxuaW1wb3J0IFJlYWN0IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgdHlwZSB7IE9yZGVyIH0gZnJvbSBcIi4vRGF0YUdyaWQudHN4XCJcbmltcG9ydCB7IERhdGFHcmlkIH0gZnJvbSBcIi4vRGF0YUdyaWQudHN4XCJcblxuY29uc3QgUEFHRV9TSVpFID0gMTBcblxuZXhwb3J0IGZ1bmN0aW9uIFRhYmxlR3JpZChwcm9wczoge1xuICB0YWJsZTogVGFibGVcbiAgc2NoZW1hPzogU2NoZW1hXG4gIGJvcmRlckNvbG9yPzogXCJncmVlblwiIHwgXCJyZWRcIlxuICB3aXRoVHlwZXM/OiBib29sZWFuXG4gIHF1aXQ/OiBib29sZWFuXG59KSB7XG4gIGNvbnN0IHsgdGFibGUsIHNjaGVtYSwgYm9yZGVyQ29sb3IgfSA9IHByb3BzXG5cbiAgY29uc3QgeyBleGl0IH0gPSB1c2VBcHAoKVxuICBjb25zdCBbY29sLCBzZXRDb2xdID0gdXNlU3RhdGUoMClcbiAgY29uc3QgW3Jvdywgc2V0Um93XSA9IHVzZVN0YXRlKDApXG4gIGNvbnN0IFtwYWdlLCBzZXRQYWdlXSA9IHVzZVN0YXRlKDEpXG4gIGNvbnN0IFtvcmRlciwgc2V0T3JkZXJdID0gdXNlU3RhdGU8T3JkZXI+KClcbiAgY29uc3QgW3JlY29yZHMsIHNldFJlY29yZHNdID0gdXNlU3RhdGU8RGF0YVJlY29yZFtdPigpXG5cbiAgY29uc3QgaGFuZGxlQ29sQ2hhbmdlID0gYXN5bmMgKG5ld0NvbDogbnVtYmVyKSA9PiB7XG4gICAgaWYgKG5ld0NvbCA8PSAwKSByZXR1cm5cbiAgICBpZiAobmV3Q29sID4gdGFibGUuY29sdW1ucy5sZW5ndGgpIHJldHVyblxuXG4gICAgc2V0Q29sKG5ld0NvbClcbiAgfVxuXG4gIGNvbnN0IGhhbmRsZVJvd0NoYW5nZSA9IGFzeW5jIChyb3c6IG51bWJlcikgPT4ge1xuICAgIGlmIChyb3cgPiBQQUdFX1NJWkUpIHtcbiAgICAgIGhhbmRsZVBhZ2VDaGFuZ2UocGFnZSArIDEpXG4gICAgICByb3cgPSAxXG4gICAgfSBlbHNlIGlmIChyb3cgPCAxKSB7XG4gICAgICBpZiAocGFnZSA9PT0gMSkgcmV0dXJuXG4gICAgICBoYW5kbGVQYWdlQ2hhbmdlKHBhZ2UgLSAxKVxuICAgICAgcm93ID0gMTBcbiAgICB9IGVsc2UgaWYgKHJlY29yZHMgJiYgcm93ID4gcmVjb3Jkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHNldFJvdyhyb3cpXG4gIH1cblxuICBjb25zdCBoYW5kbGVPcmRlckNoYW5nZSA9IGFzeW5jIChvcmRlcj86IE9yZGVyKSA9PiB7XG4gICAgc2V0T3JkZXIob3JkZXIpXG5cbiAgICBpZiAob3JkZXIpIHtcbiAgICAgIGhhbmRsZVBhZ2VDaGFuZ2UoMSwgb3JkZXIpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgaGFuZGxlUGFnZUNoYW5nZSA9IGFzeW5jIChwYWdlOiBudW1iZXIsIG5ld09yZGVyPzogT3JkZXIpID0+IHtcbiAgICBjb25zdCB0aGlzT3JkZXIgPSBuZXdPcmRlciA/PyBvcmRlclxuICAgIGlmIChwYWdlID09PSAwKSByZXR1cm5cblxuICAgIGxldCBsZGYgPSB0YWJsZVxuICAgIGlmICh0aGlzT3JkZXIpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSB0YWJsZS5jb2x1bW5zW3RoaXNPcmRlci5jb2wgLSAxXVxuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgbGRmID0gbGRmLnNvcnQobmFtZSwgdGhpc09yZGVyLmRpciA9PT0gXCJkZXNjXCIpXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgb2Zmc2V0ID0gKHBhZ2UgLSAxKSAqIFBBR0VfU0laRVxuICAgIGNvbnN0IGRmID0gYXdhaXQgbGRmLnNsaWNlKG9mZnNldCwgUEFHRV9TSVpFKS5jb2xsZWN0KClcbiAgICBjb25zdCByZWNvcmRzID0gZGYudG9SZWNvcmRzKClcblxuICAgIGlmIChyZWNvcmRzLmxlbmd0aCkge1xuICAgICAgc2V0UGFnZShwYWdlKVxuICAgICAgc2V0UmVjb3JkcyhyZWNvcmRzKVxuICAgIH1cbiAgfVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaGFuZGxlUGFnZUNoYW5nZSgxKVxuICB9LCBbdGFibGVdKVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHJlY29yZHMgJiYgcHJvcHMucXVpdCkgZXhpdCgpXG4gIH0sIFtyZWNvcmRzXSlcblxuICB1c2VJbnB1dCgoaW5wdXQsIGtleSkgPT4ge1xuICAgIGlmIChrZXkuZXNjYXBlIHx8IGlucHV0ID09PSBcInFcIikge1xuICAgICAgZXhpdCgpXG4gICAgfVxuXG4gICAgaWYgKGtleS5wYWdlVXAgfHwgaW5wdXQgPT09IFwicFwiKSB7XG4gICAgICBoYW5kbGVQYWdlQ2hhbmdlKHBhZ2UgLSAxKVxuICAgIH1cblxuICAgIGlmIChrZXkucGFnZURvd24gfHwgaW5wdXQgPT09IFwiblwiKSB7XG4gICAgICBoYW5kbGVQYWdlQ2hhbmdlKHBhZ2UgKyAxKVxuICAgIH1cblxuICAgIGlmIChrZXkuZG93bkFycm93IHx8IGlucHV0ID09PSBcImpcIikge1xuICAgICAgaGFuZGxlUm93Q2hhbmdlKHJvdyArIDEpXG4gICAgfVxuXG4gICAgaWYgKGtleS51cEFycm93IHx8IGlucHV0ID09PSBcImtcIikge1xuICAgICAgaGFuZGxlUm93Q2hhbmdlKHJvdyAtIDEpXG4gICAgfVxuXG4gICAgaWYgKGtleS5sZWZ0QXJyb3cgfHwgaW5wdXQgPT09IFwiaFwiKSB7XG4gICAgICBoYW5kbGVDb2xDaGFuZ2UoY29sIC0gMSlcbiAgICB9XG5cbiAgICBpZiAoa2V5LnJpZ2h0QXJyb3cgfHwgaW5wdXQgPT09IFwibFwiKSB7XG4gICAgICBoYW5kbGVDb2xDaGFuZ2UoY29sICsgMSlcbiAgICB9XG5cbiAgICBpZiAoa2V5LnJldHVybiB8fCBpbnB1dCA9PT0gXCJvXCIpIHtcbiAgICAgIGxldCBuZXh0T3JkZXI6IE9yZGVyIHwgdW5kZWZpbmVkID0geyBjb2wsIGRpcjogXCJkZXNjXCIgfVxuXG4gICAgICBpZiAob3JkZXI/LmNvbCA9PT0gY29sKSB7XG4gICAgICAgIGlmIChvcmRlcj8uZGlyID09PSBcImRlc2NcIikgbmV4dE9yZGVyID0geyBjb2wsIGRpcjogXCJhc2NcIiB9XG4gICAgICAgIGlmIChvcmRlcj8uZGlyID09PSBcImFzY1wiKSBuZXh0T3JkZXIgPSB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgaGFuZGxlT3JkZXJDaGFuZ2UobmV4dE9yZGVyKVxuICAgIH1cbiAgfSlcblxuICBpZiAoIXJlY29yZHMpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIj5cbiAgICAgIDxEYXRhR3JpZFxuICAgICAgICByZWNvcmRzPXtyZWNvcmRzfVxuICAgICAgICBzY2hlbWE9e3NjaGVtYX1cbiAgICAgICAgY29sPXtjb2x9XG4gICAgICAgIHJvdz17cm93fVxuICAgICAgICBvcmRlcj17b3JkZXJ9XG4gICAgICAgIHJvd0hlaWdodD17Mn1cbiAgICAgICAgYm9yZGVyQ29sb3I9e2JvcmRlckNvbG9yfVxuICAgICAgICB3aXRoVHlwZXM9e3Byb3BzLndpdGhUeXBlc31cbiAgICAgIC8+XG4gICAgICA8SGVscCBwYWdlPXtwYWdlfSAvPlxuICAgIDwvQm94PlxuICApXG59XG5cbmZ1bmN0aW9uIEhlbHAocHJvcHM6IHsgcGFnZTogbnVtYmVyIH0pIHtcbiAgY29uc3QgeyBleGl0IH0gPSB1c2VBcHAoKVxuICBjb25zdCBbaXNPcGVuLCBzZXRJc09wZW5dID0gdXNlU3RhdGUoZmFsc2UpXG5cbiAgdXNlSW5wdXQoKGlucHV0LCBrZXkpID0+IHtcbiAgICBpZiAoa2V5LmVzY2FwZSB8fCBpbnB1dCA9PT0gXCJxXCIpIHtcbiAgICAgIGV4aXQoKVxuICAgIH1cblxuICAgIGlmIChpbnB1dCA9PT0gXCJkXCIpIHtcbiAgICAgIHNldElzT3BlbighaXNPcGVuKVxuICAgIH1cbiAgfSlcblxuICBpZiAoIWlzT3Blbikge1xuICAgIHJldHVybiAoXG4gICAgICA8Qm94IHBhZGRpbmdMZWZ0PXsxfT5cbiAgICAgICAgPFBhZ2VJdGVtIHBhZ2U9e3Byb3BzLnBhZ2V9IC8+XG4gICAgICAgIDxUZXh0PntcIiwgXCJ9PC9UZXh0PlxuICAgICAgICA8SGVscEl0ZW0gYnV0dG9uPVwiZFwiIGRlc2NyaXB0aW9uPVwidG8gdG9nZ2xlIGRvY3NcIiAvPlxuICAgICAgICA8VGV4dD57XCIsIFwifTwvVGV4dD5cbiAgICAgICAgPEhlbHBJdGVtIGJ1dHRvbj1cInFcIiBkZXNjcmlwdGlvbj1cInRvIHF1aXRcIiAvPlxuICAgICAgPC9Cb3g+XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBwYWRkaW5nTGVmdD17MX0+XG4gICAgICA8VGV4dCBib2xkPlRhYmxlIFVzYWdlPC9UZXh0PlxuICAgICAgPEhlbHBJdGVtIGJ1dHRvbj1cInAsIHBnVXBcIiBkZXNjcmlwdGlvbj1cImZvciBwcmV2IHBhZ2VcIiAvPlxuICAgICAgPEhlbHBJdGVtIGJ1dHRvbj1cIm4sIHBnRG93blwiIGRlc2NyaXB0aW9uPVwiZm9yIG5leHQgcGFnZVwiIC8+XG4gICAgICA8SGVscEl0ZW0gYnV0dG9uPVwiaywgdXBcIiBkZXNjcmlwdGlvbj1cImZvciBwcmV2IHJvd1wiIC8+XG4gICAgICA8SGVscEl0ZW0gYnV0dG9uPVwiaiwgZG93blwiIGRlc2NyaXB0aW9uPVwiZm9yIG5leHQgcm93XCIgLz5cbiAgICAgIDxIZWxwSXRlbSBidXR0b249XCJoLCBsZWZ0XCIgZGVzY3JpcHRpb249XCJmb3IgcHJldiBjb2x1bW5cIiAvPlxuICAgICAgPEhlbHBJdGVtIGJ1dHRvbj1cImwsIHJpZ2h0XCIgZGVzY3JpcHRpb249XCJmb3IgbmV4dCBjb2x1bW5cIiAvPlxuICAgICAgPEhlbHBJdGVtIGJ1dHRvbj1cIm8sIGVudGVyXCIgZGVzY3JpcHRpb249XCJmb3Igb3JkZXJcIiAvPlxuICAgICAgPEhlbHBJdGVtIGJ1dHRvbj1cInEsIGVzY1wiIGRlc2NyaXB0aW9uPVwiZm9yIHF1aXRcIiAvPlxuICAgIDwvQm94PlxuICApXG59XG5cbi8vIEl0IGhhcyB3ZWlyZCBUZXh0LmRpbUNvbG9yIGJ1ZyBzbyB3ZSB1c2UgcGljb2NvbG9ycyBoZXJlXG5mdW5jdGlvbiBQYWdlSXRlbShwcm9wczogeyBwYWdlOiBudW1iZXIgfSkge1xuICByZXR1cm4gKFxuICAgIDxUZXh0PlxuICAgICAgPFRleHQ+e3BjLmRpbShcInBhZ2VcIil9IDwvVGV4dD5cbiAgICAgIDxUZXh0IGJvbGQ+e3Byb3BzLnBhZ2V9PC9UZXh0PlxuICAgIDwvVGV4dD5cbiAgKVxufVxuXG5mdW5jdGlvbiBIZWxwSXRlbShwcm9wczogeyBidXR0b246IHN0cmluZzsgZGVzY3JpcHRpb246IHN0cmluZyB9KSB7XG4gIHJldHVybiAoXG4gICAgPFRleHQ+XG4gICAgICA8VGV4dCBkaW1Db2xvcj5wcmVzczwvVGV4dD4gPFRleHQgYm9sZD57cHJvcHMuYnV0dG9ufTwvVGV4dD57XCIgXCJ9XG4gICAgICA8VGV4dCBkaW1Db2xvcj57cHJvcHMuZGVzY3JpcHRpb259PC9UZXh0PlxuICAgIDwvVGV4dD5cbiAgKVxufVxuIl19