{
  "version": 12,
  "name": "Bitcoin",
  "source": "endpoint",
  "tile": {
    "id": "12478501-60C5-4EB1-A4CC-5FE6379559F6",
    "kind": "graph",
    "label": "BTC",
    "value": {
      "kind": "data",
      "value": "/history"
    },
    "maximum": {
      "kind": "literal",
      "value": "100"
    },
    "itemTitle": "/title",
    "itemSubtitle": "/subtitle",
    "iconPointSize": 10,
    "format": "number",
    "decimals": 0,
    "graphDateField": "/date",
    "graphValueField": "/value",
    "color": "orange",
    "unit": "$",
    "icon": {
      "kind": "literal",
      "value": "chart.line.uptrend.xyaxis"
    }
  },
  "popout": [
    {
      "id": "E4D09BE2-1EFC-4E08-9617-F047A725459F",
      "kind": "metric",
      "label": "BTC/USD \u00b7 Coinbase",
      "value": {
        "kind": "data",
        "value": "/price"
      },
      "maximum": {
        "kind": "literal",
        "value": "100"
      },
      "itemTitle": "/title",
      "itemSubtitle": "/subtitle",
      "iconPointSize": 14,
      "format": "number",
      "decimals": 0,
      "textSize": "large",
      "unit": "USD"
    },
    {
      "id": "0254DDF5-C862-44F3-BA7C-79A735F39F09",
      "kind": "graph",
      "label": "7-day movement \u00b7 USD",
      "value": {
        "kind": "data",
        "value": "/history"
      },
      "maximum": {
        "kind": "literal",
        "value": "100"
      },
      "itemTitle": "/title",
      "itemSubtitle": "/subtitle",
      "iconPointSize": 14,
      "format": "number",
      "decimals": 0,
      "graphDateField": "/date",
      "graphValueField": "/value",
      "color": "orange",
      "unit": "USD"
    },
    {
      "id": "EAC53596-2412-48C2-81FB-F343714F2BBF",
      "kind": "metric",
      "label": "7-day change",
      "value": {
        "kind": "data",
        "value": "/change"
      },
      "maximum": {
        "kind": "literal",
        "value": "100"
      },
      "itemTitle": "/title",
      "itemSubtitle": "/subtitle",
      "iconPointSize": 14,
      "format": "percent",
      "decimals": 2,
      "layout": "horizontal",
      "textSize": "medium"
    }
  ],
  "inputs": [],
  "transform": "function transform(response) {\n  if (!Array.isArray(response) || response.length < 2) throw new Error(\"No hourly Bitcoin history returned.\");\n  const candles = new Map();\n  for (const row of response) {\n    if (!Array.isArray(row) || !Number.isFinite(row[0]) || !Number.isFinite(row[4]) || row[4] <= 0) {\n      throw new Error(\"The feed contains an invalid hourly candle.\");\n    }\n    candles.set(row[0], { time: row[0], price: row[4] });\n  }\n  const sorted = [...candles.values()].sort((a, b) => a.time - b.time);\n  const latest = sorted[sorted.length - 1];\n  const rows = sorted.filter(row => row.time >= latest.time - 7 * 24 * 3600);\n  const first = rows[0];\n  return {\n    price: latest.price,\n    change: (latest.price - first.price) / first.price,\n    history: rows.map(row => ({ date: new Date(row.time * 1000).toISOString(), value: row.price - first.price })),\n    period: \"Hourly candles \u00b7 \" + new Date(first.time * 1000).toISOString().slice(0, 10) + \"\u2013\" + new Date(latest.time * 1000).toISOString().slice(0, 10),\n    observed: new Date(latest.time * 1000).toISOString()\n  };\n}\n"
}
