import { aq, op } from "@uwdata/arquero"

bucket_base = "https://d33173dkfxwa5x.cloudfront.net/www/"

FA = FileAttachment
  import {aq as aq, op as op} from "@uwdata/arquero"
bucket_base = "https://d33173dkfxwa5x.cloudfront.net/www/"
FA = ƒ(name)
stationId = "017043"
statsPlace = Object {isit_answer: "Not really", isit_comment: "It's about average", isit_maximum: 24.5, isit_maximum_dt: "2025-05-01T06:04:00+00:00", isit_minimum: 11.6, isit_minimum_dt: "2025-04-30T21:38:00+00:00", isit_current: 18.05, isit_average: 43.1, isit_name: "Oodnadatta", isit_label: "Oodnadatta", isit_span: "1940 - 2022"}

Is it hot in Oodnadatta right now?

answers = ({
  "Hell no!":   {color: "white",   fill1: "#5287d1", fill2: "#2166ac" },
  "No!":        {color: "white",   fill1: "#a2cdeb", fill2: "#67a9cf" },
  "Nope":       {color: "#333333", fill1: "#f5f8fa", fill2: "#d1e5f0" },
  "Not really": {color: "#333333", fill1: "#f7f7f7", fill2: "#ebebeb" },
  "Yup":        {color: "#333333", fill1: "#fddcca", fill2: "#f7cfb7" },
  "Yeah!":      {color: "white",   fill1: "#de7b49", fill2: "#fc946a" },
  "Hell yeah!": {color: "white",   fill1: "#d1231d", fill2: "#b2182b" }
})

html`
<div class="answer-icon-and-label">
  <span class="answer-icon" style="background-color: ${answers[statsPlace.isit_answer].fill2};">
  </span>
  <span>${statsPlace.isit_answer}</span>
</div>`
answers = Object {Hell no!: Object, No!: Object, Nope: Object, Not really: Object, Yup: Object, Yeah!: Object, Hell yeah!: Object}
Not really
md`${statsPlace.isit_comment}`

It's about average

Here’s how today compares…

datefns = import("https://cdn.skypack.dev/date-fns@3.3.1?min")
tmaxWhen = new Date(Date.parse(statsPlace.isit_maximum_dt || null))
tminWhen = new Date(Date.parse(statsPlace.isit_minimum_dt || null))

tmaxWhenFriendly = isFinite(tmaxWhen) ?
  datefns.formatRelative(tmaxWhen, new Date()) : ""
tminWhenFriendly = isFinite(tminWhen) ?
  datefns.formatRelative(tminWhen, new Date()) : ""

percentRating = statsPlace.isit_average.toFixed(1) + "%"
tmaxWhen = 2025-05-01T06:04Z
tminWhen = 2025-04-30T21:38Z
percentRating = "43.1%"

md`${statsPlace.isit_minimum} °C  `

11.6 °C

md`${tminWhenFriendly}`

md`${statsPlace.isit_maximum} °C  `

24.5 °C

md`${tmaxWhenFriendly}`
html`
<div class="answer-icon-and-label">
  <span class="answer-icon" style="background-color: ${answers[statsPlace.isit_answer].fill2};"></span>
  <span>${statsPlace.isit_current.toFixed(1)} °C</span>
</div>`
18.1 °C
md`Average so far<br>hotter than **${percentRating}** of days for this time of year.`

Average so far
hotter than 43.1% of days for this time of year.

This is the distribution of temperatures typical for this time of year, which we’ve defined as a seven day window either side of today. Just like a bell curve, the plot is higher at more common temperatures and lower at rare temperatures.

… and the rest of the year.

We’ve compared every day this year at Oodnadatta to similar times of year in the past. Red days were hot compared to records; blue days were cold.

heatmapYear = "2025"

Here’s how the rest of Australia looks today so far.

nowHour = (new Date()).getUTCHours()
nowHour >= 10 && nowHour <= 22 ?
  md`Some places may still be cooling off as the night continues.` :
  md`Some places may still be heating up as the day continues.`
nowHour = 8

Some places may still be heating up as the day continues.

statsAllRaw = FA(bucket_base + "stats/stats_all.json").json()

// statsAllRaw is an object with keys by station id, but we
// need an array with an id field. let's move the ids in
statsAll = {
  const statsArray = []
  Object.keys(statsAllRaw).map(k => statsArray.push({...statsAllRaw[k], id: k}))
  const tidiedStats = aq.from(statsArray)
    .derive({
      lat: d => op.parse_float(d.isit_lat),
      lon: d => op.parse_float(d.isit_lon),
      isit_average: d => op.parse_float(d.isit_average),
      // current? (that's the actual avg temp)
      isit_maximum: d => op.parse_float(d.isit_maximum),
      isit_minimum: d => op.parse_float(d.isit_minimum),
      max_when: d => op.parse_date(d.isit_maximum_dt),
      min_when: d => op.parse_date(d.isit_minimum_dt),
      slug: d =>
        op.replace(
          op.replace(
            op.replace(
              op.lower(d.isit_label),
              /\s-\s/g, "-"),
            /\s/g, "-"),
          /[()]/g, "")
    })
    // mark as stale if latest obs are > 24 hours old
    .derive({
      max_stale:
        d => ((d.max_when - op.now()) / (1000 * 60)) / (24 * 60) > 1,
      min_stale:
        d => ((d.min_when - op.now()) / (1000 * 60)) / (24 * 60) > 1
    })
    .objects()
  return(tidiedStats)
}
statsAllRaw = Object {066214: Object, 067105: Object, 048245: Object, 086338: Object, 087031: Object, 070351: Object, 094029: Object, 040842: Object, 015590: Object, 014015: Object, 023000: Object, 009021: Object, 004032: Object, 091311: Object, 076031: Object, 017043: Object, 039128: Object, 039083: Object, 033119: Object, 065070: Object, …}
OJS Runtime Error (line 13, column 17)

op is not defined

currentStats = statsAll.filter(d => (!d.max_stale) && (!d.min_stale))
staleStats = statsAll.filter(d => d.max_stale || d.min_stale)
OJS Runtime Error

op is not defined

OJS Runtime Error

op is not defined

australia = Object {type: "FeatureCollection", name: "australia", crs: Object, features: Array(1)}
answer_domain = Array(7) ["Hell no!", "No!", "Nope", "Not really", "Yup", "Yeah!", "Hell yeah!"]
OJS Runtime Error

op is not defined

// breaking out the pointer layer for readability
// (and in case we decide to customise it later)
tipTemplate = Plot.pointer({
  x: "lon",
  y: "lat",
  channels: {
    place: {
      label: "",
      value: d => d.isit_label,
    },
    label: {
      label: "",
      value: d => d.isit_comment
    },
    separator: {
      label: "",
      value: d => ""
    },
    isit_maximum: {
      label: "Max:",
      value: d => d.isit_maximum + "°C"
    },
    isit_minimum: {
      label: "Min:",
      value: d => d.isit_minimum + "°C"
    }
  },
  fontSize: 20,
  fontFamily: "Roboto Condensed",
  format: {
    x: null,
    y: null
  },
  lineWidth: 20,
  lineHeight: 1.25,
  pointerSize: 0,
  fillOpacity: 0.8,
  strokeOpacity: 0
})