Martin Laptev

Dec

  • Home
  • About
  • CV/Résumé
  • Article List
  • Dec
    • Date
    • Time
    • Snap
    • Span
  • History
    • World War 2
  • Machine Learning
    • Probablity
    • Language Models
  • Software
    • Git
    • Jupyter
    • Observable
    • Positron
    • Quarto
      • Filter
      • Include
      • Script
    • Reveal

On this page

  • Dec measurement system
    • Longitude latitude course
    • Distance speed duration
    • Interactive world map
    • Color wheel compass
    • Hue saturation lightness (hsl)
    • Course color table
    • Red green blue (rgb)
  • Dec time zones
    • Coordinated Universal Time
    • Millenium Year Day
  • Zone equatorial meter (zem)
    • Length area volume
    • Typical seat height
    • Speed of sound
  • Inverse of b (Iob)
    • Beats per milliday (bpm)
    • Frequency period wavelength
  • Ten equal temperament (Xet)
    • Color sound table
    • Octave + note = tone
  • US customary units
    • Unit conversion table
    • Miles per hour (mph)
    • Hexamilliare wineglass keg
    • Body mass index (bmi)
    • Centizem centimeter inch
  • Summary
  • Next
  • Cite
  • View source

Other Formats

  • CommonMark

Dec

Introducing the Dec measurement system, which uses turns instead of months, weeks, hours, minutes, seconds, and degrees.

Author

Martin Laptev

Published

2025+100

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '32px'}}}%%
flowchart LR
   A[Dec]-->B[date]-->C[time]-->D[snap]-->E[span]
   click A "/dec"
   click B "/dec/date"
   click C "/dec/time"
   click D "/dec/snap"
   click E "/dec/span"

Dec measurement system

This part of my website focuses on Dec, a measurement system that I created. All Dec measurements are based on turns. When measuring angles📐, a turn represents a full⭕️circle and equals 2\(\pi\) (\(\underline\tau\)) radians (rad) or 360 degrees (°). Geographic coordinates and compass🧭directions are angles📐and thus can, and should😄, be measured in turns instead of rad or °.

Longitude latitude course

Dec measures longitude in parallels (\(\lambda\)), latitude in meridians (\(\phi\)), and compass🧭directions in windroses (\(\alpha\)). To measure certain kinds of angles📐, Dec uses specific types of turns with distinct names like \(\lambda\), \(\phi\), or \(\alpha\). All turn types can be combined with metric prefixes, like deci, centi, or milli, to create turn submultiples, such as deciturns, centiturns, or milliturns.

The table below provides the current longitude in milliparallels (\(\text m\lambda\)) and latitude in millimeridians (\(\text m\phi\)) of Points 0 and 1 on the map🗺️beneath the table. By default, Point 0 is at 800 \(\text m\lambda\) and 0 \(\text m\phi\), near the Galápagos🏝️archipelago of Ecuador🇪🇨, and Point 1 is at 800 \(\text m\lambda\) and 100 \(\text m\phi\), near the bottom of the Missouri bootheel in the United States🇺🇸.

To move the points, click the map🗺️or edit their coordinates in the table. The toggle✅inputs above the table add layers to the map🗺️: country borders, a rainbow🌈colored🎨grid of Dec graticules, a choropleth of UTC time zones, and solar terminator shading with a yellow🟡dot denoting the point where the Sun☀️is directly overhead: \(\text m\lambda\) and \(\text m\phi\).

Alongside the geographic coordinates of a point, each row of the table contains the course in milliwindroses (\(\text m\alpha\)) we would need to maintain to travel🧳the shortest distance to the other point. The shortest distance is shown as orange🟠dots on the map🗺️. The default courses in \(\text m\alpha\) are 0 (North) from Point 0 to 1 and 500 (South) from Point 1 to 0.

Distance speed duration

Dec measures distance in taurs (c), speed in omegars (v), and time in years (y) and days (d). Each of these four turn types approximates (\(\approx\)) a physical property of the Earth🌍: c = \(\tau r\) \(\approx\) its circumference, y \(\approx\) the duration of its orbit around the Sun☀️, d \(\approx\) the duration of its rotation on its axis, and \(\text c\over\text d\) = v = \(\omega r\) \(\approx\) the speed of its rotation at the Equator.

At a speed of 0.5 v or 500 milliomegars (mv), we could travel🧳the 0.1 c or 100 millitaurs (mc) between the default positions📍of Points 0 and 1 in 0.2 d or 200 millidays (md). The time required to travel🧳between two points is the distance divided by the speed: mc ÷ v = md = c ÷ v = mc ÷ mv = d.

Interactive world map
viewof travelspeed = Inputs.range([0, 1000], {label: "Speed", value: 500, step: 1})
viewof yaw = Inputs.range([0, 1000], {label: "Yaw", value: 500, step: 1})
viewof pitch = Inputs.range([-500, 500], {label: "Pitch", value: 0, step: 1})
viewof roll = Inputs.range([-500, 500], {label: "Roll", value: 0, step: 1})
viewof mapsize = Inputs.range([0, 100], {label: "Size", value: 100, step: 1})
viewof select = Inputs.select(
  projections, {format: x => x.name, value: projections.find(t => t.name === "Equirectangular (plate carrée)")})
viewof bordertoggle = labelToggle(Inputs.toggle, "Border", false, "bordertoggle")
viewof gridtoggle = labelToggle(Inputs.toggle, "Grid", false, "gridtoggle")
viewof utctoggle = labelToggle(Inputs.toggle, "UTC", false, "utctoggle")
viewof suntoggle = labelToggle(Inputs.toggle, "Sun", false, "suntoggle")
rstbtn.node();
table = createTable([
  { Point: 0, Milliparallel: 800, Millimeridian: 0, Milliwindrose: 0 },
  { Point: 1, Milliparallel: 800, Millimeridian: 100, Milliwindrose: 500 },
], { headerEditable: false, appendRows: false })
//   {Point: 0, Milliparallel: `${Math.floor(long2turn(Place_A[0], 3))}`, Millimeridian: `${Math.floor(lati2turn(Place_A[1], 3))}`, Milliwindrose: `${Math.floor(lati2turn(coor2bear(Place_A, Place_B)))}`},
//   {Point: 1, Milliparallel: `${Math.floor(long2turn(Place_B[0], 3))}`, Millimeridian: `${Math.floor(lati2turn(Place_B[1], 3))}`, Milliwindrose: `${Math.floor(lati2turn(coor2bear(Place_B, Place_A)))}`},
// ], {headerEditable: false, appendRows: false})
// https://observablehq.com/@d3/solar-terminator
// https://observablehq.com/@mbostock/time-zones
viewof coordinates = worldMapCoordinates([[turn2long(table.rows[1].cells[1].childNodes[0].innerText), turn2degr(table.rows[1].cells[2].childNodes[0].innerText % 250)], [turn2long(table.rows[2].cells[1].childNodes[0].innerText), turn2degr(table.rows[2].cells[2].childNodes[0].innerText % 250)], projection], [width, height * mapsize / 100])
//viewof coordinates = worldMapCoordinates([
//  [turn2long(table.rows[1].cells[1].childNodes[0].innerText), turn2degr(table.rows[1].cells[2].childNodes[0].innerText % 250)],
//  [turn2long(table.rows[2].cells[1].childNodes[0].innerText), turn2degr(table.rows[2].cells[2].childNodes[0].innerText % 250)],
//  projection], [width, height])
Color wheel compass
preview()
// https://observablehq.com/@maddievision/enneagram
quickRender(326, 326, context => {
  const center = 163
  const ringRadius = 140
  const ringLineWidth = 4
  // Ring
  context.beginPath();
  context.lineWidth = ringLineWidth
  context.strokeStyle = "#ddd"
  context.arc(center, center, ringRadius, 0, 2 * Math.PI);
  context.stroke();
  context.font = "Bold 16px Arial"
  context.textAlign = 'center'
  let octPoints = []
  for (let i = 0; i < 8; i++) {
    const xPhase = Math.sin(i / 8 * 2 * Math.PI)
    const yPhase = Math.cos(i / 8 * 2 * Math.PI)
    const x = center + ringRadius * xPhase
    const y = center - ringRadius * yPhase
    octPoints.push([x, y])
  }
  // Lines
  octConnections.forEach(([a, b], i ) => {
    const [x1, y1] = octPoints[a]
    const [x2, y2] = octPoints[b]
    const lineAngle = Math.atan2(y2 - y1, x2 - x1)
    // Draw just short of the label circumference
    const x2a = x2 - 28 * Math.cos(lineAngle)
    const y2a = y2 - 28 * Math.sin(lineAngle)
    const x1a = x1 + 28 * Math.cos(lineAngle)
    const y1a = y1 + 28 * Math.sin(lineAngle)
    context.lineWidth = ringLineWidth
    context.strokeStyle = "#ddd"
    context.beginPath();
    context.moveTo(x2a, y2a);
    context.lineTo(x1a, y1a);
    context.stroke();
  })
  // Arrow Heads
  octConnections.forEach(([a, b], i ) => {
    const [x1, y1] = octPoints[a]
    const [x2, y2] = octPoints[b]
    const lineAngle = Math.atan2(y2 - y1, x2 - x1)
    const xl = x2 - 88 * Math.cos(lineAngle - (15 / 360) * 2 * Math.PI)
    const yl = y2 - 88 * Math.sin(lineAngle - (15 / 360) * 2 * Math.PI)
    const xr = x2 - 88 * Math.cos(lineAngle + (15 / 360) * 2 * Math.PI)
    const yr = y2 - 88 * Math.sin(lineAngle + (15 / 360) * 2 * Math.PI)
    const x2a = x2 - 22 * Math.cos(lineAngle)
    const y2a = y2 - 22 * Math.sin(lineAngle)
    const x = x2 - 69 * Math.cos(lineAngle)
    const y = y2 - 69 * Math.sin(lineAngle)
    context.fillStyle = hsl8[i]
    context.strokeStyle = window.darkmode ? "#aaa" : "#333";
    context.lineWidth = 1
    context.beginPath();
    context.moveTo(x2a, y2a);
    context.lineTo(xl, yl);
    context.lineTo(xr, yr);
    context.lineTo(x2a, y2a);
    context.fill();
    context.stroke();
    context.fillStyle = yiq(hsl8[i]) > 0.51 ? "#000" : "white"
    context.fillText(["N", "NE", "E", "SE", "S", "SW", "W", "NW"][i], x, y + 6)
  })
  // Labels
  octPoints.forEach(([x, y], i) => {
    context.lineWidth = 1
    context.fillStyle = hsl8[i]
    context.strokeStyle = window.darkmode ? "#aaa" : "#333";
    context.beginPath();
    context.arc(x, y, 22, 0, 2 * Math.PI);
    context.fill();
    context.stroke();
    context.fillStyle = yiq(hsl8[i]) > 0.51 ? "#000" : "white";
    context.fillText(["N", "NE", "E", "SE", "S", "SW", "W", "NW"][i], x, y + 6)
  })
})
// https://observablehq.com/@observablehq/categorical-palette-tool
displayPalette(hsl8, {darkMode: true})
// https://observablehq.com/@maddievision/enneagram
quickRender(326, 326, context => {
  const center = 163
  const ringRadius = 140
  const ringLineWidth = 4
  // Ring
  context.beginPath();
  context.lineWidth = ringLineWidth
  context.strokeStyle = "#ddd"
  context.arc(center, center, ringRadius, 0, 2 * Math.PI);
  context.stroke();
  context.font = "Bold 24px Arial"
  context.textAlign = 'center'
  let decPoints = []
  for (let i = 0; i < 10; i++) {
    const xPhase = Math.sin(i / 10 * 2 * Math.PI)
    const yPhase = Math.cos(i / 10 * 2 * Math.PI)
    const x = center + ringRadius * xPhase
    const y = center - ringRadius * yPhase
    decPoints.push([x, y])
  }
  // Lines
  decConnections.forEach(([a, b], i ) => {
    const [x1, y1] = decPoints[a]
    const [x2, y2] = decPoints[b]
    const lineAngle = Math.atan2(y2 - y1, x2 - x1)
    // Draw just short of the label circumference
    const x2a = x2 - 28 * Math.cos(lineAngle)
    const y2a = y2 - 28 * Math.sin(lineAngle)
    const x1a = x1 + 28 * Math.cos(lineAngle)
    const y1a = y1 + 28 * Math.sin(lineAngle)
    context.lineWidth = ringLineWidth
    context.strokeStyle = "#ddd"
    context.beginPath();
    context.moveTo(x2a, y2a);
    context.lineTo(x1a, y1a);
    context.stroke();
  })
  // Arrow Heads
  decConnections.forEach(([a, b], i ) => {
    const [x1, y1] = decPoints[a]
    const [x2, y2] = decPoints[b]
    const lineAngle = Math.atan2(y2 - y1, x2 - x1)
    const xl = x2 - 79 * Math.cos(lineAngle - (15 / 360) * 2 * Math.PI)
    const yl = y2 - 79 * Math.sin(lineAngle - (15 / 360) * 2 * Math.PI)
    const xr = x2 - 79 * Math.cos(lineAngle + (15 / 360) * 2 * Math.PI)
    const yr = y2 - 79 * Math.sin(lineAngle + (15 / 360) * 2 * Math.PI)
    const x2a = x2 - 22 * Math.cos(lineAngle)
    const y2a = y2 - 22 * Math.sin(lineAngle)
    const x = x2 - 60 * Math.cos(lineAngle)
    const y = y2 - 60 * Math.sin(lineAngle)
    context.fillStyle = hsl10[i]
    context.strokeStyle = window.darkmode ? "#aaa" : "#333";
    context.lineWidth = 1
    context.beginPath();
    context.moveTo(x2a, y2a);
    context.lineTo(xl, yl);
    context.lineTo(xr, yr);
    context.lineTo(x2a, y2a);
    context.fill();
    context.stroke();
    context.fillStyle = yiq(hsl10[i]) > 0.51 ? "#000" : "white"
    context.fillText(i, x, y + 8)
  })
  // Labels
  decPoints.forEach(([x, y], i) => {
    context.lineWidth = 1
    context.fillStyle = hsl10[i]
    context.strokeStyle = window.darkmode ? "#aaa" : "#333";
    context.beginPath();
    context.arc(x, y, 22, 0, 2 * Math.PI);
    context.fill();
    context.stroke();
    context.fillStyle = yiq(hsl10[i]) > 0.51 ? "#000" : "white";
    context.fillText(i, x, y + 8)
  })
})
// https://observablehq.com/@observablehq/categorical-palette-tool
displayPalette(hsl10.slice(0, 10), {darkMode: true})
// https://observablehq.com/@pjedwards/compass-rose-as-legend-with-colors
svg`<svg width="${size}" height="${size}" viewBox="${-size/2} ${-size/2} ${size} ${size}">
  <g transform='rotate(${Math.round(-colorD * .36)})'>
  ${repeat(tick(radius, 5, '#434343'), 5 * 4 * 10)}
  ${repeat(tick(radius, 8), 10 * 4)}
  ${repeat(`<path d="M 0,-${radius+12} l 3,10 l -6,0 z" fill="black" stroke="black" stroke-width="1"/>`, 4, 0)}
  ${repeat(`<path d="M 0,-${radius+12} l 3,10 l -6,0 z" fill="white" stroke="black" stroke-width="1"/>`, 4, 45)}
  <circle r="${radius}" fill="#d3d3d3" stroke="#434343" stroke-width="3" />
  ${repeat(directionMarker(radius+14, 24), 4, 0)}
  ${repeat(directionMarker(radius+12, 24), 4, 45)}
  ${repeat(turnMarker(radius+14, 32), 4, 0)}
  ${repeat(turnMarker(radius+12, 32), 4, 45)}
  ${repeat(pie(radius-margin/2, 2 * Math.PI * (radius-margin/2) / deccolors.length / 2, 1, deccolors), deccolors.length, 360/deccolors.length)}
</svg>
`
// https://observablehq.com/@paavanb/progressive-color-picker
decBar = colorbar({
  colorFn: t => hslToRgb(dec2hue(t) / 1000, colorS / 1000, colorL / 1000),
  onSelect: t => {
    set(viewof colorD, t * 1000)
    onUpdateHSL(dec2hue(t), colorS / 1000, colorL / 1000)
  }
})
Hue saturation lightness (hsl)
// https://observablehq.com/@paavanb/progressive-color-picker
{ const input = Inputs.range([0, 1000], { label: "Hue", value: 0, step: 1 })
  input.value = initialHSL[0]
  input.oninput = (evt) => onUpdateHSL(dec2hue(evt.currentTarget.value / 1000), colorS / 1000, colorL / 1000)
  return Inputs.bind(input, viewof colorD)
}
// https://observablehq.com/@paavanb/progressive-color-picker
{ const input = Inputs.range([0, 1000], { label: "Saturation", value: 1000, step: 1, })
  input.oninput = (evt) => onUpdateHSL(colorD, evt.currentTarget.value / 1000, colorL / 1000)
  return Inputs.bind(input, viewof colorS)
}
// https://observablehq.com/@paavanb/progressive-color-picker
{ const input = Inputs.range([0, 1000], { label: "Lightness", value: 500, step: 1, })
  input.oninput = (evt) => onUpdateHSL(colorD, colorS / 1000, evt.currentTarget.value / 1000)
  return Inputs.bind(input, viewof colorL)
}
Course color table
\(\text m\alpha\)🧭 c°🧭 h°🎨 hex🎨
NE 125 45 44 fb0
E 250 90 68 df0
SE 375 135 96 6f0
S 500 180 180 0ff
SW 625 225 216 06f
W 750 270 264 60f
NW 875 315 292 d0f
N 0 0 0 f00

The color🎨wheel compass🧭above indicates both a hue in milliturns (mt) and a course in \(\text m\alpha\). We can convert the hue to HSL and HSV degrees (h°) and the course to compass🧭degrees (c°): 25 \(\text m\alpha\) = 9 c°. To rotate🔄the color🎨wheel compass🧭, use the “Hue” range🎚️and hue bar inputs beneath it or change the course from Point 0 to 1 on the map🗺️.

Red green blue (rgb)

The table beneath the hue bar compares the current Point 0 to 1 course in its top row with the cardinal and intercardinal directions. Together, the range🎚️inputs underneath the hue bar form a Hue Saturation Lightness (HSL) triplet. Like Red Green Blue (RGB) or hexadecimal (hex) triplets, HSL triplets specify a full-fledged color🎨instead of just a hue.

Bad Pun Alert

Feeling disoriented😵‍💫? Of course you are! Color🎨labels🏷️can help you find your bearings, stay on track, and avoid heading aches🤕. Orange you glad I couldn’t think of a color🎨pun?

Color🎨can provide a general idea of angular📐measure, regardless of the metric prefixes or units we use. Therefore, we can reuse♻️colors🎨across many different contexts. Most often, red designates starting points, like North (0 \(\text m\alpha\)) and Longitude 0 (0 \(\text m\lambda\)), and cyan denotes midpoints, such as South (500 \(\text m\alpha\)) and Longitude 5 (500 \(\text m\lambda\)).

The Equator (0 \(\text m\phi\)) is the major latitude midway between the South (-250 \(\text m\phi\)) and North (250 \(\text m\phi\)) Poles. Unlike the Equator, the Tropics of Cancer♋(65 \(\text m\phi\)) and Capricorn♑️(-65 \(\text m\phi\)) and the Arctic (250 \(\text m\phi\) – 65 \(\text m\phi\) = 185 \(\text m\phi\)) and Antarctic (65 \(\text m\phi\) – 250 \(\text m\phi\) = -185 \(\text m\phi\)) Circles are defined by the axial tilt of the Earth🌏(65 mt).

Dec time zones

Enable the “Grid” toggle✅input to see Latitudes -2 (-200 \(\text m\phi\)), -1 (-100 \(\text m\phi\)), 0 (0 \(\text m\phi\)), 1 (100 \(\text m\phi\)), and 2 (200 \(\text m\phi\)) on the map🗺️above along with the ten major longitudes that divide the Earth🌎into the ten Dec time zones. Notably, Longitude 0 is the major longitude that functions as both the Prime Meridian and International Date Line in Dec.

Like the ten major longitudes that separate them, Dec time zones are numbered 0 to 9. Based on its current deciparallel (d\(\lambda\)) longitude, , Point 0 on the map🗺️above is in Zone . The number assigned to each time zone is its offset from Zone 0 in decidays (dd). To obtain the dd offset at a location, we floor its d\(\lambda\) longitude: ⌊⌋ = .

viewof longitude = Inputs.range([0, 10], {label: "Longitude", value: .5, step: .01})

Each Dec time zone is 1 d\(\lambda\) wide and 0.5 \(\phi\) long. While 1 \(\phi\) is always ~1 c long, the length of a \(\lambda\) varies by latitude. At the Equator, 1 \(\lambda\) is ~1 c long. At the North or South Pole, the length of a \(\lambda\) is zero. The approximate c length of a \(\lambda\) is the cosine of its latitude in \(\phi\), rad, or °, depending on the input requirement of our cosine function: cos() = .

viewof latitude = Inputs.range([-.25, .25], {label: "Latitude", value: 0, step: .001})
viewof costype = Inputs.radio(["turns", "radians", "degrees"], {label: "Cosine input", value: "turns"})
Coordinated Universal Time

UTC time zone offsets range from to dd. The UTC offset provided by your web browser is ÷ 144 = dd. The Dec time zone that corresponds to this UTC offset is Zone . The time in corresponding Dec and UTC time zones can differ by up to 0.5 dd. The difference between your Dec and UTC time is ÷ 144 = dd.

To obtain the time in Zone 0, we can subtract the offset of any time zone from its time. Inversely, we can get the time in any time zone by adding its offset to the Zone 0 time. The dates and times in Zone 0 and UTC+00:00 match exactly. Zone 5 and UTC+12:00 also have matching dates and times, both are precisely one day ahead of UTC-12:00.

To avoid date mismatches with UTC time zones that have negative offsets, we can subtract ten dd from any positive Dec offset to make it negative: – 10 = . Therefore, each Dec time zone has both a positive and a negative offset. The two offsets in any time zone are exactly one day apart, produce the same time, and have the same color🎨label🏷️.

Millenium Year Day
viewof offset = Inputs.range([-10, 9], {label: "Offset", value: 0, step: 1})

When we add the offset selected by the range🎚️input above to the current date and time in Zone 0, we get + as the date and as the time. We can apply color🎨labels🏷️to each Dec date and time component. Dec dates consist of a year and a day-of-year (doy), whereas Dec times are composed of a time-of-day (tod) and a time zone.

Each doy also has two components. The first two digits of a three-digit doy represent a group of ten days called a decaday (dek). The last digit of a doy is the day-of-dek (dod). In Dec, deks are used instead of months and weeks. Likewise, Dec uses dods in lieu of days-of-month (doms) and days-of-week (dows). In Zone , it is currently Dek and Dod .

Year color🎨labels🏷️are based on millimillennia (mk). Every millennium starts with Year 0 (0 mk) and has Year 500 (500 mk) as its midpoint. Doy color🎨labels🏷️are derived from milliyears (my). Every year starts on Day 0 (0 my). The midyear point (500 my) is noon (500 md) on Day 182 in common years and midnight (0 md) on Day 183 in leap years.

Zone equatorial meter (zem)

Wikimedia

Apart from c, Dec also measures distance using a unit called the zone equatorial meter (zem). The width of a Dec time zone at the Equator is approximately ten million (~107) zems. Similarly, the distance from the Equator to one of the Poles is ~107 meters. In other words, a decimeridian (\(\text d\phi\)) is ~107 zems long and a quarter meridian is ~107 meters long.

Adobe PDF library 6.66 2010-03-06T19:45:34Z 2008-03-27T12:07:11+01:00 Illustrator 2008-03-27T16:40:58+01:00 JPEG 256 160 /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAoAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9KaVpWlnS7MmzgJMEdT6 afyD2xVFfonSv+WKD/kUn9MVd+idK/5YoP8AkUn9MVd+idK/5YoP+RSf0xV36J0r/lig/wCRSf0x V36J0r/lig/5FJ/TFXfonSv+WKD/AJFJ/TFXfonSv+WKD/kUn9MVd+idK/5YoP8AkUn9MVd+idK/ 5YoP+RSf0xV5L/zjFaWl1+Wjy3MMc8v6Uvl5yqHagl2FWB6Yq9a/ROlf8sUH/IpP6Yq79E6V/wAs UH/IpP6Yq79E6V/yxQf8ik/pirv0TpX/ACxQf8ik/pirv0TpX/LFB/yKT+mKu/ROlf8ALFB/yKT+ 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 uuid:db0c57f4-dad3-11dc-b3c0-003065732f80 image/svg+xml keyboard.ai

Wikimedia

Length area volume

You can approximate a zem (z) using your hands🤲. With your palms flat on a table in front of you and the tips of your thumbs👍touching, the maximum distance between the tips of your pinkies is ~1 z. When you spread out the fingers on one hand✋or do the “call me”, “drink”, or “shaka”🤙gesture, your thumb👍and pinky tips are ~0.5 z apart.

Wikimedia

To visualize a square zem (z2), imagine four people standing in a circle, facing inward, each with their right hand✋placed on top of the elbow of the person to their right. Alternatively, two people can stand in front of each other and raise their arms💪, placing one hand✋on the elbow of the other person and the other hand✋on their own elbow.

Wikimedia

You can approximate a z2 yourself by sitting in a chair🪑or standing🧍with your knees and feet🦶1 z, 4 decimeters (dm), or 16 inches apart, which is probably about the width of your hips or shoulders. The z2 will be between your shins, its top will be below your knees, and its bottom will be either above your ankles or feet🦶, depending on your height.

z3

Dimensions.com

Typical seat height

According to dimensions.com, 115 centizems (cz) is the typical seat height for both men and women age 25 to 45. A box📦that is the size of a cubic zem (z3) would likely fit under a typical chair🪑 or in between the shins of two people sitting in front of each other with their knees and feet🦶1 z apart and their legs🦵bent at 25 centiturn (ct) angles📐.

In Slovak🇸🇰, zem means Earth🌍. This is fitting because all Dec units are based on physical attributes of the Earth🌏. At the Equator, the Earth🌎rotates on its axis at a speed of 1.00224 v. If we could indefinitely maintain this speed while flying West in an airplane✈️towards the setting sun☀️, we would be able to perpetually fly into the sunset🌅.

Speed of sound

To travel fast enough, the airplane✈️would need to surpass the speed of sound🔊, which at 15 ° Celsius and 1 standard atmosphere is 0.735048 v or Mach 1. Mach numbers are not as reliable as v, because they are relative to the speed of sound🔊, which varies greatly by air temperature and pressure. The cruising speed of a Boeing 747 is 0.54 v or Mach 0.85.

The highway🛣️speed of a car🚗is roughly tenfold slower than the cruising speed of an airplane✈️. If we are driving on a highway🛣️at a speed of 50 mv and our exit is 1000 z away, we will have 20 centimillidays until we have to exit the highway🛣️. To ensure we do not miss our exit, we can periodically check a countdown of the remaining z: .

Inverse of b (Iob)

Dec refers to centimillidays as beats (b) because they are similar in duration to heart❤️beats or musical beats. A d is 100 centiday (cd), 105 b, or 106 microdays (\(\micro\text d\)). One mc is 100 kilozems (kz), 105 z, 106 decizems (dz), or 106 nanotaurs (nc). Therefore, mv = \(\text{mc}\over\text d\) = \(\text {kz}\over\text {cd}\) = \(\text z\over\text b\) = \(\text {dz}\over\micro\text d\) = \(\text {nc}\over\micro\text d\). A cd is 96% of a quarter hour and a b is 86.4% of a second.

Beats per milliday (bpm)

A normal resting heart❤️rate is between 100 and 166.6 b per md (BPM). The unofficial anthem of the Dec measurement system, “Turn the beat around”, has a tempo of 188.64 BPM, which corresponds to the allegro tempo marking. A Dec clock⏰ticks at a rate of 100 BPM, \(\text b^{-1}\), \(1\over\text b\), or 1 inverse-of-b (iob), which is 1.15740 times more frequent than a Hertz.

Frequency period wavelength

We can divide one by the sound🔊frequency selected by the “Iobs” range🎚️input below to get its period, 1 ÷ kiloiobs (ki) = millibeats (mb), or divide the speed of sound🔊by it to get its wavelength: 735048 microomegars (\(\micro\text v\)) ÷ iobs (i) = millizem (mz). Press the Play▶️button below to hear the chosen frequency for a duration of b.

// https://observablehq.com/@freedmand/sounds
viewof iobs = Inputs.range([1, 9999], { step: 1,  value: 380, label: "Iobs" })
// https://observablehq.com/@freedmand/sounds
viewof beats = Inputs.range([1, 999], { step: 1,  value: 1, label: "Beats" })
// https://observablehq.com/@freedmand/sounds
Play((t) => Math.sin(iobs / .864 * t * 2 * Math.PI), beats * .864)

Ten equal temperament (Xet)

The positive (+) and negative (–) indexes, hex triplets, and h° in the table below are used by Dec to label🏷️groups of ten, like dods, “top of the dd” tods, and time zones. In addition to colors🎨, Dec also labels🏷️groups of ten with the musical notes that constitute the Dec chromatic (Dechromatic) scale of the Ten equal temperament (Tenet) musical system.

Tenet (Xet) identifies each Dechromatic scale note with a single-digit integer and expresses all other possible sound🔊frequencies as decimal numbers. In contrast, the notes of the 12 equal temperament (12ET) musical system have names that consist of a letter from A to G and a symbol such as sharp (♯), half sharp (𝄲), flat (♭), and half flat (𝄳).

The sound🔊frequencies of two consecutive Xet Dechromatic scale notes always differ by one step (s), but the differences between consecutive 12ET chromatic scale notes vary from the ~599 millisteps (ms) between A♯ and B to the ~1067 ms between G♯ and A. A typical person can reliably distinguish sounds🔊that differ by at least 200 ms.

The rightmost column of the table below shows the 12ET notes that are closest to the Xet Dechromatic scale notes. 12ET considers B𝄲, D𝄲, and E𝄳 to be microtones. The sound🔊frequency differences between the nearest Xet and 12ET notes in the table range from the 8 ms between Notes 9 and A to the ~87 ms between Notes 5 and F.

Color sound table
+ – hex🎨 h°🎨 12ET🎶
0 -10 f00 0 A♯
1 -9 f90 36 B𝄲
2 -8 ff0 60 C♯
3 -7 af0 80 D𝄲
4 -6 0f0 120 E𝄳
5 -5 0ff 180 F
6 -4 08f 208 F♯
7 -3 00f 240 G
8 -2 90f 276 G♯
9 -1 f0f 300 A
piano(width)
Octave + note = tone

The image above applies Dec color🎨labels🏷️to one octave of piano🎹keys. In Xet, an octave is 10 s or 104 ms. The text below the image provides from top to bottom the scientific pitch name, integer i sound🔊frequency, and integer mz wavelength of the corresponding white key. As octave indexes and frequency increase, wavelength decreases.

Octave indexes in Xet and 12ET match except for Xet notes with indexes below 2 and 12ET notes from A♯ to B𝄲. From the perspective of Xet, all of the labeled🏷️keys in the image above are in Octave 4. When we append a positive note index that is less than ten to an octave index which is a positive integer, we obtain a Xet musical tone index.

The tone indexes of the the labeled🏷️keys in the image above range from 40.069 to 49.008. Tone 49.008 is A4, the A note widely used to tune musical instruments. Tone 41.302 is C4, the “Middle C” in between the bass and treble🎼clefs of a grand staff. The typical audible range for humans extends from Tone 03 to Tone 104.

By default, each Xet note or tone lasts one musical beat. Xet modifies the duration of notes and tones by appending × and a multiplier or ÷ and a divisor. The first two measures of the chorus from “Turn the beat around” are shown below and can be expressed in Xet as Octave 4 and a series of notes followed by a rest (∅): 9 9÷2 8 8 6×4 ∅.

abcjs = require('https://bundle.run/abcjs@5.1.2/midi.js')
code = `
M:4/4
L:1/4
K:A
y A A/2G/2- G/2 G F/2- | F3 z |
w: Turn the~ ~beat _ ~a- ~round
`
abc(code, true)
function abc(tune, midi = false, notation = true) {
    function colorRange(range, color) {
        if (range && range.elements) {
            range.elements.forEach(function(set) {
                set.forEach(function(item) {
                    item.setAttribute("fill", color);
                });
            });
        }
    }
    const result = html `<div/>`;
    if (notation) {
        const notation = result.appendChild(html `<div/>`);
        var abcElem = (abcjs.renderAbc(notation, tune));
    }
    if (midi) {
        result.appendChild(html `<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"/><link rel="stylesheet" type="text/css" href="https://unpkg.com/abcjs@5.1.2/abcjs-midi.css"/>`);
        const midi = result.appendChild(html `<div/>`);
        abcjs.renderMidi(midi, tune, {
            midiListener: function(a, b, c) {},
            animate: {
                listener: function(a, b, c) {
                    colorRange(a, "#000000");
                    colorRange(b, "#3D9AFC");
                },
                target: abcElem[0],
                qpm: abcElem[0].getBpm()
            }
        });
        //  abcjs.midi.startPlaying(document.querySelector(".abcjs-inline-midi"),true)
    }
    return result;
}

US customary units

The unit conversion table below shows the United States🇺🇸(US) customary units that Dec redefines. The values in the first column are approximate fold changes from original to redefined units. A fold change of 1 means 0 change. Identical fold changes indicate US customary units derived from the same Dec and International System of Units (SI) units.

Unit conversion table
US Dec SI
1.0356 miles \(25\over6\) kz \(5\over3\) km
0.9843 yards \(9\over4\) z 9 dm
0.9843 feet \(3\over4\) z 3 dm
0.9843 inches \(1\over16\) z 25 mm
0.9884 acres \(1\over40\) kz2 \(1\over250\) km2
1.0725 square miles \(625\over36\) kz2 \(25\over9\) km2
0.9688 square yards \(81\over16\) z2 81 dm2
0.9688 square feets \(9\over16\) z2 9 dm2
0.9688 square inches \(1\over256\) z2 625 mm2
1.1023 pounds 500 g 500 g
1.0567 barrels 2 z3 128 L
1.0567 kegs 1 z3 64 L
1.0567 gallons \(1\over16\) z3 4 L
1.0567 quarts \(1\over64\) z3 1 L
1.0567 pints \(1\over128\) z3 500 mL
1.0567 cups \(1\over256\) z3 250 mL
1.0821 wineglass 1 dz3 64 mL
1.0821 ounces \(1\over2\) dz3 32 mL
1.0821 tablespoons \(1\over4\) dz3 16 mL
Miles per hour (mph)

Unlike Dec and SI, the US customary measurement system does not use metric prefixes to scale units by powers of ten. Redefined US customary units serve as convenient reference points. US customary volume units have intuitive names and scale by powers of two. Miles are redefined such that 1 mile per hour is equal to 1 mv or \(5\over3\) kilometers (km) per hour.

Hexamilliare wineglass keg

A square kilozem (kz2) is 1 hexakilare, 16 hectares, 1600 ares, 40 Dec acres, 0.16 square kilometers (km2), ~0.062 Dec square miles, or 106 z2. A z2 is a hexamilliare (x), 16 square decimeters (dm2), 1.7 Dec square feet🦶, or 256 Dec square inches. A square decazem (Dz2) is 1 hexadeciare, 16 square meters (m²), ~19.75 Dec square yards, or 100 x.

A cubic decizem (dz3) is 1 cubic nanotaur (nc3), 2 Dec ounces, or 64 milliliters (mL). A dz3 of water🌊weighs 64 grams (g). Even though a Dec ounce of water🌊weighs close to a sixteenth of a Dec pound, Dec does not measure weights in ounces. A z3 is 16 Dec gallons or 64 liters (L). A z3 of water🌊weighs 64 kilograms (kg) or 128 Dec pounds.

Wikimedia

Body mass index (bmi)

If Leonardo da Vinci’s Vitruvian Man were 4 z tall, we could measure 1 z from his knees to his feet🦶or from his elbows💪to his fingertips. If he also weighed 64 kg, his Body Mass Index (BMI) would be 4 \(\text {kg}\over\text z^2\) or 25 \(\text {kg}\over\text m^2\). A normal BMI ranges from 2.96 to 4 \(\text {kg}\over\text z^2\) or 18.5 to 25 \(\text {kg}\over\text m^2\). A BMI of kg ÷ z2 = \(\text {kg}\over\text z^2\) = \(\text {kg}\over\text m^2\) is considered .

viewof kilograms = Inputs.range([0, 1000], {label: "Kilograms", value: 64, step: .1})
viewof zems = Inputs.range([0, 10], {label: "Zems", value: 4, step: 0.01})
Centizem centimeter inch

Wikimedia

The longest length depicted in the image of a ruler📏above is 1 dz, 1 nc, 4 centimeters (cm), or \(8\over5\) Dec inches, and the shortest length is \(1\over2\) mz, \(1\over5\) millimeters (mm), \(1\over125\) Dec inches, or \(1\over127\) US customary inches. A US customary inch is \(127\over2\) mz, \(127\over5\) mm, or \(127\over125\) Dec inches. A Dec inch is \(5\over2\) cm. A cm is \(5\over2\) cz. A z is 4 dm. A dm is 4 Dec inches.

Summary

This article introduces the Dec measurement system and describes how Dec uses metric prefixes and the properties of the planet Earth🌍to define units based on turns for geographic coordinates, compass🧭directions, dates, times, speeds, distances, areas, volumes, and weights. Each unit has a unique name, such as \(\lambda\), \(\phi\), \(\alpha\), y, d, b, v, c, z, or x.

Dec attempts to bridge the gap, improve interoperability, and faciliate conversion between the US customary and SI measurement systems by redefining US customary units. Redefinition of US customary units makes inches ~1.58% shorter, miles ~3.56% longer, pints ~5.67% larger, ounces ~8.21% larger, and pounds ~10.23% heavier.

Dec color🎨labels🏷️can convey an impression of many different kinds of values at a glance. Moreover, color🎨labels🏷️help avoid confusion when dealing with different metric prefixes. The current tod in Zone can be expressed as dd, days, or b. Metric prefixes allow us to shift the decimal separator in decimal numbers.

Next

Now that you have had a taste of Dec, I hope that you are hungry for more! If so, dive🤿deeper into Dec dates and times before tackling Dec snaps🫰and spans🌈. My filter, include, and script articles discuss the Quarto publishing system and how I display Dec dates in the navigation bar, title block, and citation section of each article on my website.

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '32px'}}}%%
flowchart LR
   A[Dec]-->B[date]-->C[time]-->D[snap]-->E[span]
   Z[  ]:::empty~~~F[Quarto]-->G[filter]-->H[include]-->I[script]
   classDef empty width:0px;
   click A "/dec"
   click B "/dec/date"
   click C "/dec/time"
   click D "/dec/snap"
   click E "/dec/span"
   click F "/quarto"
   click G "/quarto/filter"
   click H "/quarto/include"
   click I "/quarto/script"

Cite

Please support Dec by citing it as shown at the bottom of this article. Listed below are citations for the Observable notebooks that I adapted into the map🗺️, color🎨wheel compass🧭, and other visualizations above. The list also includes citations for three works that predate the French Revolution and three more recent articles published on websites.

In his 1704 book entitled Optiks, Isaac Newton presented the first color🎨wheel and linked its colors🎨to musical notes. On 2025+080, I read The Color of Sound by Clint Goss, which presents a method of connecting musical notes to colors🎨via their frequencies. The note and color🎨pairs in that article are similar to those of the Dechromatic scale.

In 1754, Jean le Rond d’Alembert lauded the benefits of decimalisation. In 1788, Claude Boniface Collignon proposed measuring length in dz or nc and tracking time in deks, dd, md, \(\micro\text d\), and nanodays (nd). On 2025+039, I saw the definition of a zem, 1 z = 10-8 c = 40 cm, in a table of ten possible length units from a 2004 arxiv article.

The fundamental properties of Dec dates are defined by algorithms developed by Howard Hinnant and described in his 2021 article entitled chrono-Compatible Low-Level Date Algorithms. On 2024+285, I found a 2014 article which proposed a decimal time system with twenty time zones, each five cd wide, based on Longitude 05 (50 \(\text m\lambda\)).

  • Agnoli, Paolo & D’Agostini, Giulio. 2004+330. “Why does the meter beat the second?” . https://arxiv.org/abs/physics/0412078.
  • Armstrong, Zan 2023+057. “Text color annotations in markdown.” . https://observablehq.com/@observablehq/text-color-annotations-in-markdown.
  • Bostock, Mike 2020+335. “Time Zones.” . https://observablehq.com/@mbostock/time-zones.
  • Bostock, Mike 2022+037. “Solar Terminator.” . https://observablehq.com/@d3/solar-terminator.
  • Bostock, Mike 2023+314. “Input: Table.” . https://observablehq.com/@observablehq/input-table.
  • Clements, John. 2014+091, “Decimal Time Zones.” . https://www.brinckerhoff.org/blog/2014/05/31/decimal-time-zones.
  • Clint Goss. 2022+098. “Color of Sound.” . https://www.flutopedia.com/sound_color.htm.
  • Collignon, Claude Boniface. 1788. “Découverte d’étalons justes, naturels, invariables et universels.” . https://archive.org/details/dcouvertedtalon00collgoog/page/n68/mode/2up.
  • Edwards, Paul. 2022+171. “Compass Rose as legend with colors.” . https://observablehq.com/@pjedwards/compass-rose-as-legend-with-colors.
  • Freedman, Dylan. 2017+345. “Sounds.” . https://observablehq.com/@freedmand/sounds.
  • Gordon, Marcus A.. 2018+288. “Wavelengths and Spectral Colours.” . https://observablehq.com/@magfoto/wavelengths-and-spectral-colours.
  • Harmath, Dénes. 2018+104. “ABC.” . https://observablehq.com/@thsoft/abc.
  • Hinnant, Howard. 2021+184. “chrono-Compatible Low-Level Date Algorithms.” . https://howardhinnant.github.io/date_algorithms.html.
  • Johnson, Ian 2021+121. “Draggable World Map Coordinates Input.” . https://observablehq.com/@enjalot/draggable-world-map-coordinates-input.
  • Lim, Maddie 2018+330. “Enneagram.” . https://observablehq.com/@maddievision/enneagram.
  • Newton, Issac. 1704. “Opticks.” . https://doi.org/10.5479/sil.302475.39088000644674.
  • Paavanb. 2024+006. “Progressive Color Picker.” . https://observablehq.com/@paavanb/progressive-color-picker.
  • Patel, Amit. 2021+290. “Compass Rose.” . https://observablehq.com/@paavanb/progressive-color-picker.
  • Pettiross, Jeff 2024+150. “Categorical color scheme test tool.” . https://observablehq.com/@observablehq/categorical-palette-tool
  • Rieder, Lukas 2023+032. “Editable table.” . https://observablehq.com/@parlant/editable-table.
  • Rivière, Philippe 2022+259. “Add a class to an observable input.” . https://observablehq.com/@recifs/add-a-class-to-an-observable-input--support.
  • Rivière, Philippe 2023+330. “D3 Projections.” . https://observablehq.com/@fil/d3-projections.
  • Yamahata, Christophe 2021+119. “Great circle: shortest distance between two locations on Earth 🌏.” . https://observablehq.com/@christophe-yamahata/great-circle-shortest-distance-between-two-locations-on-ea.
  • d’Alembert, Jean le Rond. 1754. “Decimal.” Encyclopédie, 4, 670. . https://artflsrv04.uchicago.edu/philologic4.7/encyclopedie0922/navigate/4/3458.
function createTable(data, options) {
  let table = html`<table class="editable-table"></table>`;
  table.innerHTML = xss.filterXSS(tableify.default(data));
  makeTableEditable(table, options);
  return table;
}
table.setAttribute("class", "table")
tableify = import("https://cdn.skypack.dev/tableify@1.1.1?min")
xss = import("https://cdn.skypack.dev/xss@1.0.14?min")
function createCellDiv(value, max) {
  return `<div style="
    width: ${Math.abs(value) / max}%;
    float: left;
    padding: 0px 0px 0px 2px;
    text-indent: 2px;
    box-sizing: border-box;
    overflow: visible;
    white-space: nowrap;
    display: flex;
    justify-content: start;">${Math.round(value)}</div>`
}
liveTable = observeTable(table)
function makeTableEditable(table, options) {
  const defaults = {headerEditable: false, appendRows: true};
  options = options === undefined ? {} : options;
  for (let key in defaults) {
    options[key] = options[key] === undefined ? defaults[key] : options[key];
  }
  return Generators.observe((_notify) => {
    const navigate = (event) => {
      const cell = event.target;
      const row = cell.closest('tr');
      const table = row.closest('table');
      const isBody = row.parentNode.tagName === 'TBODY';
      const isHeader = row.parentNode.tagName === 'THEAD';
      const colIndex = cell.cellIndex;
      const colCount = row.cells.length;
      const rowIndex = row.rowIndex;
      const rowCount = table.rows.length;
      const headStop = options.headerEditable ? 0 : 1;
      let direction = null;
      let x = colIndex;
      let y = rowIndex;
      if (![
      // https://www.freecodecamp.org/news/javascript-keycode-list-keypress-event-key-codes#heading-a-full-list-of-key-event-values
        8, 9, 13, 16, 17, 18, 27, 33, 34, 35, 36, 37, 38, 39, 40, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 109, 189
      ].includes(event.which)) {
        event.preventDefault();
      }
      else {
      switch(event.code) {
        // Tab cycles through the table, adding new rows as needed.
        case 'Tab':
          event.preventDefault();
          if (event.altKey || event.shiftKey) {
            direction = -1;
            if (x - 1 < 0) {
              if (y - 1 < headStop) break;
              x = colCount - 1;
              y = y - 1;
            } else {
              x = x - 1;
            }
          } else {
            direction = 1;
            if (x + 1 === colCount) {
              x = 0;
              y = y + 1;
            } else {
              x = x + 1;
            }
          }
          break;
        // Plain Enter navigates downwards.
        // Shift + Enter or Alt + Enter goes up to the cell above.
        case 'Enter':
          event.preventDefault();
          if (event.altKey || event.shiftKey) {
            direction = -1;
            x = x;
            y = y - 1;
          }
          else {
            direction = 1;
            x = x;
            y = y + 1;
          }
          break;
        // The arrow keys allow you to navigate through cells.
        // No new rows are added.
        case 'ArrowUp':
        case 'ArrowDown':
        case 'ArrowLeft':
        case 'ArrowRight':
        case 'Enter':
          if (!event.altKey) break;
          event.preventDefault();
          switch(event.code) {
            case 'ArrowUp':
              direction = -1;
              y = Math.max(y - 1, headStop);
              break;
            case 'ArrowDown':
              direction = 1;
              y = Math.min(y + 1, rowCount - 1);
              break;
            case 'ArrowLeft':
              direction = -1;
              x = Math.max(x - 1, 0);
              break;
            case 'ArrowRight':
              direction = 1;
              x = Math.min(x + 1, colCount - 1);
              break;
          }
          break;
      }
      if (direction !== null) {
        let nextRow;
        if (y === rowCount) {
          nextRow = options.appendRows ? addRowRelativeTo(row, direction) : row;
        } else {
          nextRow = table.rows[y];
        }
        let nextCell = nextRow.cells[x];
        focusCell(nextCell);
      }
    };
    }
    table.addEventListener("keydown", navigate, false);
    if (table.rows.length > 0) {
      for (let row of table.rows) {
        if (!options.headerEditable && row.rowIndex === 0) continue;
        for (let cell of row.cells) {
        if (cell.cellIndex === 0) continue;
          let cellValue = cell.innerText
          cell.innerHTML = `<div style="
            width: ${Math.abs(cellValue) / (cell.cellIndex === 2 ? 2.5 : 10)}%;
            float: left;
            padding: 0px 0px 0px 2px;
            text-indent: 2px;
            box-sizing: border-box;
            overflow: visible;
            white-space: nowrap;
            display: flex;
            justify-content: start;">${cellValue}</div>`
        if (cell.cellIndex === 3) continue;
          cell.contentEditable = true;
        }
      }
    }
    return () => table.removeEventListener("keydown", navigate);
  });
}
function observeTable(table) {
  return Generators.observe((notify) => {
    const keyinput = (event) => notify(parseTableData(table));
    table.addEventListener("input", keyinput, false);
    notify(parseTableData(table));
    return () => window.removeEventListener("input", keyinput);
  });
}
function parseTableData(table) {
  const header = [];
  const data = [];
  for (let row of table.rows) {
    const rowIndex = row.rowIndex;
    const isHeader = row.parentNode.tagName === 'THEAD' && rowIndex === 0;
    let obj = {};
    for (let cell of row.cells) {
      const head = header[cell.cellIndex];
      if (isHeader) {
        header.push(cell.innerText);
      } else {
        obj[head] = cell.innerText;
      }
    }
    if (!isHeader) data.push(obj);
  }
  return JSON.parse(JSON.stringify(data));
}
function focusCell(td) {
  const s = window.getSelection();
  const r = document.createRange();
  let textNode = td.childNodes[0];
  const i = td.innerText.length;
  td.focus();
  if (textNode) {
    r.setStart(textNode, i);
    r.setEnd(textNode, i);
  } else {
    r.selectNode(td);
  }
  s.removeAllRanges();
  s.addRange(r);
}
function addRowRelativeTo(tr, direction) {
  const newTr = document.createElement('tr');
  const insertPosition = direction == 1 ? 'afterend' : 'beforebegin';
  tr.insertAdjacentElement(insertPosition, newTr);
  for (let _td of Array.from(tr.children)) {
    const newTd = document.createElement('td');
    newTd.appendChild(document.createTextNode(''));
    newTd.contentEditable = true;
    newTr.appendChild(newTd);
  }
  return newTr;
}
// https://observablehq.com/@observablehq/text-color-annotations-in-markdown
rstbtn = d3.create('button').html('Reset').attr("id", "rstbtn").attr("class", "btn btn-quarto");
// https://observablehq.com/@recifs/add-a-class-to-an-observable-input--support
function labelToggle(inputType, inputLabel, inputValue, inputId) {
  const input = inputType({label: inputLabel, value: inputValue});
  input.setAttribute("id", inputId);
  return input;
}
// https://observablehq.com/@observablehq/synchronized-inputs
function set(input, value) {
  input.value = value;
  input.dispatchEvent(new Event("input", {bubbles: true}));
}
// https://observablehq.com/@observablehq/input-table
// https://stackoverflow.com/a/52079217
// Converts from degrees to radians.
function toRadians(degrees) { return degrees * Math.PI / 180; };
// Converts from radians to degrees.
function toDegrees(radians) { return radians * 180 / Math.PI; }
function coor2bear(strt, dest) {
  const [strtLng, strtLat] = strt.map(toRadians);
  const [destLng, destLat] = dest.map(toRadians);
  return (toDegrees(Math.atan2(
    Math.sin(destLng - strtLng) * Math.cos(destLat),
    Math.cos(strtLat) * Math.sin(destLat) - Math.sin(strtLat) * Math.cos(destLat) * Math.cos(destLng - strtLng)
  )) + 360) % 360;
}
function yiq(color) {
  const {r, g, b} = d3.rgb(color);
  return (r * 299 + g * 587 + b * 114) / 1000 / 255; // returns values between 0 and 1
}
function textcolor(content, style = {}) {
  const {
    background,
    color = yiq(background) > 0.51 ? "#000" : "white",
    padding = "0 5px",
    borderRadius = "4px",
    fontWeight = 400,
    fontFamily = "monospace",
    ...rest
  } = typeof style === "string" ? {background: style} : style;
  return htl.html`<span style=${{
    background,
    color,
    padding,
    borderRadius,
    fontWeight,
    fontFamily,
    ...rest
  }}>${content}</span>`;
}
function turn2comp(turn) {
  return ["N", "NE", "E", "SE", "S", "SW", "W", "NW"][Math.round(turn / 125) % 8]
}
function dec2rgb(d) {
  const color = d3.color(piecewiseColor(d % 1))
  return [color.r, color.g, color.b]
}
function dec2hue(d) {
  return rgbToHsl(...dec2rgb(d))[0] * 1000
}
piecewiseColor = d3.piecewise(d3.interpolateRgb, [
  "#f00",    //  0   0 red
  "#f50",    //  0.25  20 yr
  "#f60",    //  0.5   24 yr orangered
  "#f70",    //  0.75  28 yr
  "#f90",    //  1     36 yr orange
  "#fb0",    //  1.25  44 yr
  "#fc0",    //  1.5   48 yr yelloworange
  "#fd0",    //  1.75  52 yr
  "#ff0",    //  2     60 yellow
  "#ef0",    //  2.25  64 gy
  "#df0",    //  2.5   68 gy limeyellow
  "#cf0",    //  2.75  72 gy
  "#af0",    //  3     80 gy lime
  "#8f0",    //  3.25  88 gy
  "#7f0",    //  3.5   92 gy greenlime
  "#6f0",    //  3.75  96 gy
  "#0f0",    //  4    120 green
  "#0f7",    //  4.25 148 cg
  "#0f9",    //  4.5  156 cg cyangreen
  "#0fb",    //  4.75 164 cg
  "#0ff",    //  5    180 cyan
  "#0cf",    //  5.25 192 bc
  "#0bf",    //  5.5  196 bc azurecyan
  "#0af",    //  5.75 200 bc
  "#08f",    //  6    208 bc azure
  "#06f",    //  6.25 216 bc
  "#05f",    //  6.5  220 bc blueazure
  "#04f",    //  6.75 224 bc
  "#00f",    //  7    240 blue
  "#50f",    //  7.25 260 mb
  "#60f",    //  7.5  264 mb purpleblue
  "#70f",    //  7.75 268 mb
  "#90f",    //  8    276 mb purple
  "#b0f",    //  8.25 284 mb
  "#c0f",    //  8.5  288 mb violetpurple
  "#d0f",    //  8.75 292 mb
  "#f0f",    //  9    300 magenta
  "#f0a",    //  9.25 320 rm
  "#f08",    //  9.5  328 rm
  "#f06",    //  9.75 336 rm
  "#f00",    //  0        0 red
])
hueMtr = Math.round(colorD)
hueDeg = dec2hue(colorD / 1000) * .36
hStr = `hsl(${hueDeg}`
slStr = `, ${colorS / 10}%, ${colorL / 10}%)`
hslStr = hStr + slStr
bkgH = ({background: hStr + ", 100%, 50%)"})
bkgHsl = ({background: hslStr})
rainbowMtr = textcolor(hueMtr, bkgHsl)
rainbowDir = textcolor(turn2comp(hueMtr), bkgHsl)
rainbowDegC = textcolor(Math.round(colorD *.36), bkgHsl)
rainbowDegH = textcolor(Math.round(hueDeg), bkgHsl)
rainbowHex = textcolor(shortenHex(d3.color(hslStr).formatHex()).slice(1), bkgHsl)
wavehex = d3.color(wavelengthToColor(wavelength * .4)[0]).formatHex()
wavehexHsl = textcolor(wavehex.slice(1), wavehex)
rainbowN5zn = textcolor('-5', d3.color(`hsl(180${slStr}`).formatHex())
rainbowP583 = textcolor('5.83̅', d3.color(`hsl(129.88235294117646${slStr}`).formatHex())
// Show preview swatches of color
preview = () => {
  const container = DOM.element('div')
  d3.select(container).attr('style', 'display: flex;')
  d3.select(container)
    .append('div')
      .text('Selected')
      .style('font-weight', 'bold')
    .append('div')
      .classed('swatch', true)
      .style('background-color', `hsl(${dec2hue(colorD / 1000) * .36}, ${colorS / 10}%, ${colorL / 10}%`);
  d3.select(container)
    .append('div')
      .text('Preview')
      .style('font-style', 'italic')
    .append('div')
      .classed('swatch', true)
      .style('background-color', `rgb(${hoverRGB[0]}, ${hoverRGB[1]}, ${hoverRGB[2]}`)
  d3.select(container).selectAll('div.swatch')
    .style('width', '100px')
    .style('height', '100px')
    .style('margin-right', '8px')
    .style('padding', '4px')
  return container
}
// The currently hovered color
mutable hoverRGB = [255, 0, 0]
/**
 * Draw an interactive color bar
 * @param colorFn (t: number) => [number, number, number] Given a position on the bar (between 0 and 1), return its RGB
 * @param onSelect (t: number) => void Callback for when a position is selected on the bar
 */
function colorbar({colorFn, onSelect}) {
  const WIDTH = 360
  const HEIGHT = 32
  const container = DOM.element('div')
  function handleSelect(coords) {
    const t = coords[0] / WIDTH
    onSelect(t)
  }
  let isDragging = false
  const canvas = d3.select(container).append('canvas')
    .attr('width', WIDTH)
    .attr('height', HEIGHT)
    .attr('style', 'cursor: crosshair; border: 1px solid black; border-radius: 2px;')
    .on('mousedown', function() {
      isDragging = true
      handleSelect(d3.mouse(this))
    })
    .on('mouseup', () => { isDragging = false; })
    .on('mousemove', function() {
      const coords = d3.mouse(this)
      if (isDragging) {
        handleSelect(coords)
      }
      mutable hoverRGB = colorFn(coords[0] / WIDTH)
    })
  const ctx = canvas.node().getContext('2d')
  const imgData = ctx.getImageData(0, 0, WIDTH, HEIGHT)
  // Possible optimization: cache d3.range so we're not recalculating it a million times
  d3.range(WIDTH).forEach(colIdx => {
    const t = colIdx / WIDTH
    const rgb = colorFn(t)
    d3.range(HEIGHT).forEach(rowIdx => {
      const screenIdx = rowIdx * WIDTH + colIdx
      const imgDataIdx = 4 * screenIdx
      imgData.data[imgDataIdx] = rgb[0]
      imgData.data[imgDataIdx + 1] = rgb[1]
      imgData.data[imgDataIdx + 2] = rgb[2]
      imgData.data[imgDataIdx + 3] = 255
    })
  });
  ctx.putImageData(imgData, 0, 0)
  return container;
}
initialRGB = [255, 0, 0]
initialHSL = rgbToHsl(...initialRGB)
viewof colorR = Inputs.input(initialRGB[0])
viewof colorG = Inputs.input(initialRGB[1])
viewof colorB = Inputs.input(initialRGB[2])
viewof colorD = Inputs.input(dec2hue(initialHSL[0]))
viewof colorS = Inputs.input(1000)
viewof colorL = Inputs.input(500)
viewof colorA = Inputs.input(1000)
/**
 * Update all color values based on current HSL
 */
onUpdateHSL = function(h, s, l) {
  const rgb = hslToRgb(h / 1000, s / 1000, l / 1000)
  console.log(h)
  set(viewof colorR, rgb[0])
  set(viewof colorG, rgb[1])
  set(viewof colorB, rgb[2])
}
/**
 * Credit to github.com/mjackson Source: https://gist.github.com/mjackson/5311256
 * Converts an RGB color value to HSL. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes r, g, and b are contained in the set [0, 255] and
 * returns h, s, and l in the set [0, 1].
 *
 * @param   Number  r       The red color value
 * @param   Number  g       The green color value
 * @param   Number  b       The blue color value
 * @return  Array           The HSL representation
 */
function rgbToHsl(r, g, b) {
  r /= 255, g /= 255, b /= 255;
  var max = Math.max(r, g, b), min = Math.min(r, g, b);
  var h, s, l = (max + min) / 2;
  if (max == min) {
    h = s = 0; // achromatic
  } else {
    var d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }
  return [ h, s, l ];
}
/**
 * Credit to github.com/mjackson Source: https://gist.github.com/mjackson/5311256
 * Converts an HSL color value to RGB. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes h, s, and l are contained in the set [0, 1] and
 * returns r, g, and b in the set [0, 255].
 *
 * @param   {number}  h       The hue
 * @param   {number}  s       The saturation
 * @param   {number}  l       The lightness
 * @return  {Array}           The RGB representation
 */
function hslToRgb(h, s, l){
    let r, g, b;
    if(s == 0){
        r = g = b = l; // achromatic
    } else {
        let q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        let p = 2 * l - q;
        r = hue2rgb(p, q, h + 1/3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1/3);
    }
    return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
/**
 * Credit github.com/mjackson. Source: https://gist.github.com/mjackson/5311256
 */
function hue2rgb(p, q, t) {
  if (t < 0) t += 1;
  if (t > 1) t -= 1;
  if (t < 1/6) return p + (q - p) * 6 * t;
  if (t < 1/2) return q;
  if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
  return p;
}
// https://observablehq.com/@maddievision/simple-canvas
pixelRatio = window.devicePixelRatio;
createCanvas = (width, height) => {
  const canvas = document.createElement('canvas');
  canvas.width = width * pixelRatio;
  canvas.height = height * pixelRatio;
  canvas.style.width = width + 'px';
  canvas.style.height = height + 'px';
  return canvas
}
renderWithScale = (context, renderFunction) => {
  context.save();
  context.scale(pixelRatio, pixelRatio);
  renderFunction()
  context.restore();
}
quickRender = (width, height, renderer) => {
  const canvas = createCanvas(width, height)
  const context = canvas.getContext('2d')
  renderWithScale(context, () => {
    renderer(context)
  })
  return canvas
}
// http://howardhinnant.github.io/date_algorithms.html#civil_from_days
function unix2dote(unix, zone, offset = 719468) {
  return [(unix ?? Date.now()) / 86400000 + (
    zone = zone ?? -Math.round(
      (new Date).getTimezoneOffset() / 144)
    ) / 10 + offset, zone]
}
function unix2dote1(unix, zone, offset = 719468) {
  return [(unix ?? Date.now()) / 86400000 + (
    zone = zone ?? (-Math.round(
      (new Date).getTimezoneOffset() / 144) + 10) % 10
    ) / 10 + offset, zone]
}
octConnections = [
  [0, 4],
  [1, 5],
  [2, 6],
  [3, 7],
  [4, 0],
  [5, 1],
  [6, 2],
  [7, 3],
]
decConnections = [
  [0, 5],
  [1, 6],
  [2, 7],
  [3, 8],
  [4, 9],
  [5, 0],
  [6, 1],
  [7, 2],
  [8, 3],
  [9, 4]
]
hsl8 = [
  `hsl(0, ${colorS / 10}%, ${colorL / 10}%)`,   // 0
  `hsl(44, ${colorS / 10}%, ${colorL / 10}%)`, // 875
  `hsl(68, ${colorS / 10}%, ${colorL / 10}%)`, // 750
  `hsl(96, ${colorS / 10}%, ${colorL / 10}%)`, // 625
  `hsl(180, ${colorS / 10}%, ${colorL / 10}%)`, // 500
  `hsl(216, ${colorS / 10}%, ${colorL / 10}%)`, // 375
  `hsl(264, ${colorS / 10}%, ${colorL / 10}%)`, // 250
  `hsl(292, ${colorS / 10}%, ${colorL / 10}%)`, // 125
]
hsl10 = [
  `hsl(0, ${colorS / 10}%, ${colorL / 10}%)`, // red
  `hsl(36, ${colorS / 10}%, ${colorL / 10}%)`, // orange
  `hsl(60, ${colorS / 10}%, ${colorL / 10}%)`, // yellow
  `hsl(80, ${colorS / 10}%, ${colorL / 10}%)`, // lime
  `hsl(120, ${colorS / 10}%, ${colorL / 10}%)`, // green
  `hsl(180, ${colorS / 10}%, ${colorL / 10}%)`, // cyan
  `hsl(208, ${colorS / 10}%, ${colorL / 10}%)`, // azure
  `hsl(240, ${colorS / 10}%, ${colorL / 10}%)`, // blue
  `hsl(276, ${colorS / 10}%, ${colorL / 10}%)`, // violet
  `hsl(300, ${colorS / 10}%, ${colorL / 10}%)`, // magenta
  `hsl(0, ${colorS / 10}%, ${colorL / 10}%)`, // red
]
hsla10 = [
  `hsla(0, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // red
  `hsla(36, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // orange
  `hsla(60, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // yellow
  `hsla(80, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // lime
  `hsla(120, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // green
  `hsla(180, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // cyan
  `hsla(208, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // azure
  `hsla(240, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // blue
  `hsla(276, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // violet
  `hsla(300, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // magenta
  `hsla(0, ${colorS / 10}%, ${colorL / 10}%, ${colorA / 10}%)`, // red
]
function dote2date(dote, zone = 0) {
  const cote = Math.floor((
      dote >= 0 ? dote
      : dote - 146096
    ) / 146097),
  dotc = dote - cote * 146097,
  yotc = Math.floor((dotc
    - Math.floor(dotc / 1460)
    + Math.floor(dotc / 36524)
    - Math.floor(dotc / 146096)
  ) / 365);
  return [
    yotc + cote * 400,
    dotc - (yotc * 365
      + Math.floor(yotc / 4)
      - Math.floor(yotc / 100)
  ), zone]}
sunLonHsl = textcolor(sunLon, `hsl(${d3.hsl(piecewiseColor(sunLon % 1000 / 1000)).h}` + slStr)
sunLatHsl = textcolor(sunLat, `hsl(${d3.hsl(piecewiseColor((sunLat + 1000) % 1000 / 1000)).h}` + slStr)
dz = unix2dote(now)
ydz = dote2date(...dz)
decZone = ydz[2]
decZonePos = (decZone + 10) % 10
decSign = decZone < 0 ? "+" : "–"
decSignOff = offset < 0 ? "+" : "–"
dzOff = unix2dote(now, offset)
ydzOff = dote2date(...dzOff)
decYearOff = ydzOff[0]
decYearOffHsl = textcolor(decYearOff, `hsl(${d3.hsl(piecewiseColor(decYearOff % 1000 / 1000)).h}` + slStr)
decDateOff = Math.floor(ydzOff[1])
decDek = Math.floor(decDateOff / 10)
decDod = decDateOff % 10
decDotyOff = decDateOff.toString().padStart(3, "0")
decTimeOff = ydzOff[1] % 1
decOffsetPosi = (offset + 10) % 10
decOffsetNega = decOffsetPosi - 10
decOffsetHslP = textcolor(decOffsetPosi, `hsl(${d3.hsl(piecewiseColor(decOffsetPosi / 10)).h}` + slStr)
decOffsetHslN = textcolor(decOffsetNega, `hsl(${d3.hsl(piecewiseColor(decOffsetPosi / 10)).h}` + slStr)
decOffsetHsl0 = textcolor(offset, `hsl(${d3.hsl(piecewiseColor(decOffsetPosi / 10)).h}` + slStr)
decOffsetHsl1 = textcolor(Math.abs(offset), `hsl(${d3.hsl(piecewiseColor(decOffsetPosi / 10)).h}` + slStr)
decOffsetHsl2 = textcolor(decOffsetPosi, `hsl(${d3.hsl(piecewiseColor(decOffsetPosi / 10)).h}` + slStr)
decOffsetHsl3 = textcolor(decOffsetPosi, `hsl(${d3.hsl(piecewiseColor(decOffsetPosi / 10)).h}` + slStr)
decDateOffHsl = textcolor(decDateOff.toString().padStart(3, "0"), `hsl(${d3.hsl(piecewiseColor(decDateOff / (365 + isLeapOff))).h}` + slStr)
decDekOffHsl = textcolor(decDek, `hsl(${d3.hsl(piecewiseColor(decDek / 37)).h}` + slStr)
decDodOffHsl = textcolor(decDod, `hsl(${d3.hsl(piecewiseColor(decDod / 10)).h}` + slStr)
decTimeOffHsl0 = textcolor((decTimeOff * 10).toFixed(4), `hsl(${d3.hsl(piecewiseColor(decTimeOff)).h}` + slStr)
decTimeOffHsl1 = textcolor((decTimeOff * 10).toFixed(4), `hsl(${d3.hsl(piecewiseColor(decTimeOff)).h}` + slStr)
decTimeOffHsl2 = textcolor(decTimeOff.toFixed(5).slice(1), `hsl(${d3.hsl(piecewiseColor(decTimeOff)).h}` + slStr)
decTimeOffHsl3 = textcolor((decTimeOff * 100000).toFixed(0), `hsl(${d3.hsl(piecewiseColor(decTimeOff)).h}` + slStr)
dzP0 = unix2dote(now, 0)
ydzP0 = dote2date(...dzP0)
decYearP0 = ydzP0[0]
utcOffsetM = -(new Date).getTimezoneOffset()
utcOffsetD = utcOffsetM / 144
utcOffDiff = parseFloat((Math.round(utcOffsetD) - utcOffsetD).toFixed(2))
utcOffDiffHsl = textcolor(utcOffDiff, `hsl(${d3.hsl(piecewiseColor(utcOffDiff / 10)).h}` + slStr)
utcOffsetMdiffHsl = textcolor(parseFloat((utcOffDiff * 144).toFixed(2)), `hsl(${d3.hsl(piecewiseColor(utcOffDiff / 10)).h}` + slStr)
utcOffsetP = (utcOffsetD + 10) % 10
decZonHslP = textcolor(decZonePos, `hsl(${d3.hsl(piecewiseColor(decZonePos / 10)).h}` + slStr)
utcOffHslM = textcolor(utcOffsetM, `hsl(${d3.hsl(piecewiseColor(utcOffsetP / 10)).h}` + slStr)
utcOffHslD = textcolor(parseFloat(utcOffsetD.toFixed(2)), `hsl(${d3.hsl(piecewiseColor(utcOffsetP / 10)).h}` + slStr)
decLon = longitude % 10
decLonHsl = textcolor(parseFloat(decLon.toFixed(2)), `hsl(${d3.hsl(piecewiseColor(decLon / 10)).h}` + slStr)
decZon = Math.floor(decLon)
decZonHsl = textcolor(decZon, `hsl(${d3.hsl(piecewiseColor(decZon / 10)).h}` + slStr)
parLat = textcolor(parseFloat(latitude.toFixed(3)), `hsl(${d3.hsl(piecewiseColor((latitude + 1) % 1)).h}` + slStr)
parCos = Math.cos(latitude * 2 * Math.PI)
parLen = textcolor(parseFloat(parCos.toFixed(3)), `hsl(${d3.hsl(piecewiseColor(parCos)).h}` + slStr)
conversionFactor = costype === "turns" ? "" : costype === "radians" ?  tex`\,\tau\!` : tex`\times360`
zemsLeft = 1000 - 50 * Math.floor(now / 86400000 % 1 * 1000 % 1 * 100 % 21)
zLeft = textcolor(zemsLeft, `hsl(${d3.hsl(piecewiseColor(zemsLeft / 1000)).h}` + slStr)
point0long = long2turn(Place_A[0], 1)
point0zone = Math.floor(point0long)
point0lHsl = textcolor(parseFloat(point0long.toFixed(2)), `hsl(${d3.hsl(piecewiseColor(point0long / 10)).h}` + slStr)
point0zHsl = textcolor(point0zone, `hsl(${d3.hsl(piecewiseColor(point0zone / 10)).h}` + slStr)
isLeapOff = decYearOff % 4 == 0 && decYearOff % 100 != 0 || decYearOff % 400 == 0;
timezones = FileAttachment("../asset/timezones.json").json()
zones = topojson.feature(timezones, timezones.objects.timezones).features
mesh = topojson.mesh(timezones, timezones.objects.timezones)
color = d3.scaleSequential(d3.interpolateRdBu).domain([-12, 14])
coor = [[[-18, -89.98], [-18, 89.98], [18, 89.98], [18, -89.98], [-18, -89.98], ]]
deczones = [...Array(10).keys()].map(
  i => ({
    "type": "Feature",
    "geometry": {
      "type": "Polygon",
      "coordinates": [coor[0].map(t => [t[0]+36*i, t[1]])]
      },
    "properties": []
  })
)
// https://observablehq.com/@enjalot/draggable-world-map-coordinates-input
// https://observablehq.com/@christophe-yamahata/great-circle-shortest-distance-between-two-locations-on-ea
function worldMapCoordinates(config = {}, dimensions) {
  var n_point;
  var lonA, lonB, latA, latB;
  const {
    value = [], title, description, width = dimensions[0]
  } = Array.isArray(config) ? {value: config} : config;
  const height = dimensions[1];
  [lonA, latA] = value[0];
  [lonB, latB] = value[1];
  lonA = lonA != null ? lonA : 90;
  latA = latA != null ? latA : 0.025;
  lonB = lonB != null ? lonB : -90;
  latB = latB != null ? latB : 36;
  const formEl = html`<form style="width: ${width}px;"></form>`;
  const context = DOM.context2d(width, height);
  const canvas = context.canvas;
  const projection = config[2]
    .precision(0.1)
    .fitSize([width, height], { type: "Sphere" });
  const path = d3.geoPath(projection, context).pointRadius(2.5);
  formEl.append(canvas);
  function fillMesh(f) {
    context.beginPath();
    path(f);
    context.fillStyle = color(f.properties.zone);
    context.fill();
    context.innerHTML = `<title>${f.properties.places} ${f.properties.time_zone}</title>`;
  }
  function draw(lon0, lat0, lon1, lat1) {
    if (!utctoggle) {
      context.beginPath(); path({type: "Sphere"});
      context.fillStyle = window.darkmode ? "#007FFF" : mapcolors.ocean;
      context.fill();
      if (gridtoggle) {
        deczones.map((f, i) =>  {
          context.beginPath();
          path(f);
          context.fillStyle = hsla10[i];
          context.fill();
        })
      }
    }
    if (utctoggle) {
      zones.map(f => fillMesh(f))
    }
    context.beginPath();
    path(land);
    if (!utctoggle) {
      context.fillStyle = window.darkmode ? "#0808" : mapcolors.land;
      context.fill();
    }
    context.strokeStyle = `#000`;
    context.stroke();
    if (bordertoggle) {
      context.beginPath();
      path(borders);
      context.lineWidth = 1.25;
      context.strokeStyle = window.darkmode ? "#aaa" : "#333";
      context.stroke();
    }
    if (utctoggle) {
      context.beginPath();
      path(mesh);
      context.lineWidth = 1.25;
      context.strokeStyle = `#999`;
      context.stroke();
    }
    if (gridtoggle) {
      context.beginPath();
      path(graticule);
      context.lineWidth = 1.25;
      context.strokeStyle = utctoggle || !window.darkmode ? "#000" : "#fff";
      context.stroke();
      // context.font = width < 760 ? "12px serif" : "21px serif";
      // context.fillStyle = `#000`;
      // d3.range(-1.5, 342 + 1, 36).map(x =>  context.fillText(long2zone(x), ...projection([x, 27.5])));
      // d3.range(-1.5, 342 + 1, 36).map(x =>  context.fillText(long2zone(x), ...projection([x, -48])));
      // d3.range(-18, 336 + 1, 36).map(x => context.fillText(formatLongitude(x), ...projection([x, 90])));
      // d3.range(-18, 336 + 1, 36).map(x => context.fillText(formatLongitude(x), ...projection([x, -90])));
    }
    if (suntoggle) {
      context.beginPath();
      path(night);
      context.fillStyle = "rgba(0,0,255,0.3)";
      context.fill();
      context.beginPath();
      path.pointRadius(width / 84 + 5);
      path({type: "Point", coordinates: sun});
      context.strokeStyle = "#0009";
      context.fillStyle = "#ff0b";
      context.lineWidth = 1;
      context.stroke();
      context.fill();
    }
    if (lon0 != null && lat0 != null) {
      const pointPath = { type: "MultiPoint", coordinates: [[lon0, lat0]], id: "point0test"};
      context.beginPath();
      path.pointRadius(point_radius_2);
      path(pointPath);
      context.fillStyle = window.darkmode ? "#A24" : "#FDF";
      context.fill();
      context.strokeStyle = window.darkmode ? "white" : "black";
      context.stroke();
    }
    if (lon1 != null && lat1 != null) {
      const pointPath = { type: "MultiPoint", coordinates: [[lon1, lat1]] };
      context.beginPath();
      path.pointRadius(point_radius_2);
      path(pointPath);
      context.fillStyle = window.darkmode ? "#24B" : "#BFF";
      context.fill();
      context.strokeStyle = window.darkmode ? "white" : "black";
      context.stroke();
    }
    // We draw the path between 2 points
    var interpolation = d3.geoInterpolate([lon0,lat0],[lon1,lat1]);
    var nb_points =  d3.geoDistance([lon0,lat0],[lon1,lat1])*20;
    for(let i = 1; i<nb_points; i++) {
      const pointPath = { type: "MultiPoint", coordinates: [interpolation(i/nb_points)] };
      path.pointRadius(point_radius);
      context.beginPath(),
      context.fillStyle = window.darkmode ? "#FF420E" : "orange",
      path(pointPath),
      context.strokeStyle = window.darkmode ? "white" : "black";
      context.fill(),
      context.stroke();
    }
  }
  draw(lonA, latA, lonB, latB);
  canvas.onclick = function(ev) {
    const { offsetX, offsetY } = ev;
    var coords = projection.invert([offsetX, offsetY]);
    if(n_point==0){
    lonA = +coords[0].toFixed(2);
    latA = +coords[1].toFixed(2);
      n_point = 1;
    }else{
    lonB = +coords[0].toFixed(2);
    latB = +coords[1].toFixed(2);
      n_point = 0;
    }
    const point0bear = Math.round(lati2turn(coor2bear([lonA, latA], [lonB, latB])))
    set(viewof colorD, point0bear)
    table.rows[1].cells[1].innerHTML = createCellDiv(long2turn(lonA), 10)
    table.rows[2].cells[1].innerHTML = createCellDiv(long2turn(lonB), 10)
    table.rows[1].cells[2].innerHTML = createCellDiv(lati2turn(latA) % 250, 2.5)
    table.rows[2].cells[2].innerHTML = createCellDiv(lati2turn(latB) % 250, 2.5)
    table.rows[1].cells[3].innerHTML = createCellDiv(point0bear, 10)
    table.rows[2].cells[3].innerHTML = createCellDiv(lati2turn(coor2bear([lonB, latB], [lonA, latA])), 10)
    draw(lonA, latA, lonB, latB);
    canvas.dispatchEvent(new CustomEvent("input", { bubbles: true }));
  };
  function resetlatlon() {
    lonA = -90;
    latA = 0;
    lonB = -90;
    latB = 36;
    set(viewof bordertoggle, false);
    set(viewof gridtoggle, false);
    set(viewof suntoggle, false);
    set(viewof utctoggle, false);
    set(viewof yaw, 500);
    set(viewof pitch, 0);
    set(viewof roll, 0);
    set(viewof select, projections.find(t => t.name === "Equirectangular (plate carrée)"));
    set(viewof colorD, 0)
    set(viewof colorS, 1000)
    set(viewof colorL, 500)
    table.rows[1].cells[1].innerHTML = createCellDiv(800, 10)
    table.rows[2].cells[1].innerHTML = createCellDiv(800, 10)
    table.rows[1].cells[2].innerHTML = createCellDiv(0, 2.5)
    table.rows[2].cells[2].innerHTML = createCellDiv(100, 2.5)
    table.rows[1].cells[3].innerHTML = createCellDiv(0, 10)
    table.rows[2].cells[3].innerHTML = createCellDiv(500, 10)
    draw(lonA, latA, lonB, latB);
    canvas.dispatchEvent(new CustomEvent("input", { bubbles: true }));
  }
  table.onkeyup = function(ev) {
   if ([
    // https://www.freecodecamp.org/news/javascript-keycode-list-keypress-event-key-codes#heading-a-full-list-of-key-event-values
      9, 13, 27
    ].includes(ev.which)) {
      lonA = turn2long(liveTable[0].Milliparallel);
      latA = turn2degr(liveTable[0].Millimeridian % 250);
      lonB = turn2long(liveTable[1].Milliparallel);
      latB = turn2degr(liveTable[1].Millimeridian % 250);
      const point0bear = Math.round(lati2turn(coor2bear([lonA, latA], [lonB, latB])))
      set(viewof colorD, point0bear)
      table.rows[1].cells[1].innerHTML = createCellDiv(long2turn(lonA), 10)
      table.rows[2].cells[1].innerHTML = createCellDiv(long2turn(lonB), 10)
      table.rows[1].cells[2].innerHTML = createCellDiv(lati2turn(latA) % 250, 2.5)
      table.rows[2].cells[2].innerHTML = createCellDiv(lati2turn(latB) % 250, 2.5)
      table.rows[1].cells[3].innerHTML = createCellDiv(point0bear, 10)
      table.rows[2].cells[3].innerHTML = createCellDiv(lati2turn(coor2bear([lonB, latB], [lonA, latA])), 10)
      draw(lonA, latA, lonB, latB);
      canvas.dispatchEvent(new CustomEvent("input", { bubbles: true }));
    } else if ([
    // https://www.freecodecamp.org/news/javascript-keycode-list-keypress-event-key-codes#heading-a-full-list-of-key-event-values
      8, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 109, 189
    ].includes(ev.which)) {
      lonA = turn2long(liveTable[0].Milliparallel);
      latA = turn2degr(liveTable[0].Millimeridian % 250);
      lonB = turn2long(liveTable[1].Milliparallel);
      latB = turn2degr(liveTable[1].Millimeridian % 250);
      const point0bear = Math.round(lati2turn(coor2bear([lonA, latA], [lonB, latB])))
      set(viewof colorD, point0bear)
      table.rows[1].cells[3].innerHTML = createCellDiv(point0bear, 10)
      table.rows[2].cells[3].innerHTML = createCellDiv(lati2turn(coor2bear([lonB, latB], [lonA, latA])), 10)
      draw(lonA, latA, lonB, latB);
      canvas.dispatchEvent(new CustomEvent("input", { bubbles: true }));
    }
  }
  rstbtn.on('click', resetlatlon);
  document.getElementsByClassName("quarto-color-scheme-toggle")[0].onclick = function (e) {
    window.quartoToggleColorScheme();
    window.darkmode = document.getElementsByTagName("body")[0].className.match(/quarto-dark/) ? true : false;
    draw(lonA, latA, lonB, latB);
    return false;
  };
  const form = input({
    type: "worldMapCoordinates",
    title,
    description,
    display: v => "",
     // html`<div style="width: ${width}px; white-space: nowrap; color: #444; text-align: center; font: 13px sans-serif; margin-bottom: 5px;">
     //       <span style="color: ${color_A}">Longitude: ${lonA != null ? lonA.toFixed(2) : ""}</span>
     //       &nbsp; &nbsp;
     //       <span style="color: ${color_A}">Latitude: ${latA != null ? latA.toFixed(2) : ""} </span>
     //     </div>
     //     <div style="width: ${width}px; white-space: nowrap; color: #444; text-align: center; font: 13px sans-serif; margin-bottom: 5px;">
     //       <span style="color: ${color_B}">Longitude: ${lonB != null ? lonB.toFixed(2) : ""}</span>
     //       &nbsp; &nbsp;
     //       <span style="color: ${color_B}">Latitude: ${latB != null ? latB.toFixed(2) : ""}</span>
     //     </div>`,
    getValue: () => [[lonA != null ? lonA : null, latA != null ? latA : null], [lonB != null ? lonB : null, latB != null ? latB : null]],
    form: formEl
  });
  return form;
}
point_radius = width / 900 * mapsize / 100 + 3
point_radius_2 = width / 150 * mapsize / 100 + 3
Place_A = coordinates[0]
Place_B = coordinates[1]
distance_km = (d3.geoDistance(Place_A, Place_B)* 6371).toFixed(0)
distance_mc = distance_km / 40
distance_mcHsl0 = textcolor(parseFloat(distance_mc.toFixed(0)), `hsl(${d3.hsl(piecewiseColor(distance_mc % 1000 / 1000)).h}` + slStr)
distance_mcHsl1 = textcolor(parseFloat(distance_mc.toFixed(0)), `hsl(${d3.hsl(piecewiseColor(distance_mc % 1000 / 1000)).h}` + slStr)
distance_c = distance_mc / 1000
distance_cHsl = textcolor(parseFloat(distance_c.toFixed(3)), `hsl(${d3.hsl(piecewiseColor(distance_c % 1)).h}` + slStr)
velocity_v = travelspeed / 1000
velocity_vHsl0 = textcolor(parseFloat(velocity_v.toFixed(3)), `hsl(${d3.hsl(piecewiseColor(velocity_v)).h}` + slStr)
velocity_vHsl1 = textcolor(parseFloat(velocity_v.toFixed(3)), `hsl(${d3.hsl(piecewiseColor(velocity_v)).h}` + slStr)
velocity_mvHsl = textcolor(parseFloat(travelspeed.toFixed(0)), `hsl(${d3.hsl(piecewiseColor(travelspeed / 1000)).h}` + slStr)
traveltime = Math.round(distance_mc) / Math.round(travelspeed)
traveltimeHsl0 = Number.isFinite(traveltime) ? textcolor(parseFloat(Math.round(traveltime * 1000).toFixed(3)), `hsl(${d3.hsl(piecewiseColor(traveltime % 1)).h}` + slStr) : traveltime
traveltimeHsl1 = Number.isFinite(traveltime) ? textcolor(parseFloat(traveltime.toFixed(3)), `hsl(${d3.hsl(piecewiseColor(traveltime % 1)).h}` + slStr) : traveltime
nb_points = Math.round(distance_km/150)
d3format = require("d3-format@1")
function input(config) {
  let {
    form,
    type = "text",
    attributes = {},
    action,
    getValue,
    title,
    description,
    format,
    display,
    submit,
    options
  } = config;
  const wrapper = html`<div></div>`;
  if (!form)
    form = html`<form>
    <input name=input type=${type} />
  </form>`;
  Object.keys(attributes).forEach(key => {
    const val = attributes[key];
    if (val != null) form.input.setAttribute(key, val);
  });
  if (submit)
    form.append(
      html`<input name=submit type=submit style="margin: 0 0.75em" value="${
        typeof submit == "string" ? submit : "Submit"
      }" />`
    );
  form.append(
    html`<output name=output style="font: 14px Menlo, Consolas, monospace; margin-left: 0.5em;"></output>`
  );
  if (title)
    form.prepend(
      html`<div style="font: 700 0.9rem sans-serif; margin-bottom: 3px;">${title}</div>`
    );
  if (description)
    form.append(
      html`<div style="font-size: 0.85rem; font-style: italic; margin-top: 3px;">${description}</div>`
    );
  if (format)
    format = typeof format === "function" ? format : d3format.format(format);
  if (action) {
    action(form);
  } else {
    const verb = submit
      ? "onsubmit"
      : type == "button"
      ? "onclick"
      : type == "checkbox" || type == "radio"
      ? "onchange"
      : "oninput";
    form[verb] = e => {
      e && e.preventDefault();
      const value = getValue ? getValue(form.input) : form.input.value;
      if (form.output) {
        const out = display ? display(value) : format ? format(value) : value;
        if (out instanceof window.Element) {
          while (form.output.hasChildNodes()) {
            form.output.removeChild(form.output.lastChild);
          }
          form.output.append(out);
        } else {
          form.output.value = out;
        }
      }
      form.value = value;
      if (verb !== "oninput")
        form.dispatchEvent(new CustomEvent("input", { bubbles: true }));
    };
    if (verb !== "oninput")
      wrapper.oninput = e => e && e.stopPropagation() && e.preventDefault();
    if (verb !== "onsubmit") form.onsubmit = e => e && e.preventDefault();
    form[verb]();
  }
  while (form.childNodes.length) {
    wrapper.appendChild(form.childNodes[0]);
  }
  form.append(wrapper);
  return form;
}
// https://observablehq.com/@fil/d3-projections
projections = [
  { name: "Airocean", value: d3.geoAirocean },
  { name: "Airy’s minimum error", value: d3.geoAiry },
  { name: "Aitoff", value: d3.geoAitoff },
  { name: "American polyconic", value: d3.geoPolyconic },
  { name: "Armadillo", value: d3.geoArmadillo, options: { clip: { type: "Sphere" } } },
  { name: "August", value: d3.geoAugust },
  { name: "azimuthal equal-area", value: d3.geoAzimuthalEqualArea },
  { name: "azimuthal equidistant", value: d3.geoAzimuthalEquidistant },
  { name: "Baker dinomic", value: d3.geoBaker },
  { name: "Berghaus’ star", value: d3.geoBerghaus, options: { clip: { type: "Sphere" } } },
  { name: "Bertin’s 1953", value: d3.geoBertin1953 },
  { name: "Boggs’ eumorphic", value: d3.geoBoggs },
  { name: "Boggs’ eumorphic (interrupted)", value: d3.geoInterruptedBoggs, options: { clip: { type: "Sphere" } } },
  { name: "Bonne", value: d3.geoBonne },
  { name: "Bottomley", value: d3.geoBottomley },
  { name: "Bromley", value: d3.geoBromley },
  { name: "Butterfly (gnomonic)", value: d3.geoPolyhedralButterfly },
  { name: "Butterfly (Collignon)", value: d3.geoPolyhedralCollignon },
  { name: "Butterfly (Waterman)", value: d3.geoPolyhedralWaterman },
  { name: "Cahill-Keyes", value: d3.geoCahillKeyes },
  { name: "Collignon", value: d3.geoCollignon },
  { name: "conic equal-area", value: d3.geoConicEqualArea },
  { name: "conic equidistant", value: d3.geoConicEquidistant },
  { name: "Craig retroazimuthal", value: d3.geoCraig },
  { name: "Craster parabolic", value: d3.geoCraster },
  { name: "Cox", value: d3.geoCox },
  { name: "cubic", value: d3.geoCubic },
  { name: "cylindrical equal-area", value: d3.geoCylindricalEqualArea },
  { name: "cylindrical stereographic", value: d3.geoCylindricalStereographic },
  { name: "dodecahedral", value: d3.geoDodecahedral },
  { name: "Eckert I", value: d3.geoEckert1 },
  { name: "Eckert II", value: d3.geoEckert2 },
  { name: "Eckert III", value: d3.geoEckert3 },
  { name: "Eckert IV", value: d3.geoEckert4 },
  { name: "Eckert V", value: d3.geoEckert5 },
  { name: "Eckert VI", value: d3.geoEckert6 },
  { name: "Eisenlohr conformal", value: d3.geoEisenlohr },
  { name: "Equal Earth", value: d3.geoEqualEarth },
  { name: "Equirectangular (plate carrée)", value: d3.geoEquirectangular },
  { name: "Fahey pseudocylindrical", value: d3.geoFahey },
  { name: "flat-polar parabolic", value: d3.geoMtFlatPolarParabolic },
  { name: "flat-polar quartic", value: d3.geoMtFlatPolarQuartic },
  { name: "flat-polar sinusoidal", value: d3.geoMtFlatPolarSinusoidal },
  { name: "Foucaut’s stereographic equivalent", value: d3.geoFoucaut },
  { name: "Foucaut’s sinusoidal", value: d3.geoFoucautSinusoidal },
  { name: "general perspective", value: d3.geoSatellite },
  { name: "Gingery", value: d3.geoGingery, options: { clip: { type: "Sphere" } } },
  { name: "Ginzburg V", value: d3.geoGinzburg5 },
  { name: "Ginzburg VI", value: d3.geoGinzburg6 },
  { name: "Ginzburg VIII", value: d3.geoGinzburg8 },
  { name: "Ginzburg IX", value: d3.geoGinzburg9 },
  { name: "Goode’s homolosine", value: d3.geoHomolosine},
  { name: "Goode’s homolosine (interrupted)", value: d3.geoInterruptedHomolosine, options: { clip: { type: "Sphere" } }  },
  { name: "gnomonic", value: d3.geoGnomonic },
  { name: "Gringorten square", value: d3.geoGringorten },
  { name: "Gringorten quincuncial", value: d3.geoGringortenQuincuncial },
  { name: "Guyou square", value: d3.geoGuyou },
  { name: "Hammer", value: d3.geoHammer },
  { name: "Hammer retroazimuthal", value: d3.geoHammerRetroazimuthal, options: { clip: { type: "Sphere" } } },
  { name: "HEALPix", value: d3.geoHealpix, options: { clip: { type: "Sphere" } } },
  { name: "Hill eucyclic", value: d3.geoHill },
  { name: "Hufnagel pseudocylindrical", value: d3.geoHufnagel },
  { name: "icosahedral", value: d3.geoIcosahedral },
  { name: "Imago", value: d3.geoImago },
  { name: "Kavrayskiy VII", value: d3.geoKavrayskiy7 },
  { name: "Lagrange conformal", value: d3.geoLagrange },
  { name: "Larrivée", value: d3.geoLarrivee },
  { name: "Laskowski tri-optimal", value: d3.geoLaskowski },
  { name: "Loximuthal", value: d3.geoLoximuthal },
  { name: "Mercator", value: d3.geoMercator },
  { name: "Miller cylindrical", value: d3.geoMiller },
  { name: "Mollweide", value: d3.geoMollweide },
  { name: "Mollweide (Goode’s interrupted)", value: d3.geoInterruptedMollweide, options: { clip: { type: "Sphere" } } },
  { name: "Mollweide (interrupted hemispheres)", value: d3.geoInterruptedMollweideHemispheres, options: { clip: { type: "Sphere" } } },
  { name: "Natural Earth", value: d3.geoNaturalEarth1 },
  { name: "Natural Earth II", value: d3.geoNaturalEarth2 },
  { name: "Nell–Hammer", value: d3.geoNellHammer },
  { name: "Nicolosi globular", value: d3.geoNicolosi },
  { name: "orthographic", value: d3.geoOrthographic },
  { name: "Patterson cylindrical", value: d3.geoPatterson },
  { name: "Peirce quincuncial", value: d3.geoPeirceQuincuncial },
  { name: "rectangular polyconic", value: d3.geoRectangularPolyconic },
  { name: "Robinson", value: d3.geoRobinson },
  { name: "sinusoidal", value: d3.geoSinusoidal },
  { name: "sinusoidal (interrupted)", value: d3.geoInterruptedSinusoidal, options: { clip: { type: "Sphere" } } },
  { name: "sinu-Mollweide", value: d3.geoSinuMollweide },
  { name: "sinu-Mollweide (interrupted)", value: d3.geoInterruptedSinuMollweide, options: { clip: { type: "Sphere" } } },
  { name: "stereographic", value: d3.geoStereographic },
  { name: "Lee’s tetrahedal", value: d3.geoTetrahedralLee },
  { name: "Times", value: d3.geoTimes },
  { name: "Tobler hyperelliptical", value: d3.geoHyperelliptical },
  { name: "transverse Mercator", value: d3.geoTransverseMercator },
  { name: "Van der Grinten", value: d3.geoVanDerGrinten },
  { name: "Van der Grinten II", value: d3.geoVanDerGrinten2 },
  { name: "Van der Grinten III", value: d3.geoVanDerGrinten3 },
  { name: "Van der Grinten IV", value: d3.geoVanDerGrinten4 },
  { name: "Wagner IV", value: d3.geoWagner4 },
  { name: "Wagner VI", value: d3.geoWagner6 },
  { name: "Wagner VII", value: d3.geoWagner7 },
  { name: "Werner", value: d3.geoBonne ? () => d3.geoBonne().parallel(90) : null },
  { name: "Wiechel", value: d3.geoWiechel },
  { name: "Winkel tripel", value: d3.geoWinkel3 }
]
mapcolors = ({
  night: "#719fb6",
  day: "#ffe438",
  grid: "#4b6a79",
  ocean: "#adeeff",
  land: "#90ff7888",
  sun: "#ffb438"
})
function long2turn(degrees = -180, e = 3) {
  // turns: e=0, deciturns: e=1, etc.
  return (((degrees %= 360) < 0 ? degrees + 360 : degrees) + 18) / (360 / 10**e) % 10**e;
}
function turn2degr(turns = -500, e = 3) {
  // turns: e=0, deciturns: e=1, etc.
  return turns % 10**e * (360 / 10**e)
}
function turn2long(turns = -500, e = 3) {
  // turns: e=0, deciturns: e=1, etc.
  return turns % 10**e * (360 / 10**e) - 18
}
function long2zone(degrees = -180) { return Math.floor(long2turn(degrees, 1)); }
function lati2turn(degrees = -180, e = 3) {
  // turns: e=0, deciturns: e=1, etc.
  return (degrees %= 360) / (360 / 10**e) % 10**e;
}
selectedProjection = select ? select.value() : d3.geoEquirectangular()
projection = {
  let proj = selectedProjection;
  if (proj.rotate) proj.rotate([-turn2long(yaw), -turn2degr(pitch), turn2degr(roll)]);
  return proj;
}
sun = {
  const now = new Date;
  const day = new Date(+now).setUTCHours(0, 0, 0, 0);
  const t = solar.century(now);
  const longitude = (day - now) / 864e5 * 360 - 180;
  return [longitude - solar.equationOfTime(t) / 4, solar.declination(t)];
}
sunLon = Math.round(long2turn(sun[0]))
sunLat = Math.round(lati2turn(sun[1]))
night = d3.geoCircle().radius(90).center(antipode(sun))()
antipode = ([longitude, latitude]) => [longitude + 180, -latitude]
height = {
  const [[x0, y0], [x1, y1]] = d3.geoPath(projection.fitWidth(width, sphere)).bounds(sphere);
  const dy = Math.ceil(y1 - y0), l = Math.min(Math.ceil(x1 - x0), dy);
  projection.scale(projection.scale() * (l - 1) / l).precision(0.2);
  return dy;
}
d3 = require("d3@5", "d3-array@3", "d3-geo@3", "d3-geo-projection@4", "d3-geo-polygon@1.8")
sphere = ({type: "Sphere"})
graticule = d3.geoGraticule().stepMinor([36, 36]).stepMajor([36, 36])()
graticule.coordinates = graticule.coordinates.map(
  i => i.map(j => j.map((k, index, arr) => i.length === 3 && index === 0 ? k - 18 : k))
)
land = topojson.feature(world, world.objects.land)
world = fetch("https://cdn.jsdelivr.net/npm/world-atlas@2/land-50m.json").then(response => response.json())
topojson = require("topojson-client@3")
solar = require("solar-calculator@0.3/dist/solar-calculator.min.js")
borders = topojson.mesh(countries, countries.objects.countries, (a, b) => a !== b)
countries = fetch("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-50m.json").then(response => response.json())
deccolors = [
  `hsl(20${slStr}`,
  `hsl(24${slStr}`,
  `hsl(28${slStr}`,
  `hsl(36${slStr}`,
  `hsl(44${slStr}`,
  `hsl(48${slStr}`,
  `hsl(52${slStr}`,
  `hsl(60${slStr}`,
  `hsl(64${slStr}`,
  `hsl(68${slStr}`,
  `hsl(72${slStr}`,
  `hsl(80${slStr}`,
  `hsl(88${slStr}`,
  `hsl(92${slStr}`,
  `hsl(96${slStr}`,
  `hsl(120${slStr}`,
  `hsl(148${slStr}`,
  `hsl(156${slStr}`,
  `hsl(164${slStr}`,
  `hsl(180${slStr}`,
  `hsl(192${slStr}`,
  `hsl(196${slStr}`,
  `hsl(200${slStr}`,
  `hsl(208${slStr}`,
  `hsl(216${slStr}`,
  `hsl(220${slStr}`,
  `hsl(224${slStr}`,
  `hsl(240${slStr}`,
  `hsl(260${slStr}`,
  `hsl(264${slStr}`,
  `hsl(268${slStr}`,
  `hsl(276${slStr}`,
  `hsl(284${slStr}`,
  `hsl(288${slStr}`,
  `hsl(292${slStr}`,
  `hsl(300${slStr}`,
  `hsl(320${slStr}`,
  `hsl(328${slStr}`,
  `hsl(336${slStr}`,
  `hsl(0${slStr}`,
]
viewof size = Inputs.range([50, 700], {
  value: 300,
  step: 20,
  label: 'size'
})
viewof numMajorTicks = Inputs.range([0, 45], {
  value: 6,
  step: 2,
  label: "Major ticks"
})
viewof numMinorTicks = Inputs.range([0, 10], {
  value: 2,
  step: 1,
  label: "Minor ticks"
})
function repeat(component, N, initialAngle=0) {
  // NOTE: if component is a function, it will be called with (angle, i)
  if (N <= 0) return "";
  let result = [];
  for (let i = 0; i < N; i++) {
    let angle = (360 / N) * i + initialAngle;
    let el = typeof component === 'function'? component(angle, i) : component;
    result.push(`<g transform="rotate(${angle})">${el}</g>`);
  }
  return result.join("");
}
function tick(radius, length, color='black') {
  return `<path d="M 0,${-radius} l 0,${-length}" fill="none" stroke="${color}" stroke-width="1" />`;
}
function directionMarker(radius, fontSize) { return (angle, _) => {
  let label = {0: 'N', 45: 'NE', 90: 'E', 135: 'SE', 180: 'S', 225: 'SW', 270: 'W', 315: 'NW'}[angle] ?? '??';
  return `<text y="${-radius-(margin/2)}" font-size="${fontSize}" text-anchor="middle" dy=".36em">${label}</text>`;
};
}
function turnMarker(radius, fontSize) { return (angle, _) => {
  let label = {0: '0', 45: '125', 90: '250', 135: '375', 180: '500', 225: '625', 270: '750', 315: '875'}[angle] ?? '??';
  return `<text y="${-radius-(margin/2)}" font-size="${fontSize}" text-anchor="middle" dy="-0.36em">${label}</text>`;
  };
}
function pie(radius, width, narrowness=1.0, piecolors) {
  return (_, i) => `<path id="piepath" d="M 0,0 L ${-width},${-radius} A ${width} ${width/2} 0 0 1 ${width} ${-radius} z" fill="${piecolors[i]}" stroke="black" stroke-width="0.5"/>`;
}
margin = size / 14
padding = 42
radius = size / 2 - margin - padding
window.darkmode = document.getElementsByTagName("body")[0].className.match(/quarto-dark/) ? true : false;
function displayPalette(palette, { darkMode = false } = {}) {
  return htl.html`
  <div style="display: flex; flex-direction: column;">
    <div style="margin-bottom:8px;">${cielabScatter(palette, { darkMode: darkMode })}</div>
    <div style="display: flex; flex-direction: row; align-items: center; justify-content: space-evenly;">
      <div style="">${lightnessSpectrum(palette, { darkMode: darkMode })}</div>
      <div>${swatches(palette)}</div>
  </div></div>
</div>`
}
paletteDots = function(palette, { darkMode = false } = {}) {
  return Plot.plot( {
    marks: [
      Plot.dot(palette, {
        x: (d,i) => i * 36,
        r: 16,
        fill: { value: (d) => d, label: "Color" },
        stroke: darkMode ? "white" : "#202020" ,
        tip: {
          format: { x: false },
          fill: darkMode ? "#202020" : "white"
        }
      }),
      Plot.text(palette.map((d,i) => i), {
        x: (d) => d * 36,
        dx: 18,
        dy: 16,
        opacity: 0.8
      }),
    ],
    x: { domain: [ 0, 320 ], ticks: 0 },
    height: 48,
    width: (palette.length) * 40,
    marginTop: 16,
    style: { fontSize: 18, overflow: "visible" }
    })
}
function cielabScatter(palette, { darkMode = false } = {}) {
  let labPalette = palette.map((c,i)=>({...d3.lab(c), i, color: c, ...({})}));
  return Plot.plot({
    width: colorsize,
    height: colorsize,
    style: { fontSize: 12 },
    marks: [
      Plot.frame({rx: size / 2, ry: size / 2, opacity: 0.2}),
      Plot.gridX({ticks: 3, opacity: 0.2}),
      Plot.gridY({ticks: 3, opacity: 0.2}),
      Plot.ruleX([0], {opacity: 0.25}),
      Plot.ruleY([0], {opacity: 0.25}),
      Plot.dot(labPalette, {
        x: "a", y: "b", r: 5,
        fill: { value: (d) => d.color, label: "Color" },
        channels: {
          L: { value: "l", label: "L*" }
        },
        tip: {
          format: { fill: (d,i) => `${i}` },
          fill: "#202020",
        }
      }),
    ],
    x: {
      domain: [-80, 80],
      ticks: 3,
      tickSize: 0,
      labelArrow: null,
      labelAnchor: "center",
      label: "a*"
    },
    y: {
      domain: [-80, 80],
      ticks: 3,
      tickRotate: 0,
      tickSize: 0,
      labelArrow: null,
      labelAnchor: "center",
      label: "b*"
    }
  });
}
function lightnessSpectrum(palette, { darkMode = false } = {}) {
  let labPalette = palette.map((c,i)=>({...d3.lab(c), i, color: c, ...({})}));
  return Plot.plot({
    height: colorsize,
    width: 70,
    style: { fontSize: 12, overflow: "visible" }, // let the tip overflow the rect of the plot
    marks: [
      Plot.tickY( labPalette, {
        y: (d) => d.l,
        stroke: { value: (d) => d.color, label: "Color" },
        strokeWidth: 3,
        tip: {
          anchor: "right",
          frameAnchor: "left",
          format: {
            fontSize: 12,
            stroke: (d,i) => `${i}`,
            a: true, b: true
          },
          fill: "#202020"
        },
        channels: {
          a: { value: "a", label: "a*" },
          b: { value: "b", label: "b*" }
        },
      })
    ],
    y: {
      domain: [30, 100],
      grid: true,
      tickSize: 0,
      labelAnchor: "center",
      label: "L*",
      labelArrow: false
    },
  })
}
function swatches(palette) {
  return Plot.plot({
    height: colorsize,
    width: 50,
    x: {ticks: 0},
    margin: 0,
    marks: [
      Plot.barX(
        palette, {
          y: (d,i) => i,
          fill: (d) => d,
          inset: -1
        }
      )
    ]
})}
colorsize = 210
kg = parseFloat(kilograms.toFixed(2))
zem2 = parseFloat((zems**2).toFixed(2))
bmi = parseFloat((kilograms / zems**2).toFixed(2))
bmim2 = parseFloat((bmi * 25 / 4).toFixed(2))
bmiStr = bmi < 2.96 ? "underweight" : bmi < 4 ? "normal" : bmi < 4.8 ? "overweight" : "obese"
// https://observablehq.com/@magfoto/wavelengths-and-spectral-colours
// takes wavelength in nm and returns an rgba value
    function wavelengthToColor(wavelength) {
        let R,
            G,
            B,
            alpha,
            colorSpace,
            wl = wavelength,
            gamma = 1;
        if (wl >= 380 && wl < 440) {
            R = -1 * (wl - 440) / (440 - 380);
            G = 0;
            B = 1;
       } else if (wl >= 440 && wl < 490) {
           R = 0;
           G = (wl - 440) / (490 - 440);
           B = 1;
        } else if (wl >= 490 && wl < 510) {
            R = 0;
            G = 1;
            B = -1 * (wl - 510) / (510 - 490);
        } else if (wl >= 510 && wl < 580) {
            R = (wl - 510) / (580 - 510);
            G = 1;
            B = 0;
        } else if (wl >= 580 && wl < 645) {
            R = 1;
            G = -1 * (wl - 645) / (645 - 580);
            B = 0.0;
        } else if (wl >= 645 && wl <= 780) {
            R = 1;
            G = 0;
            B = 0;
        } else {
            R = 0;
            G = 0;
            B = 0;
        }
        // intensty is lower at the edges of the visible spectrum.
        if (wl > 780 || wl < 380) {
            alpha = 0;
        } else if (wl > 700) {
            alpha = (780 - wl) / (780 - 700);
        } else if (wl < 420) {
            alpha = (wl - 380) / (420 - 380);
        } else {
            alpha = 1;
        }
        colorSpace = ["rgba(" + (R * 100) + "%," + (G * 100) + "%," + (B * 100) + "%, " + alpha + ")", R, G, B, alpha]
        // colorSpace is an array with 5 elements.
        // The first element is the complete code as a string.
        // Use colorSpace[0] as is to display the desired color.
        // Use the last four elements alone or together to access each of the individual r, g, and b channels.
        return colorSpace;
    }
// https://observablehq.com/@freedmand/sounds
function piano(stlibWidth) {
  const width = 960;
  const keyHeight = 450;
  const height = 575;
  const whiteKeys = 11;
  const blackKeys = [1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1];
  const whiteOffsets = blackKeys.reduce((x, y) => x.concat([y + x[x.length - 1] + 1]), [0]);
  const svg = html`<svg width="100%" height="auto" viewBox="0 0 ${width} ${height}"
    xmlns="http://www.w3.org/2000/svg"></svg>`;
  function wrap(elem, note) {
    const freq = 440 * Math.pow(2, note / 12);
    // Play a note when clicked.
    const oscillator = ctx.createOscillator();
    const gain = ctx.createGain();
    gain.gain.value = 0;
    oscillator.type = 'square';
    oscillator.frequency.setValueAtTime(freq, ctx.currentTime);
    oscillator.connect(gain);
    gain.connect(ctx.destination);
    oscillator.start();
    elem.style.cursor = 'pointer';
    elem.onclick = () => {
      gain.gain.cancelScheduledValues(ctx.currentTime);
      gain.gain.linearRampToValueAtTime(0.1, ctx.currentTime + 0.05);
      gain.gain.linearRampToValueAtTime(0, ctx.currentTime + 0.3);
    };
    return elem;
  }
  // Draw the white keys.
  for (let i = 0; i <= whiteKeys - 1; i++) {
    svg.appendChild(wrap(html`<svg><rect x="${width * i / whiteKeys}" y="0" width="${width / whiteKeys}" height="${keyHeight}" fill=${whiteKeyColors[i]} stroke="black" stroke-width="2"/></svg>`, whiteOffsets[i] - 4));
    svg.appendChild(html`<svg><text style="user-select: none;" x="${width * (i + 0.5) / whiteKeys}" y="${keyHeight + 42}" font-family="monospace" id="pianotext" font-size="36" text-anchor="middle">${String.fromCharCode('A'.charCodeAt(0) + (i + 5) % 7) + (i < 4 ? "3" : "4")}</text></svg>`);
    svg.appendChild(html`<svg><text style="user-select: none;" x="${width * (i + 0.5) / whiteKeys}" y="${keyHeight + 82}" font-family="monospace" id="pianotext" font-size="36" text-anchor="middle">${Math.round(220 * Math.pow(2, (whiteOffsets[i] - 4) / 12) * .864)}</text></svg>`);
    svg.appendChild(html`<svg><text style="user-select: none;" x="${width * (i + 0.5) / whiteKeys}" y="${keyHeight + 122}" font-family="monospace" id="pianotext" font-size="36" text-anchor="middle">${Math.round(73504.8 / (220 * Math.pow(2, (whiteOffsets[i] - 4) / 12) * .864))}</text></svg>`);
  }
  // Draw the black keys.
  for (let i = 0; i <= whiteKeys - 2; i++) {
    if (blackKeys[i] == 1) {
      svg.appendChild(wrap(html`<svg><rect x="${width * ((i + 0.65) / whiteKeys)}" y="0" width="${width / whiteKeys * 0.7}" height="${keyHeight * 0.55}" fill=${blackKeyColors[i]} stroke="black" stroke-width="2"/></svg>`, whiteOffsets[i] - 4 + blackKeys[i]));
    }
  }
  return svg;
}
whiteKeyColors = [
  "#fff",
  "#fff",
  "#fff",
  xetHex[1],
  xetHex[2],
  xetHex[4],
  xetHex[6],
  xetHex[7],
  xetHex[9],
  xetHex[11],
  "#fff",
  "#fff",
  "#fff",
]
blackKeyColors = [
  "#000",
  "#000",
  xetHex[0],
  "",
  xetHex[3],
  xetHex[5],
  "",
  xetHex[8],
  xetHex[10],
  "#000",
  "#000",
  "#000",
]
// https://observablehq.com/@freedmand/sounds
ctx = new (window.AudioContext || window.webkitAudioContext)()
function Play(genFn, duration = 1) {
  return new SoundBuffer(genFn, duration).gui();
}
class SoundBuffer {
  constructor(genFn, duration = .864) {
    this.duration = duration;
    // Create an audio buffer.
    this.audioBuffer = ctx.createBuffer(1, ctx.sampleRate * this.duration, ctx.sampleRate);
    this.buffer = this.audioBuffer.getChannelData(0);
    let max = 0;
    for (let i = 0; i < this.audioBuffer.length; i++) {
      const value = genFn(i / ctx.sampleRate);
      this.buffer[i] = value;
      if (Math.abs(value) > max) max = Math.abs(value);
    }
    for (let i = 0; i < this.audioBuffer.length; i++) {
      this.buffer[i] = this.buffer[i] / max;
    }
  }
  play(maxVol = 0.3) {
    this.stop();
    this.source = ctx.createBufferSource();
    this.source.buffer = this.audioBuffer;
    const gain = ctx.createGain();
    gain.gain.value = maxVol;
    this.source.connect(gain);
    gain.connect(ctx.destination);
    this.source.start();
  }
  stop() {
    if (this.source) this.source.stop();
  }
  draw(height = 50, width = width, color = 'blue') {
    const drawingCtx = DOM.context2d(width, height);
    // Draw the middle line.
    drawingCtx.strokeStyle = 'gainsboro';
    drawingCtx.beginPath();
    drawingCtx.moveTo(0, height / 2);
    drawingCtx.lineTo(width, height / 2);
    drawingCtx.stroke();
    // Draw the waveform.
    drawingCtx.strokeStyle = color;
    drawingCtx.beginPath();
    for (let i = 0; i < width; i++) {
      const value = this.buffer[Math.floor(i / width * this.audioBuffer.length)];
      const y = height - Math.floor((value / 2 + 0.5) * height * 0.9 + height * 0.05);
      if (i == 0) {
        drawingCtx.moveTo(i, y);
      } else {
        drawingCtx.lineTo(i, y);
      }
    }
    drawingCtx.stroke();
    return drawingCtx.canvas;
  }
  gui() {
    const ui = html`<style>
      .sound-player {
        border: solid 1px gainsboro;
        background: #f5f5f5;
        font-family: sans-serif;
        color: #6f6f6f;
        font-size: 0.8em;
      }
      .sound-pane {
        height: 50px;
        background: white;
        margin: 8px;
        border: solid 1px gainsboro;
        position: relative;
      }
      .icons {
        margin: 0 8px 8px 8px;
      }
      .icons .button {
         cursor: pointer;
         border: solid 1px transparent;
      }
      .icons .button:hover {
         border: solid 1px gainsboro;
      }
      .cursor {
        background: red;
        width: 2px;
        height: 100%;
        position: absolute;
      }
    </style>
    <div class="sound-player">
      <div class="sound-pane">
        <span class="cursor" style="display: none;"></span>
      </div>
      <div class="icons">
        <span class="button play-button" style="font-size:18px;">▶</span>
        <span class="button stop-button" style="font-size:18px;">◼</span>&nbsp;&nbsp;
        <span class="duration">${Math.round(this.duration / .864)} b</span>
      </div>
    </div>`;
    const cursor = ui.querySelector('.cursor');
    let interval = null;
    const resetInterval = () => {
      if (interval != null) {
        clearInterval(interval);
        interval = null;
      }
    };
    const soundPlayer = ui.querySelector('.sound-player');
    ui.querySelector('.sound-pane').appendChild(this.draw(46, width - 20));
    ui.querySelector('.play-button').onclick = () => {
      cursor.style.left = '0';
      this.play();
      cursor.style.display = 'block';
      const playTime = Date.now();
      resetInterval();
      interval = setInterval(() => {
        if (!document.contains(soundPlayer)) {
          resetInterval();
          this.stop();
        }
        let progress = (Date.now() - playTime) / this.duration / 1000;
        if (progress < 0) progress = 0;
        if (progress > 1) {
          progress = 1;
          resetInterval();
          this.stop();
          cursor.style.display = 'none';
        }
        cursor.style.left = `${Math.floor(progress * (width - 20))}px`;
      }, 20);
    };
    ui.querySelector('.stop-button').onclick = () => {
      resetInterval();
      this.stop();
      cursor.style.display = 'none';
    };
    return ui;
  }
}
function shortenHex(hex) {
  if (!/^#([0-9a-f]{3}){1,2}$/i.test(hex)) {
    return hex;
  }
  hex = hex.replace("#", "");
  if (hex.length === 6 && hex[0] === hex[1] && hex[2] === hex[3] && hex[4] === hex[5]) {
    return "#" + hex[0] + hex[2] + hex[4];
  }
  return "#" + hex;
}
dtHex = d3.color(piecewiseColor(deciturns / 10)).formatHex()
dtHexHsl = textcolor(shortenHex(dtHex).slice(1), dtHex)
dtValHsl = textcolor(deciturns.toFixed(1), dtHex)
piecewiseIob = d3.piecewise(d3.interpolateRound, [
  301.734720,
  319.675162,
  338.684026,
  358.823261,
  380.160000,
  402.765523,
  426.715171,
  452.088950,
  478.971619,
  507.452688,
  537.627456,
  569.596406,
  603.466416,
  639.351360,
])
piecewiseLen = d3.piecewise(d3.interpolateRound, [
  2436.073648,
  2299.359125,
  2170.306080,
  2048.495960,
  1933.522727,
  1825.002285,
  1722.572924,
  1625.892425,
  1534.637900,
  1448.505481,
  1367.206961,
  1290.471625,
  1218.042928,
  1149.677698,
])
class minMax {
  constructor(limits) {
    this.min = Math.min(...limits)
    this.max = Math.max(...limits)
  }
  scale(val) {
    return (val - this.min) / (this.max - this.min)
  }
}
octave4scaler = new minMax([200, 400])
freqs = [
  201.38,
  213.36,
  226.04,
  239.49,
  253.73,
  268.81,
  284.80,
  301.73,
  319.68,
  338.68,
  358.82,
  380.16,
]
notes = [
  "A♯",
  "B",
  "C",
  "C♯",
  "D",
  "D♯",
  "E",
  "F",
  "F#",
  "G",
  "G♯",
  "A",
]
xet = freqs.map(x => octave4scaler.scale(x))
xetFix = xet.map(x => parseFloat((x * 10).toFixed(2)))
xetCol = xet.map(piecewiseColor)
xetHex = xetCol.map(x => d3.color(x).formatHex())
xetHue = xetCol.map(x => Math.round(d3.hsl(x).h))
xetIob = xet.map(piecewiseIob)
xetLen = xet.map(piecewiseLen)
hues = Object.fromEntries([
    0.002,
    0.004,
    0.008,
    0.014,
    0.0158,
    0.016,
    0.021,
    0.022,
    0.024,
    0.030,
    0.040,
    0.039,
    0.065,
    0.067,
    0.130,
    0.185,
    0.40069,
    0.41302,
    0.413,
    0.4132,
    0.460,
    0.480,
    0.490,
    0.49008,
    0.599,
    0.704,
    0.754,
    0.788,
    0.815,
    0.864,
    0.935,
    0.960,
  ].map(i => [i, d3.hsl(piecewiseColor(i)).h])
);
h26div300 = d3.hsl(piecewiseColor(26 / 300)).h
hD039 = d3.hsl(piecewiseColor(39 / 365)).h
hD080 = d3.hsl(piecewiseColor(80 / 365)).h
hD285 = d3.hsl(piecewiseColor(285 / 365)).h
fMile = 5 / 3 / 1.609344
fInch = 25 / 25.4
hIob = d3.hsl(piecewiseColor(1 / .864 % 1)).h
hMile = d3.hsl(piecewiseColor(fMile % 1)).h
hInch = d3.hsl(piecewiseColor(fInch % 1)).h
hAvLb = d3.hsl(piecewiseColor(500 / 453.59237 % 1)).h
hPint = d3.hsl(piecewiseColor(4 / 3.785411784 % 1)).h
hFlOz = d3.hsl(piecewiseColor(32 / 29.5735296875 % 1)).h
hAcre = d3.hsl(piecewiseColor(247.1053814672 / 250 % 1)).h
hSqMi = d3.hsl(piecewiseColor(fMile**2 % 1)).h
hSqIn = d3.hsl(piecewiseColor(fInch**2 % 1)).h
bcHue = (xetHue[1] + xetHue[2]) / 2
ddsHue = (xetHue[4] + xetHue[5]) / 2
dseHue = (xetHue[5] + xetHue[6]) / 2
html`
<style>
.colorAs {
  background: hsl(${xetHue[0]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[0]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorAs3 {
  background: hsl(${hues[0.40069]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.40069]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color0158 {
  background: hsl(${hues[0.0158]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.0158]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorC4 {
  background: hsl(${hues[0.41302]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.41302]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorA4 {
  background: hsl(${hues[0.49008]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.49008]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorB {
  background: hsl(${xetHue[1]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[1]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorBc {
  background: hsl(${bcHue} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${bcHue}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorC {
  background: hsl(${xetHue[2]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[2]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorCs {
  background: hsl(${xetHue[3]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[3]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorD {
  background: hsl(${xetHue[4]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[4]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorDs {
  background: hsl(${xetHue[5]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[5]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorDds {
  background: hsl(${ddsHue} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${ddsHue}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorDsE {
  background: hsl(${dseHue} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${dseHue}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorE {
  background: hsl(${xetHue[6]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[6]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorF {
  background: hsl(${xetHue[7]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[7]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorFs {
  background: hsl(${xetHue[8]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[8]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorG {
  background: hsl(${xetHue[9]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[9]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorGs {
  background: hsl(${xetHue[10]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[10]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorA {
  background: hsl(${xetHue[11]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${xetHue[11]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color0 {
  background: hsl(0 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(0, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color002 {
  background: hsl(${hues[.002]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[.002]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color004 {
  background: hsl(${hues[.004]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[.004]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color008 {
  background: hsl(${hues[.008]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[.008]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color014 {
  background: hsl(${hues[.014]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[.014]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color016 {
  background: hsl(${hues[0.016]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.016]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color021 {
  background: hsl(${hues[0.021]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.021]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color022 {
  background: hsl(${hues[0.022]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.022]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color024 {
  background: hsl(${hues[0.024]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.024]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color025 {
  background: hsl(20 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(20, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color030 {
  background: hsl(${hues[0.030]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.030]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color039 {
  background: hsl(${hues[0.039]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.039]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color040 {
  background: hsl(${hues[0.040]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.040]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color050 {
  background: hsl(24 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(24, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color065 {
  background: hsl(${hues[0.065]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.065]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color067 {
  background: hsl(${hues[0.067]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.067]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color26div300 {
  background: hsl(${h26div300} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${h26div300}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color1 {
  background: hsl(36 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(36, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color125 {
  background: hsl(44 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(44, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color130 {
  background: hsl(${hues[0.130]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.130]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color185 {
  background: hsl(${hues[0.185]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.185]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color2 {
  background: hsl(60 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(60, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color250 {
  background: hsl(68 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(68, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color3 {
  background: hsl(80 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(80, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color375 {
  background: hsl(96 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(96, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color4 {
  background: hsl(120 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(120, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color413 {
  background: hsl(${hues[0.413]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.413]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color4132 {
  background: hsl(${hues[0.4132]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.4132]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color460 {
  background: hsl(${hues[0.460]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.460]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color480 {
  background: hsl(${hues[0.480]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.480]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color490 {
  background: hsl(${hues[0.490]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.490]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color5 {
  background: hsl(180 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(180, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color599 {
  background: hsl(${hues[0.599]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.599]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color6 {
  background: hsl(208 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(208, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color625 {
  background: hsl(216 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(216, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color7 {
  background: hsl(240 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(240, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color704 {
  background: hsl(${hues[0.704]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.704]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color750 {
  background: hsl(264 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(264, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color754 {
  background: hsl(${hues[0.754]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.754]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color788 {
  background: hsl(${hues[0.788]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.788]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color8 {
  background: hsl(276 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(276, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color815 {
  background: hsl(${hues[0.815]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.815]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color864 {
  background: hsl(${hues[0.864]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.864]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color875 {
  background: hsl(292 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(292, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color9 {
  background: hsl(300 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(300, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color935 {
  background: hsl(${hues[0.935]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.935]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color950 {
  background: hsl(328 ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(328, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color960 {
  background: hsl(${hues[0.960]} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hues[0.960]}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorD039 {
  background: hsl(${hD039} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hD039}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorD080 {
  background: hsl(${hD080} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hD080}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorD285 {
  background: hsl(${hD285} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hD285}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorff6300 {
  background: #ff6300;
  color: black;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorffec00 {
  background: #ffec00;
  color: black;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color99ff00 {
  background: #99ff00;
  color: black;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color28ff00 {
  background: #28ff00;
  color: black;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color00ffe8 {
  background: #00ffe8;
  color: black;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color007cff {
  background: #007cff;
  color: white;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color0800ff {
  background: #0800ff;
  color: white;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.color5e00d6 {
  background: #5e00d6;
  color: white;
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorIob {
  background: hsl(${hIob} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hIob}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorMile {
  background: hsl(${hMile} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hMile}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorInch {
  background: hsl(${hInch} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hInch}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorAvLb {
  background: hsl(${hAvLb} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hAvLb}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorPint {
  background: hsl(${hPint} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hPint}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorFlOz {
  background: hsl(${hFlOz} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hFlOz}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorAcre {
  background: hsl(${hAcre} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hAcre}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorSqMi {
  background: hsl(${hSqMi} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hSqMi}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
.colorSqIn {
  background: hsl(${hSqIn} ${colorS / 10}% ${colorL / 10}%);
  color: ${yiq(`hsl(${hSqIn}, ${colorS / 10}%, ${colorL / 10}%)`) > 0.51 ? "black" : "white"};
  padding: 0px 5px;
  border-radius: 4px;
  font-weight: 400;
  font-family: monospace;
}
</style>
`
Back to top

Reuse

CC BY-SA 4.0

Citation

BibTeX citation:
@online{laptev2024,
  author = {Laptev, Martin},
  title = {Dec},
  date = {2024},
  urldate = {2024},
  url = {https://maptv.github.io/dec},
  langid = {en}
}
For attribution, please cite this work as:
Laptev, Martin. 2024. “Dec.” 2024. https://maptv.github.io/dec.
Article List
Date
Source Code
---
title: Dec
author:
  - name: Martin Laptev
    url: https://maptv.github.io
image: /asset/colorWheelCompass.svg
description: >
  Introducing the Dec measurement system, which uses turns instead of months, weeks, hours, minutes, seconds, and degrees.
citation:
  url: https://maptv.github.io/dec
aliases:
  - /d
license: CC BY-SA
lightbox: false
toc: true
toc-depth: 5
bread-crumbs: false
format:
  html:
    grid:
      body-width: 900px
    shift-heading-level-by: 3
    include-after-body:
      - ../asset/cite.html
      - ../asset/style.html
      - ../asset/stamp.html
      - ../asset/tooltip.html
  commonmark: default
filters:
  - ../asset/date.lua
---

:::{#firstnav}
{{< include /asset/_decnav.qmd >}}
:::

# Dec measurement system {.hiddenheading #dec}

This part of my website focuses on Dec, a [measurement system](https://en.wikipedia.org/wiki/System_of_units_of_measurement#:~:text=a%20collection%20of%20units%20of%20measurement%20and%20rules%20relating%20them%20to%20each%20other) that [I](https://maptv.github.io) created. All Dec measurements are based on [turns](https://en.wikipedia.org/wiki/Turn_%28angle%29#:~:text=a%20unit%20of%20plane%20angle%20measurement%20equal%20to%202%CF%80%C2%A0radians%2C%20360%C2%A0degrees). When measuring [angles](https://en.wikipedia.org/wiki/Angle#:~:text=the%20figure%20formed%20by%20two%20rays)📐, a turn represents a full⭕️circle and equals 2$\pi$ ([$\underline\tau$](https://en.wikipedia.org/wiki/Turn_%28angle%29#:~:text=the%20Greek%20letter,to%20one%20turn)) [radians](https://en.wikipedia.org/wiki/Radian#:~:text=the%20unit%20of%20angle%20in%20the%20International%20System%20of%20Units) ([rad]{.tool data-bs-toggle="tooltip" data-bs-title="radians"}) or 360 [degrees](https://en.wikipedia.org/wiki/Degree_(angle)#:~:text=a%20measurement%20of%20a%20plane%20angle%20in%20which%20one%20full%20rotation%20is%20360%20degrees) ([°]{.tool data-bs-toggle="tooltip" data-bs-title="degrees"}). [Geographic coordinates](https://en.wikipedia.org/wiki/Geographic_coordinate_system#:~:text=positions%20directly%20on%20Earth%20as%20latitude%20and%20longitude) and [compass](https://en.wikipedia.org/wiki/Compass#:~:text=a%20device%20that%20shows%20the%20cardinal%20directions%20used%20for%20navigation%20and%20geographic%20orientation)🧭directions are angles📐and thus can, and should😄, be measured in turns instead of [rad]{.tool data-bs-toggle="tooltip" data-bs-title="radians"} or [°]{.tool data-bs-toggle="tooltip" data-bs-title="degrees"}.

## Longitude latitude course {.hiddenheading #llc}

Dec measures [longitude](https://en.wikipedia.org/wiki/Longitude#:~:text=denoted%20by%20the%20Greek%20letter%20lambda) in [parallels](https://en.wikipedia.org/wiki/Circle_of_latitude#:~:text=an%20abstract%20east%E2%80%93west%20small%20circle%20connecting%20all%20locations%20around%20Earth%20(ignoring%20elevation)%20at%20a%20given%20latitude%20coordinate%20line) ([$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="parallels"}), [latitude]([$\underline\phi$](https://en.wikipedia.org/wiki/Latitude#:~:text=denoted%20by%20the%20Greek%20lower%2Dcase%20letter%20phi)) in [meridians](https://en.wikipedia.org/wiki/Meridian_arc#Full_meridian_(polar_perimeter):~:text=The%20polar%20Earth%27s%20circumference%20is%20simply%20four%20times%20quarter%20meridian) ([$\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="meridians"}), and compass🧭directions in [windroses](https://en.wikipedia.org/wiki/Compass_rose#:~:text=a%20polar%20diagram%20displaying%20the%20orientation%20of%20the%20cardinal%20directions) ([$\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="windroses"}). To measure certain kinds of angles📐, Dec uses specific types of turns with distinct names like [$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="parallel"}, [$\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="meridian"}, or [$\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="windrose"}. All turn types can be combined with [metric prefixes](https://en.wikipedia.org/wiki/Metric_prefix#:~:text=a%20unit%20prefix%20that%20precedes%20a%20basic%20unit%20of%20measure%20to%20indicate%20a%20multiple%20or%20submultiple%20of%20the%20unit), like [deci](https://en.wikipedia.org/wiki/Deci-#:~:text=a%20decimal%20unit%20prefix%20in%20the%20metric%20system%20denoting%20a%20factor%20of%20one%20tenth), [centi](https://en.wikipedia.org/wiki/Centi-#:~:text=a%20unit%20prefix%20in%20the%20metric%20system%20denoting%20a%20factor%20of%20one%20hundredth), or [milli](https://en.wikipedia.org/wiki/Milli-#:~:text=a%20unit%20prefix%20in%20the%20metric%20system%20denoting%20a%20factor%20of%20one%20thousandth), to create turn [submultiples](https://en.wikipedia.org/wiki/Multiple_%28mathematics%29#:~:text=of%20%22a%20being-,a%20unit%20fraction,-of%20b%22%20%28a), such as [deciturns]{.tool data-bs-toggle="tooltip" data-bs-title="tenths of a turn"}, [centiturns]{.tool data-bs-toggle="tooltip" data-bs-title="hundredths of a turn"}, or [milliturns]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a turn"}.

The table below provides the current longitude in [milliparallels]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a parallel"} ([$\text m\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="milliparallels"}) and latitude in [millimeridians]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a meridian"} ([$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) of Points [0]{.point0} and [1]{.point1} on the map🗺️beneath the table. By default, Point [0]{.point0} is at [800]{.color8} [$\text m\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="milliparallels"} and [0]{.color0} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}, near the [Galápagos🏝️archipelago](https://en.wikipedia.org/wiki/Gal%C3%A1pagos_Islands#:~:text=an%20archipelago%20of%20volcanic%20islands%20in%20the%20Eastern%20Pacific) of Ecuador🇪🇨, and Point [1]{.point1} is at [800]{.color8} [$\text m\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="milliparallels"} and [100]{.color1} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}, near the bottom of the [Missouri bootheel](https://en.wikipedia.org/wiki/Missouri_Bootheel#:~:text=a%20salient%20(protrusion)%20located%20in%20the%20southeasternmost%20part%20of%20the%20U.S.%20state%20of%20Missouri) in the United States🇺🇸.

To move the points, click the map🗺️or edit their coordinates in the table. The [toggle](https://observablehq.com/framework/inputs/toggle)✅inputs above the table add layers to the map🗺️: country borders, a rainbow🌈colored🎨grid of Dec [graticules](https://en.wikipedia.org/wiki/Graticule_(cartography)#:~:text=a%20graphical%20depiction%20of%20a%20coordinate%20system%20as%20a%20grid%20of%20lines), a [choropleth](https://en.wikipedia.org/wiki/Choropleth_map#:~:text=a%20type%20of%20statistical%20thematic%20map%20that%20uses%20pseudocolor) of [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time#:~:text=the%20primary%20time%20standard%20globally%20used%20to%20regulate%20clocks%20and%20time) time zones, and [solar terminator](https://en.wikipedia.org/wiki/Terminator_(solar)#:~:text=a%20moving%20line%20that%20divides%20the%20daylit%20side%20and%20the%20dark%20night%20side%20of%20a%20planetary%20body) shading with a yellow🟡dot denoting the [point](https://en.wikipedia.org/wiki/Subsolar_point#:~:text=the%20point%20at%20which%20its%20Sun%20is%20perceived%20to%20be%20directly%20overhead) where the Sun☀️is [directly overhead](https://en.wikipedia.org/wiki/Zenith#:~:text=the%20imaginary%20point%20on%20the%20celestial%20sphere%20directly%20%22above%22%20a%20particular%20location): \${sunLonHsl} [$\text m\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="milliparallels"} and \${sunLatHsl} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}.

Alongside the geographic coordinates of a point, each row of the table contains the [course](https://en.wikipedia.org/wiki/Azimuth#:~:text=%20azimuth%20is%20usually%20denoted%20alpha) in [milliwindroses]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a compass rose"} ([$\text m\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="milliwindroses"}) we would need to maintain to travel🧳the shortest distance to the other point. The shortest distance is shown as orange🟠dots on the map🗺️. The default courses in [$\text m\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="milliwindroses"} are [0]{.color0} (North) from Point [0]{.point0} to [1]{.point1} and [500]{.color5} (South) from Point [1]{.point1} to [0]{.point0}.

## Distance speed duration {.hiddenheading #dsd}

Dec measures distance in [taurs](https://en.wikipedia.org/wiki/Turn_(angle)#Tau_proposals:~:text=%E2%81%A0%20turn-,Circumference%20of%20a%20circle,-%F0%9D%90%B6) ([c]{.tool data-bs-toggle="tooltip" data-bs-title="taurs"}), speed in [omegars](https://en.wikipedia.org/wiki/Angular_velocity#:~:text=linear%20velocity%20is%20the%20radius%20times%20the%20angular%20velocity) ([v]{.tool data-bs-toggle="tooltip" data-bs-title="omegars"}), and time in years ([y]{.tool data-bs-toggle="tooltip" data-bs-title="years"}) and days ([d]{.tool data-bs-toggle="tooltip" data-bs-title="days"}). Each of these four turn types approximates ($\approx$) a physical property of the Earth🌍: [c]{.tool data-bs-toggle="tooltip" data-bs-title="taur"} = [$\tau r$]{.tool data-bs-toggle="tooltip" data-bs-title="taur"} $\approx$ its [circumference](https://en.wikipedia.org/wiki/Earth%27s_circumference#:~:text=the%20distance%20around%20Earth), [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"} $\approx$ the duration of its [orbit](https://en.wikipedia.org/wiki/Earth%27s_orbit#:~:text=From%20a%20vantage%20point%20above%20the%20north%20pole%20of%20either%20the%20Sun%20or%20Earth%2C%20Earth%20would%20appear%20to%20revolve%20in%20a%20counterclockwise%20direction%20around%20the%20Sun) around the Sun☀️, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"} $\approx$ the duration of its [rotation](https://en.wikipedia.org/wiki/Earth%27s_rotation#:~:text=the%20rotation%20of%20planet%20Earth%20around%20its%20own%20axis) on its [axis](https://en.wikipedia.org/wiki/Axial_tilt#:~:text=the%20imaginary%20line%20that%20passes%20through%20both%20the%20north%20pole%20and%20south%20pole), and $\text c\over\text d$ = [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegar"} = [$\omega r$]{.tool data-bs-toggle="tooltip" data-bs-title="omegar"} $\approx$ the speed of its rotation at the [Equator](https://en.wikipedia.org/wiki/Equator#:~:text=the%20circle%20of%20latitude%20that%20divides%20Earth%20into%20the%20Northern%20and%20Southern%20hemispheres).

At a speed of [0.5]{.color5} [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegars"} or [500]{.color5} [milliomegars]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of an omegar"} ([mv]{.tool data-bs-toggle="tooltip" data-bs-title="milliomegars"}), we could travel🧳the [0.1]{.color1} [c]{.tool data-bs-toggle="tooltip" data-bs-title="taurs"} or [100]{.color1} [millitaurs]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a taur"} ([mc]{.tool data-bs-toggle="tooltip" data-bs-title="millitaurs"}) between the default positions📍of Points [0]{.point0} and [1]{.point1} in [0.2]{.color2} [d]{.tool data-bs-toggle="tooltip" data-bs-title="days"} or [200]{.color2} [millidays]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a day"} ([md]{.tool data-bs-toggle="tooltip" data-bs-title="millidays"}). The time required to travel🧳between two points is the distance divided by the speed: \${distance_mcHsl0} [mc]{.tool data-bs-toggle="tooltip" data-bs-title="millitaurs"} &divide; \${velocity_vHsl0} [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegars"} = \${traveltimeHsl0} [md]{.tool data-bs-toggle="tooltip" data-bs-title="millidays"} = \${distance_cHsl} [c]{.tool data-bs-toggle="tooltip" data-bs-title="taurs"} &divide; \${velocity_vHsl1} [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegars"} = \${distance_mcHsl1} [mc]{.tool data-bs-toggle="tooltip" data-bs-title="millitaurs"} &divide; \${velocity_mvHsl} [mv]{.tool data-bs-toggle="tooltip" data-bs-title="milliomegars"} = \${traveltimeHsl1} [d]{.tool data-bs-toggle="tooltip" data-bs-title="days"}.

## Interactive world map {.hiddenheading #map}

{{< include /dec/_maptable.qmd >}}

## Color wheel compass {.hiddenheading #cwc}

{{< include /dec/_color.qmd >}}

The [color🎨wheel](https://en.wikipedia.org/wiki/Color_wheel#:~:text=an%20abstract%20illustrative%20organization%20of%20color%20hues%20around%20a%20circle) compass🧭above indicates both a [hue](https://en.wikipedia.org/wiki/Hue#:~:text=an%20angular%20position%20around%20a%20central%20or%20neutral%20point%20or%20axis%20on%20a%20color%20space%20coordinate%20diagram) in [milliturns]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a turn"} ([mt]{.tool data-bs-toggle="tooltip" data-bs-title="milliturns"}) and a course in [$\text m\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="milliwindroses"}. We can convert the hue to [HSL and HSV](https://en.wikipedia.org/wiki/HSL_and_HSV#:~:text=the%20two%20most%20common%20cylindrical%2Dcoordinate%20representations%20of%20points%20in%20an%20RGB%20color%20model) degrees ([h°]{.tool data-bs-toggle="tooltip" data-bs-title="HSL or HSV degrees"}) and the course to compass🧭degrees ([c°]{.tool data-bs-toggle="tooltip" data-bs-title="compass degrees"}): 25 [$\text m\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="milliwindroses"} = 9 [c°]{.tool data-bs-toggle="tooltip" data-bs-title="compass degrees"}. To rotate🔄the color🎨wheel compass🧭, use the "Hue" [range](https://observablehq.com/framework/inputs/range)🎚️and [hue bar](https://observablehq.com/@paavanb/progressive-color-picker) inputs beneath it or change the course from Point [0]{.point0} to [1]{.point1} on the map🗺️.

## Red green blue (rgb) {.hiddenheading #rgb}

The table beneath the hue bar compares the current Point [0]{.point0} to [1]{.point1} course in its top row with the [cardinal](https://en.wikipedia.org/wiki/Cardinal_direction#:~:text=north%2C%20south%2C%20east%2C%20and%20west) and [intercardinal](https://en.wikipedia.org/wiki/Cardinal_direction#:~:text=northeast%20(NE)%2C%20southeast%20(SE)%2C%20southwest%20(SW)%2C%20and%20northwest%20(NW)) directions. Together, the range🎚️inputs underneath the hue bar form a Hue Saturation Lightness ([HSL]{.tool data-bs-toggle="tooltip" data-bs-title="Hue Saturation Lightness"}) triplet. Like [Red]{.color0} [Green]{.color4} [Blue]{.color7} ([RGB](https://en.wikipedia.org/wiki/RGB_color_model#:~:text=an%20additive%20color%20model)) or [hexadecimal](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet:~:text=hexadecimal%20number%20used%20in%20HTML%2C%20CSS%2C%20SVG%2C%20and%20other%20computing%20applications%20to%20represent%20colors) ([hex]{.tool data-bs-toggle="tooltip" data-bs-title="hexadecimal"}) triplets, [HSL]{.tool data-bs-toggle="tooltip" data-bs-title="Hue Saturation Lightness"} triplets specify a full-fledged color🎨instead of just a hue.

::: {.callout-warning}
# Bad Pun Alert
Feeling ***disoriented***😵‍💫? Of [***course***](https://en.wikipedia.org/wiki/Course_(navigation)#:~:text=the%20cardinal%20direction%20in%20which%20the%20craft%20is%20to%20be%20steered) you are! Color🎨labels🏷️can help you find your [***bearings***](https://en.wikipedia.org/wiki/Bearing_(navigation)#:~:text=the%20horizontal%20angle%20between%20the%20direction%20of%20an%20object%20and%20north%20or%20another%20object), stay on [***track***](https://en.wikipedia.org/wiki/Course_(navigation)#:~:text=The%20path%20that%20a%20vessel%20follows), and avoid [***heading***](https://en.wikipedia.org/wiki/Course_(navigation)#:~:text=the%20direction%20where%20the%20watercraft's%20bow%20or%20the%20aircraft's%20nose%20is%20pointed) aches🤕. [Orange]{.orange} you glad I couldn't think of a color🎨pun?
:::

Color🎨can provide a general idea of angular📐[measure](https://en.wikipedia.org/wiki/Angle#:~:text=The%20magnitude%20of%20an%20angle), regardless of the metric prefixes or [units](https://en.wikipedia.org/wiki/Angle#Units) we use. Therefore, we can reuse♻️colors🎨across many different contexts. Most often, [red]{.color0} designates starting points, like North ([0]{.color0} [$\text m\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="milliwindroses"}) and [Longitude 0](https://en.wikipedia.org/wiki/18th_meridian_west#:~:text=a%20line%20of%20longitude%20that%20extends%20from%20the%20North%20Pole%20across%20the%20Arctic%20Ocean%2C%20Greenland%2C%20Iceland%2C%20the%20Atlantic%20Ocean%2C%20the%20Canary%20Islands%2C%20the%20Southern%20Ocean%2C%20and%20Antarctica%20to%20the%20South%20Pole) ([0]{.color0} [$\text m\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="milliparallels"}), and [cyan]{.color5} denotes midpoints, such as South ([500]{.color5} [$\text m\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="milliwindroses"}) and [Longitude 5](https://en.wikipedia.org/wiki/162nd_meridian_east#:~:text=a%20line%20of%20longitude%20that%20extends%20from%20the%20North%20Pole%20across%20the%20Arctic%20Ocean%2C%20Asia%2C%20the%20Pacific%20Ocean%2C%20the%20Southern%20Ocean%2C%20and%20Antarctica%20to%20the%20South%20Pole) ([500]{.color5} [$\text m\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="milliparallels"}).

The Equator ([0]{.color0} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) is the [major latitude](https://en.wikipedia.org/wiki/Circle_of_latitude#:~:text=mark%20the%20divisions%20between%20the%20five%20principal%20geographical%20zones) midway between the South ([-250]{.color750} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) and North ([250]{.color250} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) Poles. Unlike the Equator, the Tropics of [Cancer](https://en.wikipedia.org/wiki/Tropic_of_Cancer#:~:text=northernmost%20circle%20of%20latitude%20where%20the%20Sun%20can%20be%20seen%20directly%20overhead)♋([65]{.color065} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) and [Capricorn](https://en.wikipedia.org/wiki/Tropic_of_Capricorn#:~:text=the%20southernmost%20latitude%20where%20the%20Sun%20can%20be%20seen%20directly%20overhead)♑️([-65]{.color935} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) and the [Arctic](https://en.wikipedia.org/wiki/Arctic_Circle#:~:text=the%20southernmost%20latitude%20at%20which%2C%20on%20the%20winter%20solstice%20in%20the%20Northern%20Hemisphere%2C%20the%20Sun%20does%20not%20rise%20all%20day%2C%20and%20on%20the%20Northern%20Hemisphere%27s%20summer%20solstice%2C%20the%20Sun%20does%20not%20set) ([250]{.color250} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"} -- [65]{.color065} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"} = [185]{.color185} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) and [Antarctic](https://en.wikipedia.org/wiki/Antarctic_Circle#:~:text=the%20Sun%20is%20above%20the%20horizon%20for%2024%20continuous%20hours%20at%20least%20once%20per%20year%20(and%20therefore%20visible%20at%20solar%20midnight)%20and%20the%20centre%20of%20the%20Sun%20(ignoring%20refraction)%20is%20below%20the%20horizon%20for%2024%20continuous%20hours%20at%20least%20once%20per%20year%20(and%20therefore%20not%20visible%20at%20solar%20noon)) ([65]{.color065} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"} -- [250]{.color250} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"} = [-185]{.color815} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) Circles are defined by the [axial tilt](https://en.wikipedia.org/wiki/Axial_tilt#Earth:~:text=the%20angle%20between%20the%20ecliptic%20and%20the%20celestial%20equator%20on%20the%20celestial%20sphere) of the Earth🌏([65]{.color065} [mt]{.tool data-bs-toggle="tooltip" data-bs-title="milliturns"}).

# Dec time zones {#dtz}

Enable the “Grid” toggle✅input to see Latitudes [-2](https://en.wikipedia.org/wiki/72nd_parallel_south#:~:text=a%20circle%20of%20latitude%20that%20is%2072%20degrees%20south%20of%20the%20Earth's%20equatorial%20plane%20in%20the%20Antarctic) ([-200]{.color8} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}), [-1](https://en.wikipedia.org/wiki/36th_parallel_south#:~:text=a%20circle%20of%20latitude%20that%20is%2036%20degrees%20south%20of%20the%20Earth's%20equatorial%20plane) ([-100]{.color9} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}), [0](https://en.wikipedia.org/wiki/Equator#:~:text=the%20circle%20of%20latitude%20that%20divides%20Earth%20into%20the%20Northern%20and%20Southern%20hemispheres) ([0]{.color0} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}), [1](https://en.wikipedia.org/wiki/36th_parallel_north#:~:text=a%20circle%20of%20latitude%20that%20is%2036%20degrees%20north%20of%20the%20Earth's%20equatorial%20plane) ([100]{.color1} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}), and [2](https://en.wikipedia.org/wiki/72nd_parallel_north#:~:text=a%20circle%20of%20latitude%20that%20is%2072%20degrees%20north%20of%20the%20Earth's%20equatorial%20plane%2C%20in%20the%20Arctic) ([200]{.color2} [$\text m\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="millimeridians"}) on the map🗺️above along with the ten major longitudes that divide the Earth🌎into the ten Dec time zones. Notably, Longitude [0]{.color0} is the major longitude that functions as both the [Prime Meridian](https://en.wikipedia.org/wiki/Prime_meridian#:~:text=an%20arbitrarily%2Dchosen%20meridian%20%28a%20line%20of%20longitude%29%20in%20a%20geographic%20coordinate%20system%20at%20which%20longitude%20is%20defined%20to%20be%200%C2%B0) and [International Date Line](https://en.wikipedia.org/wiki/International_Date_Line#:~:text=the%20line%20between%20the%20South%20and%20North%20Poles%20that%20is%20the%20boundary%20between%20one%20calendar%20day%20and%20the%20next) in Dec.

Like the ten major longitudes that separate them, Dec time zones are numbered [0]{.color0} to [9]{.color9}. Based on its current [deciparallel]{.tool data-bs-toggle="tooltip" data-bs-title="a tenth of a parallel"} ([d$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="deciparallel"}) longitude, \${point0lHsl}, Point [0]{.point0} on the map🗺️above is in Zone \${point0zHsl}. The number assigned to each time zone is its offset from Zone [0]{.color0} in [decidays]{.tool data-bs-toggle="tooltip" data-bs-title="tenths of a day"} ([dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"}). To obtain the [dd]{.tool data-bs-toggle="tooltip" data-bs-title="deciday"} offset at a location, we [floor](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions#:~:text=the%20greatest%20integer%20less%20than%20or%20equal%20to%20x) its [d$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="deciparallel"} longitude: ⌊\${decLonHsl}⌋ = \${decZonHsl}.

```{ojs}
//| echo: false
//| label: loninput
viewof longitude = Inputs.range([0, 10], {label: "Longitude", value: .5, step: .01})
```

Each Dec time zone is 1 [d$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="deciparallel"} wide and 0.5 [$\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="meridians"} long. While 1 [$\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="meridian"} is always [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}1 [c]{.tool data-bs-toggle="tooltip" data-bs-title="taur"} long, the length of a [$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="parallel"} [varies by latitude](https://en.wikipedia.org/wiki/Longitude#Length_of_a_degree_of_longitude:~:text=depends%20only%20on%20the%20radius%20of%20a%20circle%20of%20latitude). At the Equator, 1 [$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="parallel"} is [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}1 [c]{.tool data-bs-toggle="tooltip" data-bs-title="taur"} long. At the [North](https://en.wikipedia.org/wiki/North_Pole#:~:text=the%20point%20in%20the%20Northern%20Hemisphere%20where%20the%20Earth%27s%20axis%20of%20rotation%20meets%20its%20surface) or [South](https://en.wikipedia.org/wiki/South_Pole#:~:text=the%20point%20in%20the%20Southern%20Hemisphere%20where%20the%20Earth%27s%20axis%20of%20rotation%20meets%20its%20surface) Pole, the length of a [$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="parallel"} is zero. The approximate [c]{.tool data-bs-toggle="tooltip" data-bs-title="taur"} length of a [$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="parallel"} is the [cosine](https://en.wikipedia.org/wiki/Sine_and_cosine#:~:text=the%20ratio%20of%20the%20length%20of%20the%20adjacent%20leg%20to%20that%20of%20the%20hypotenuse) of its latitude in [$\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="meridians"}, [rad]{.tool data-bs-toggle="tooltip" data-bs-title="radians"}, or [°]{.tool data-bs-toggle="tooltip" data-bs-title="degrees"}, depending on the input requirement of our cosine function: cos(\${parLat}\${conversionFactor}) = \${parLen}.

```{ojs}
//| echo: false
//| label: latinput
viewof latitude = Inputs.range([-.25, .25], {label: "Latitude", value: 0, step: .001})
```

```{ojs}
//| echo: false
//| label: costype
viewof costype = Inputs.radio(["turns", "radians", "degrees"], {label: "Cosine input", value: "turns"})
```

## Coordinated Universal Time {.hiddenheading #utc}

[UTC time zone offsets](https://en.wikipedia.org/wiki/UTC_offset#:~:text=the%20difference%20in%20hours%20and%20minutes%20between%20Coordinated%20Universal%20Time%20(UTC)%20and%20the%20standard%20time%20at%20a%20particular%20place) range from \${rainbowN5zn} to \${rainbowP583} [dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"}. The UTC offset provided by your web browser is \${utcOffHslM} &div; 144 = \${utcOffHslD} [dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"}. The Dec time zone that corresponds to this UTC offset is Zone \${decZonHslP}. The time in corresponding Dec and UTC time zones can differ by up to [0.5]{.color050} [dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"}. The difference between your Dec and UTC time is \${utcOffsetMdiffHsl } &div; 144 = \${utcOffDiffHsl} [dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"}.

To obtain the time in Zone [0]{.color0}, we can subtract the offset of any time zone from its time. Inversely, we can get the time in any time zone by adding its offset to the Zone [0]{.color0} time. The dates and times in Zone [0]{.color0} and [UTC[+00:00]{.color0}](https://en.wikipedia.org/wiki/UTC%2B00:00#:~:text=the%20basis%20of%20Coordinated%20Universal%20Time) match exactly. Zone [5]{.color5} and [UTC[+12:00]{.color5}](https://en.wikipedia.org/wiki/UTC%2B12:00) also have matching dates and times, both are precisely one day ahead of [UTC[-12:00]{.color5}](https://en.wikipedia.org/wiki/UTC%E2%88%9212:00).

To avoid date mismatches with UTC time zones that have negative offsets, we can subtract ten [dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"} from any positive Dec offset to make it negative: \${decOffsetHslP} -- [10]{.color0} = \${decOffsetHslN}. Therefore, each Dec time zone has both a positive and a negative offset. The two offsets in any time zone are exactly one day apart, produce the same time, and have the same color🎨label🏷️.

## Millenium Year Day {.hiddenheading #myd}

```{ojs}
//| echo: false
//| label: offinput
viewof offset = Inputs.range([-10, 9], {label: "Offset", value: 0, step: 1})
```

When we add the offset selected by the range🎚️input above to the current date and time in Zone [0]{.color0}, we get \${decYearOffHsl}[+]{style="font-family:monospace;"}\${decDateOffHsl} as the date and \${decTimeOffHsl0}[\${decSignOff}]{style="font-family:monospace;"}\${decOffsetHsl1} as the time. We can apply color🎨labels🏷️to each Dec date and time component. Dec dates consist of a year and a day-of-year ([doy]{.tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}), whereas Dec times are composed of a time-of-day ([tod]{.tool data-bs-toggle="tooltip" data-bs-title="time-of-day"}) and a time zone.

Each [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days-of-year"} also has two components. The first two digits of a three-digit [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days-of-year"} represent a group of ten days called a [decaday]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"} ([dek]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}). The last digit of a [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days-of-year"} is the day-of-dek ([dod]{.tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"}). In Dec, [deks]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"} are used instead of months and weeks. Likewise, Dec uses [dods]{.tool data-bs-toggle="tooltip" data-bs-title="days-of-dek"} in lieu of days-of-month ([doms]{.tool data-bs-toggle="tooltip" data-bs-title="days-of-month"}) and days-of-week ([dows]{.tool data-bs-toggle="tooltip" data-bs-title="days-of-week"}). In Zone \${decOffsetHsl2}, it is currently [Dek]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"} \${decDekOffHsl} and [Dod]{.tool data-bs-toggle="tooltip" data-bs-title="Day-of-dek"} \${decDodOffHsl}.

Year color🎨labels🏷️are based on [millimillennia]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a millennium"} ([mk]{.tool data-bs-toggle="tooltip" data-bs-title="millimillennia"}). Every millennium starts with Year 0 ([0]{.color0} [mk]{.tool data-bs-toggle="tooltip" data-bs-title="millimillennia"}) and has Year 500 ([500]{.color5} [mk]{.tool data-bs-toggle="tooltip" data-bs-title="millimillennia"}) as its midpoint. [Doy]{.tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} color🎨labels🏷️are derived from [milliyears]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a year"} ([my]{.tool data-bs-toggle="tooltip" data-bs-title="milliyears"}). Every year starts on [Day 0]{.tool data-bs-toggle="tooltip" data-bs-title="March 1"} ([0]{.color0} [my]{.tool data-bs-toggle="tooltip" data-bs-title="milliyears"}). The midyear point ([500]{.color5} [my]{.tool data-bs-toggle="tooltip" data-bs-title="milliyears"}) is noon ([500]{.color5} [md]{.tool data-bs-toggle="tooltip" data-bs-title="millidays"}) on [Day 182]{.tool data-bs-toggle="tooltip" data-bs-title="August 30"} in [common years](https://en.wikipedia.org/wiki/Common_year#:~:text=a%20calendar%20year%20with%20365%20days) and midnight ([0]{.color0} [md]{.tool data-bs-toggle="tooltip" data-bs-title="millidays"}) on [Day 183]{.tool data-bs-toggle="tooltip" data-bs-title="August 31"} in [leap years](https://en.wikipedia.org/wiki/Leap_year#:~:text=a%20calendar%20year%20that%20contains%20an%20additional%20day).

# Zone equatorial meter (zem) {#zem}

:::{.column-page-right fig-align="center" style="text-align:center;font-size:.825rem;" id="zemmodulor" .lighthouse}
![](../asset/Modulor_measurements.svg){#zModu}
[Wikimedia](https://commons.m.wikimedia.org/wiki/File:Modulor_measurements.svg#mw-jump-to-license)
:::

Apart from [c]{.tool data-bs-toggle="tooltip" data-bs-title="taur"}, Dec also measures distance using a unit called the **z**one **e**quatorial **m**eter ([zem]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meter"}). The width of a Dec time zone at the Equator is approximately ten million ([~10^7^]{.tool data-bs-toggle="tooltip" data-bs-title="approximately ten million"}) [zems]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meters"}. Similarly, the distance from the Equator to one of the Poles is [~10^7^]{.tool data-bs-toggle="tooltip" data-bs-title="approximately ten million"} [meters](https://en.wikipedia.org/wiki/Metre#Definition:~:text=the%20base%20unit%20of%20length%20in%20the%20International%20System%20of%20Units). In other words, a [decimeridian]{.tool data-bs-toggle="tooltip" data-bs-title="a tenth of a meridian"} ([$\text d\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="decimeridian"}) is [~10^7^]{.tool data-bs-toggle="tooltip" data-bs-title="approximately ten million"} [zems]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meters"} long and a [quarter meridian](https://en.wikipedia.org/wiki/Meridian_arc#Full_meridian_(polar_perimeter):~:text=The%20distance%20from%20the%20equator%20to%20the%20pole) is [~10^7^]{.tool data-bs-toggle="tooltip" data-bs-title="approximately ten million"} meters long.

:::{.column-margin fig-align="center" style="text-align:center;" id="zemhands" .hand}
{{< include _hands.qmd >}}
[[Wikimedia](https://commons.wikimedia.org/wiki/File:Typing-colour_for-finger-positions.svg)]{.handlabel}
:::

## Length area volume {.hiddenheading #lav}

You can approximate a [zem]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meter"} ([z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"}) using your hands🤲. With your palms flat on a table in front of you and the tips of your thumbs👍touching, the maximum distance between the tips of your pinkies is [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}1 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"}. When you spread out the fingers on one hand✋or do the "[call me](https://en.wikipedia.org/wiki/Shaka_sign#:~:text=the%20gesture%20is%20commonly%20understood%20to%20mimic%20the%20handset%20of%20a%20traditional%20landline%20telephone)", "[drink](https://en.wikipedia.org/wiki/Shaka_sign#:~:text=placing%20the%20thumb%20to%20the%20mouth%20and%20motioning%20the%20little%20finger%20upward%20as%20if%20tipping%20up%20a%20bottle%27s%20bottom%20end)", or "[shaka](https://en.wikipedia.org/wiki/Shaka_sign#:~:text=a%20gesture%20with%20friendly%20intent%20often%20associated%20with%20Hawaii%20and%20surf%20culture)"🤙gesture, your thumb👍and pinky tips are [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}0.5 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zems"} apart.

:::{.column-margin fig-align="center" style="text-align:center;" #zemarms}
![](../asset/squareZem.svg){#zArms}
[Wikimedia](https://commons.wikimedia.org/wiki/File:Extended_arm.jpg){#armlabel}
:::

To visualize a square [zem]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meter"} ([z^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square zem"}), imagine four people standing in a circle, facing inward, each with their right hand✋placed on top of the elbow of the person to their right. Alternatively, two people can stand in front of each other and raise their arms💪, placing one hand✋on the elbow of the other person and the other hand✋on their own elbow.

:::{.column-margin fig-align="center" style="text-align:center;" #zemlift}
![](../asset/Man_Lifting_Barbell_Cartoon.svg){#zLift}
[Wikimedia](https://commons.wikimedia.org/wiki/File:Man_Lifting_Barbell_Cartoon.svg){#liftlabel}
:::

You can approximate a [z^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square zem"} yourself by sitting in a chair🪑or standing🧍with your knees and feet🦶1 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"}, 4 [decimeters]{.tool data-bs-toggle="tooltip" data-bs-title="tenths of a meter"} ([dm]{.tool data-bs-toggle="tooltip" data-bs-title="decimeters"}), or 16 inches apart, which is probably about the width of your hips or shoulders. The [z^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square zem"} will be between your shins, its top will be below your knees, and its bottom will be either above your ankles or feet🦶, depending on your height.

:::{.column-margin fig-align="center" style="text-align:center;" id="zemcubic"}
{{< include _cubic.qmd >}}
[Dimensions.com](https://www.dimensions.com/element/sitting-male-side-1){#cubiclabel}
:::

## Typical seat height {.hiddenheading #tsh}

According to [dimensions.com](https://www.dimensions.com), 115 [centizems]{.tool data-bs-toggle="tooltip" data-bs-title="hundredths of a zem"} ([cz]{.tool data-bs-toggle="tooltip" data-bs-title="centizems"}) is the [typical seat height](https://www.dimensions.com/element/sitting-female-side-1#:~:text=Seat%20Height%20(Typical)%3A-,18%E2%80%9D%20%7C%2046%20cm,-Style%3A%20Casual) for both men and women age 25 to 45. A box📦that is the size of a cubic [zem]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meter"} ([z^3^]{.tool data-bs-toggle="tooltip" data-bs-title="cubic zem"}) would likely fit under a typical chair🪑 or in between the shins of two people sitting in front of each other with their knees and feet🦶1 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"} apart and their legs🦵bent at 25 [centiturn]{.tool data-bs-toggle="tooltip" data-bs-title="a hundredth of a turn"} ([ct]{.tool data-bs-toggle="tooltip" data-bs-title="centiturn"}) angles📐.

In [Slovak](https://sk.wikipedia.org/wiki/Zem)🇸🇰, [zem]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meter"} means Earth🌍. This is fitting because all Dec units are based on physical attributes of the Earth🌏. At the Equator, the Earth🌎rotates on its axis at a speed of 1.00224 [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegars"}. If we could indefinitely maintain this speed while flying West in an airplane✈️towards the setting sun☀️, we would be able to perpetually fly [into the sunset](https://tvtropes.org/pmwiki/pmwiki.php/Main/RidingIntoTheSunset)🌅.

## Speed of sound {.hiddenheading #sos}

To travel fast enough, the airplane✈️would need to surpass the [speed of sound](https://en.wikipedia.org/wiki/Speed_of_sound#:~:text=the%20distance%20travelled%20per%20unit%20of%20time%20by%20a%20sound%20wave)🔊, which at 15 [°]{.tool data-bs-toggle="tooltip" data-bs-title="degrees"} [Celsius](https://en.wikipedia.org/wiki/Celsius#:~:text=the%20unit%20of%20temperature%20on%20the%20Celsius%20temperature%20scale) and 1 [standard atmosphere](https://en.wikipedia.org/wiki/Standard_atmosphere_(unit)#:~:text=a%20unit%20of%20pressure%20defined%20as%20101325%20Pa) is 0.735048 [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegars"} or Mach 1. [Mach numbers](https://en.wikipedia.org/wiki/Mach_number) are not as reliable as [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegar"}, because they are relative to the speed of sound🔊, which varies greatly by air temperature and pressure. The cruising speed of a [Boeing 747](https://en.wikipedia.org/wiki/Boeing_747#:~:text=sweep%2C%20allowing%20a-,Mach%C2%A00.85,-%28490%C2%A0kn;%20900) is 0.54 [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegars"} or Mach 0.85.

The highway🛣️speed of a car🚗is roughly tenfold slower than the cruising speed of an airplane✈️. If we are driving on a highway🛣️at a speed of 50 [mv]{.tool data-bs-toggle="tooltip" data-bs-title="milliomegars"} and our exit is 1000 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zems"} away, we will have 20 [centimillidays]{.tool data-bs-toggle="tooltip" data-bs-title="hundred thousandths of a day"} until we have to exit the highway🛣️. To ensure we do not miss our exit, we can periodically check a countdown of the remaining [z]{.tool data-bs-toggle="tooltip" data-bs-title="zems"}: \${zLeft}.

# Inverse of b (Iob) {#iob}

Dec refers to [centimillidays]{.tool data-bs-toggle="tooltip" data-bs-title="hundred thousandths of a day"} as [beats]{.tool data-bs-toggle="tooltip" data-bs-title="hundred thousandths of a day"} ([b]{.tool data-bs-toggle="tooltip" data-bs-title="beats"}) because they are similar in duration to heart❤️beats or [musical beats](https://en.wikipedia.org/wiki/Beat_(music)#:~:text=I-,n%20music%20and%20music%20theory%2C%20the%20beat%20is%20the%20basic%20unit%20of%20time,-%2C%20the). A [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"} is 100 [centiday]{.tool data-bs-toggle="tooltip" data-bs-title="hundredths of a day"} ([cd]{.tool data-bs-toggle="tooltip" data-bs-title="centidays"}), [10^5^]{.tool data-bs-toggle="tooltip" data-bs-title="a hundred thousand"} [b]{.tool data-bs-toggle="tooltip" data-bs-title="beats"}, or [10^6^]{.tool data-bs-toggle="tooltip" data-bs-title="a million"} [microdays]{.tool data-bs-toggle="tooltip" data-bs-title="millionths of a day"} ([$\micro\text d$]{.tool data-bs-toggle="tooltip" data-bs-title="microdays"}). One [mc]{.tool data-bs-toggle="tooltip" data-bs-title="millitaur"} is 100 [kilozems]{.tool data-bs-toggle="tooltip" data-bs-title="thousands of zems"} ([kz]{.tool data-bs-toggle="tooltip" data-bs-title="thousands of zems"}), [10^5^]{.tool data-bs-toggle="tooltip" data-bs-title="a hundred thousand"} [z]{.tool data-bs-toggle="tooltip" data-bs-title="zems"}, [10^6^]{.tool data-bs-toggle="tooltip" data-bs-title="a million"} [decizems]{.tool data-bs-toggle="tooltip" data-bs-title="tenths of a zem"} ([dz]{.tool data-bs-toggle="tooltip" data-bs-title="decizems"}), or [10^6^]{.tool data-bs-toggle="tooltip" data-bs-title="a million"} [nanotaurs]{.tool data-bs-toggle="tooltip" data-bs-title="millionths of a taur"} ([nc]{.tool data-bs-toggle="tooltip" data-bs-title="nanotaurs"}). Therefore, [mv]{.tool data-bs-toggle="tooltip" data-bs-title="milliomegar"} = $\text{mc}\over\text d$ = $\text {kz}\over\text {cd}$ = $\text z\over\text b$ = $\text {dz}\over\micro\text d$ = $\text {nc}\over\micro\text d$. A [cd]{.tool data-bs-toggle="tooltip" data-bs-title="centiday"} is [96%]{.color960} of a quarter hour and a [b]{.tool data-bs-toggle="tooltip" data-bs-title="beat"} is [86.4%]{.color864} of a second.

## Beats per milliday (bpm) {.hiddenheading #bpm}

A [normal resting heart❤️rate](https://en.wikipedia.org/wiki/Heart_rate#:~:text=heart%20rate%20is-,60–100%20bpm,-.%20An%20ultra%2Dtrained) is between 100 and 166.[6]{style="text-decoration-line:overline;"} [b]{.tool data-bs-toggle="tooltip" data-bs-title="beats"} per [md]{.tool data-bs-toggle="tooltip" data-bs-title="millidays"} ([BPM]{.tool data-bs-toggle="tooltip" data-bs-title="beats per milliday"}). The unofficial anthem of the Dec measurement system, "[Turn the beat around](https://en.wikipedia.org/wiki/Turn_the_Beat_Around#:~:text=a%20disco%20song%20written%20by%20Gerald%20Jackson%20and%20Peter%20Jackson%2C%20and%20performed%20by%20American%20actress%20and%20singer%20Vicki%20Sue%20Robinson%20in%201976)", has a [tempo](https://en.wikipedia.org/wiki/Tempo#:~:text=the%20speed%20or%20pace%20of%20a%20given%20composition) of 188.64 [BPM]{.tool data-bs-toggle="tooltip" data-bs-title="beats per milliday"}, which corresponds to the _allegro_ [tempo marking](https://en.wikipedia.org/wiki/Tempo#Approximately_from_the_slowest_to_the_fastest). A Dec clock⏰ticks at a rate of 100 [BPM]{.tool data-bs-toggle="tooltip" data-bs-title="beats per milliday"}, $\text b^{-1}$, $1\over\text b$, or 1 [inverse](https://en.wikipedia.org/wiki/Multiplicative_inverse#:~:text=x%2C%20denoted%20by-,1/x%20or%20x%E2%88%921,-%2C%20is%20a%20number)-of-[b]{.tool data-bs-toggle="tooltip" data-bs-title="beat"} ([iob]{.tool data-bs-toggle="tooltip" data-bs-title="inverse-of-b"}), which is [1.15[740]{style="text-decoration-line:overline;"}]{.colorIob} times more frequent than a [Hertz](https://en.wikipedia.org/wiki/Hertz#:~:text=one%20event%20(or%20cycle)).

## Frequency period wavelength {.hiddenheading #fpw}

We can divide one by the sound🔊[frequency](https://en.wikipedia.org/wiki/Frequency#:~:text=the%20number%20of%20occurrences%20of%20a%20repeating%20event%20per%20unit%20of%20time) selected by the "[Iobs]{.tool data-bs-toggle="tooltip" data-bs-title="inverse-of-b"}" range🎚️input below to get its [period](https://en.wikipedia.org/wiki/Frequency#:~:text=the%20reciprocal%20of%20the%20frequency), 1 &div; \${parseFloat((iobs / 1000).toFixed(3))} [kiloiobs]{.tool data-bs-toggle="tooltip" data-bs-title="thousands of iobs"} ([ki]{.tool data-bs-toggle="tooltip" data-bs-title="kiloiobs"}) = \${parseFloat((1000 / iobs).toFixed(3))} [millibeats]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a beat"} ([mb]{.tool data-bs-toggle="tooltip" data-bs-title="millibeats"}), or divide the speed of sound🔊by it to get its [wavelength](https://en.wikipedia.org/wiki/Wavelength#:~:text=the%20distance%20over%20which%20the%20wave%27s%20shape%20repeats): 735048 [microomegars]{.tool data-bs-toggle="tooltip" data-bs-title="millionths of an omegar"} ([$\micro\text v$]{.tool data-bs-toggle="tooltip" data-bs-title="milliomegars"}) &div; \${iobs} [iobs]{.tool data-bs-toggle="tooltip" data-bs-title="inverses-of-b"} ([i]{.tool data-bs-toggle="tooltip" data-bs-title="iobs"}) = \${parseFloat((735048 / iobs).toFixed(2))} [millizem]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a zem"} ([mz]{.tool data-bs-toggle="tooltip" data-bs-title="millizem"}). Press the Play▶️button below to hear the chosen frequency for a duration of \${beats} [b]{.tool data-bs-toggle="tooltip" data-bs-title="beats"}.

```{ojs}
//| echo: false
//| label: iobinput
//| class: freqcomponent
// https://observablehq.com/@freedmand/sounds
viewof iobs = Inputs.range([1, 9999], { step: 1,  value: 380, label: "Iobs" })
```

```{ojs}
//| echo: false
//| label: beatinput
//| class: freqcomponent
// https://observablehq.com/@freedmand/sounds
viewof beats = Inputs.range([1, 999], { step: 1,  value: 1, label: "Beats" })
```

```{ojs}
//| echo: false
//| label: iobplayer
//| class: freqcomponent
// https://observablehq.com/@freedmand/sounds
Play((t) => Math.sin(iobs / .864 * t * 2 * Math.PI), beats * .864)
```

# Ten equal temperament (Xet) {#xet}

The positive (**+**) and negative (**--**) [indexes](https://en.wikipedia.org/wiki/Index#:~:text=an%20integer%20pointer%20into%20an%20array%20data%20structure), [hex]{.tool data-bs-toggle="tooltip" data-bs-title="hexadecimal"} triplets, and [h°]{.tool data-bs-toggle="tooltip" data-bs-title="HSL or HSV degrees"} in the table below are used by Dec to label🏷️groups of ten, like [dods]{.tool data-bs-toggle="tooltip" data-bs-title="days-of-dek"}, "[top of the [dd]{.tool data-bs-toggle="tooltip" data-bs-title="deciday"}](https://en.wiktionary.org/wiki/top_of_the_hour)" [tods]{.tool data-bs-toggle="tooltip" data-bs-title="times-of-day"}, and time zones. In addition to colors🎨, Dec also labels🏷️groups of ten with the [musical notes](https://en.wikipedia.org/wiki/Musical_note#:~:text=Chromatic%20scale,-note%20naming%20conventions) that constitute the Dec [chromatic](https://en.wikipedia.org/wiki/Chromatic_scale#:~:text=a%20set%20of%20twelve%20pitches%20(more%20completely%2C%20pitch%20classes)%20used%20in%20tonal%20music) (Dechromatic) [scale](https://en.wikipedia.org/wiki/Scale_(music)#:~:text=any%20consecutive%20series%20of%20notes%20that%20form%20a%20progression%20between%20one%20note%20and%20its%20octave) of the **Ten** **e**qual **t**emperament ([Tenet]{.tool data-bs-toggle="tooltip" data-bs-title="ten equal temperament"}) musical system.

[Tenet]{.tool data-bs-toggle="tooltip" data-bs-title="ten equal temperament"} ([Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"}) identifies each Dechromatic scale note with a single-digit integer and expresses all other possible sound🔊frequencies as decimal numbers. In contrast, the notes of the [12 equal temperament](https://en.wikipedia.org/wiki/12_equal_temperament#:~:text=the%20musical%20system%20that%20divides%20the%20octave%20into%2012%20parts) ([12ET]{.tool data-bs-toggle="tooltip" data-bs-title="12 equal temperament"}) musical system have names that consist of a letter from [A]{.colorA} to [G]{.colorG} and a symbol such as sharp ([♯]{.iosevka}), half sharp ([𝄲]{.iosevka}), flat ([♭]{.iosevka}), and half flat ([𝄳]{.iosevka}).

The sound🔊frequencies of two consecutive [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} Dechromatic scale notes always differ by one step ([s]{.tool data-bs-toggle="tooltip" data-bs-title="step"}), but the differences between consecutive [12ET]{.tool data-bs-toggle="tooltip" data-bs-title="12 equal temperament"} chromatic scale notes vary from the [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[599]{.color599} [millisteps]{.tool data-bs-toggle="tooltip" data-bs-title="ten thousandths of an octave"} ([ms]{.tool data-bs-toggle="tooltip" data-bs-title="millisteps"}) between [A[♯]{.iosevka}]{.colorAs} and [B]{.colorB} to the [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[1067]{.color067} [ms]{.tool data-bs-toggle="tooltip" data-bs-title="millisteps"} between [G[♯]{.iosevka}]{.colorGs} and [A]{.colorA}. A typical person can reliably distinguish sounds🔊that [differ](https://en.wikipedia.org/wiki/Cent_(music)#:~:text=Normal%20adults%20are%20able%20to%20recognize%20pitch%20differences%20of%20as%20small%20as%2025%20cents%20very%20reliably) by at least [200]{.color2} [ms]{.tool data-bs-toggle="tooltip" data-bs-title="millisteps"}.

The rightmost column of the table below shows the [12ET]{.tool data-bs-toggle="tooltip" data-bs-title="12 equal temperament"} notes that are closest to the [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} Dechromatic scale notes. [12ET]{.tool data-bs-toggle="tooltip" data-bs-title="12 equal temperament"} considers [B[𝄲]{.iosevka}]{.colorBc}, [D[𝄲]{.iosevka}]{.colorDds}, and [E[𝄳]{.iosevka}]{.colorDsE} to be [microtones](https://en.wikipedia.org/wiki/Microtonality#:~:text=intervals%20not%20found%20in%20the%20customary%20Western%20tuning%20of%20twelve%20equal%20intervals%20per%20octave). The sound🔊frequency differences between the nearest [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} and [12ET]{.tool data-bs-toggle="tooltip" data-bs-title="12 equal temperament"} notes in the table range from the [8]{.color008} [ms]{.tool data-bs-toggle="tooltip" data-bs-title="millisteps"} between Notes [9]{.color9} and [A]{.colorA} to the [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[87]{.color26div300} [ms]{.tool data-bs-toggle="tooltip" data-bs-title="millisteps"} between Notes [5]{.color5} and [F]{.colorF}.

## Color sound table {.hiddenheading #cst}

{{< include /dec/_notetable.qmd >}}

## Octave + note = tone {.hiddenheading #ont}

The image above applies Dec color🎨labels🏷️to one [octave](https://en.wikipedia.org/wiki/Octave#:~:text=the%20interval%20between%20one%20musical%20pitch%20and%20another%20with%20double%20or%20half%20its%20frequency) of piano🎹keys. In [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"}, an octave is 10 [s]{.tool data-bs-toggle="tooltip" data-bs-title="steps"} or 10^4^ [ms]{.tool data-bs-toggle="tooltip" data-bs-title="millisteps"}. The text below the image provides from top to bottom the [scientific pitch name](https://en.wikipedia.org/wiki/Scientific_pitch_notation#:~:text=a%20method%20of%20specifying%20musical%20pitch%20by%20combining%20a%20musical%20note%20name%20(with%20accidental%20if%20needed)%20and%20a%20number%20identifying%20the%20pitch%27s%20octave), integer [i]{.tool data-bs-toggle="tooltip" data-bs-title="iob"} sound🔊frequency, and integer [mz]{.tool data-bs-toggle="tooltip" data-bs-title="millizem"} wavelength of the corresponding white key. As octave indexes and frequency increase, wavelength decreases.

Octave indexes in [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} and [12ET]{.tool data-bs-toggle="tooltip" data-bs-title="12 equal temperament"} match except for [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} notes with indexes below [2]{.color2} and [12ET]{.tool data-bs-toggle="tooltip" data-bs-title="12 equal temperament"} notes from [A[♯]{.iosevka}]{.colorAs} to [B[𝄲]{.iosevka}]{.colorB}. From the perspective of [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"}, all of the labeled🏷️keys in the image above are in Octave [4]{.color4}. When we append a positive note index that is less than ten to an octave index which is a positive integer, we obtain a [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} [musical tone](https://en.wikipedia.org/wiki/Musical_tone#:~:text=a%20steady%20periodic%20sound) index.

The tone indexes of the the labeled🏷️keys in the image above range from [40.069]{.colorAs3} to [49.008]{.colorA4}. Tone [49.008]{.colorA4} is [A4]{.colorA4}, the [A]{.colorA} note widely used to [tune musical instruments](https://en.wikipedia.org/wiki/Concert_pitch#:~:text=the%20pitch%20reference%20to%20which%20a%20group%20of%20musical%20instruments%20are%20tuned%20for%20a%20performance). Tone [41.302]{.colorC4} is [C4]{.colorC4}, the "[Middle [C]{.colorC}](https://en.wikipedia.org/wiki/C_(musical_note)#Middle_C:~:text=above%20the%20top%20line%20of%20the%20bass%20staff%20or%20below%20the%20bottom%20line%20of%20the%20treble%20staff)" in between the [bass](https://en.wikipedia.org/wiki/Clef#Bass_clef) and [treble](https://en.wikipedia.org/wiki/Clef#:~:text=the%20most%20common%20clef%20in%20use%20and%20is%20generally%20the%20first%20clef%20learned%20by%20music%20students)🎼[clefs](https://en.wikipedia.org/wiki/Clef#:~:text=a%20musical%20symbol%20used%20to%20indicate%20which%20notes%20are%20represented%20by%20the%20lines%20and%20spaces%20on%20a%20musical%20staff) of a [grand staff](https://en.wikipedia.org/wiki/Staff_(music)#Grand_staff). The typical [audible](https://en.wikipedia.org/wiki/Hearing_range#:~:text=the%20frequency%20range%20that%20can%20be%20heard%20by%20humans) range for humans extends from Tone [03]{.color030} to Tone [104]{.color040}.

By default, each [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} note or tone lasts one musical beat. [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} modifies the duration of notes and tones by appending &times; and a multiplier or &div; and a divisor. The first two [measures](https://en.wikipedia.org/wiki/Bar_(music)#:~:text=a%20segment%20of%20music) of the [chorus](https://en.wikipedia.org/wiki/Chorus#:~:text=the%20part%20of%20a%20song%20that%20is%20repeated%20several%20times) from "[Turn the beat around](https://en.wikipedia.org/wiki/Turn_the_Beat_Around#:~:text=a%20disco%20song%20written%20by%20Gerald%20Jackson%20and%20Peter%20Jackson%2C%20and%20performed%20by%20American%20actress%20and%20singer%20Vicki%20Sue%20Robinson%20in%201976)" are shown below and can be expressed in [Xet]{.tool data-bs-toggle="tooltip" data-bs-title="Tenet"} as Octave [4]{.color4} and a series of notes followed by a rest (&empty;): [9]{.color9} [9]{.color9}&div;2 [8]{.color8} [8]{.color8} [6]{.color6}&times;4 &empty;.

{{< include /dec/_chorus.qmd >}}

# US customary units {#ucu}

The [unit conversion](https://en.wikipedia.org/wiki/Conversion_of_units#:~:text=the%20conversion%20of%20the%20unit%20of%20measurement%20in%20which%20a%20quantity%20is%20expressed) table below shows the [United States🇺🇸(US) customary units](https://en.wikipedia.org/wiki/Imperial_and_US_customary_measurement_systems) that Dec redefines. The values in the first column are approximate [fold changes](https://en.wikipedia.org/wiki/Fold_change#:~:text=measure%20describing%20how%20much%20a%20quantity%20changes%20between%20an%20original%20and%20a%20subsequent%20measurement) from original to redefined units. A fold change of [1]{.color0} means [0]{.color0} [change](https://en.wikipedia.org/wiki/Relative_change#:~:text=compare%20two%20quantities%20while%20taking%20into%20account%20the%20%22sizes%22%20of%20the%20things%20being%20compared). Identical fold changes indicate [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary units derived from the same Dec and [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units#:~:text=the%20world%27s%20most%20widely%20used%20system%20of%20measurement) ([SI]{.tool data-bs-toggle="tooltip" data-bs-title="International System of Units"}) units.

## Unit conversion table {.hiddenheading #uct}

{{< include /dec/_kegtable.qmd >}}

## Miles per hour (mph) {.hiddenheading #mph}

Unlike Dec and [SI]{.tool data-bs-toggle="tooltip" data-bs-title="International System of Units"}, the [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary measurement system does not use metric prefixes to scale units by [powers of ten](https://en.wikipedia.org/wiki/Power_of_10#:~:text=any%20of%20the%20integer%20powers%20of%20the%20number%20ten). Redefined [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary units serve as convenient reference points. [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary volume units have intuitive names and scale by [powers of two](https://en.wikipedia.org/wiki/Power_of_two#:~:text=a%20number%20of%20the%20form%202n%20where%20n%20is%20an%20integer). Miles are redefined such that 1 mile per hour is equal to 1 [mv]{.tool data-bs-toggle="tooltip" data-bs-title="milliomegar"} or $5\over3$ [kilometers]{.tool data-bs-toggle="tooltip" data-bs-title="thousands of meters"} ([km]{.tool data-bs-toggle="tooltip" data-bs-title="kilometers"}) per hour.

## Hexamilliare wineglass keg {.hiddenheading #xwk}

A square [kilozem]{.tool data-bs-toggle="tooltip" data-bs-title="a thousand zems"} ([kz^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square kilozem"}) is 1 [hexakilare]{.tool data-bs-toggle="tooltip" data-bs-title="sixteen hundred ares"}, 16 [hectares]{.tool data-bs-toggle="tooltip" data-bs-title="hundreds of ares"}, 1600 [ares](https://en.wikipedia.org/wiki/Hectare#Are), 40 Dec acres, 0.16 square [kilometers]{.tool data-bs-toggle="tooltip" data-bs-title="thousands of meters"} ([km^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square kilometers"}), [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}0.062 Dec square miles, or [10^6^]{.tool data-bs-toggle="tooltip" data-bs-title="a million"} [z^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square zems"}. A [z^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square zem"} is a [hexamilliare]{.tool data-bs-toggle="tooltip" data-bs-title="1.6 thousandth of an are"} ([x]{.tool data-bs-toggle="tooltip" data-bs-title="hexamilliares"}), 16 square [decimeters]{.tool data-bs-toggle="tooltip" data-bs-title="tenths of a meter"} ([dm^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square decimeters"}), 1.[7]{style="text-decoration-line:overline;"} Dec square feet🦶, or 256 Dec square inches. A square [decazem]{.tool data-bs-toggle="tooltip" data-bs-title="ten zem"} ([Dz^2^]{.tool data-bs-toggle="tooltip" data-bs-title="square decazem"}) is 1 [hexadeciare]{.tool data-bs-toggle="tooltip" data-bs-title="sixteen hundredths of an are"}, 16 square meters ([m²]{.tool data-bs-toggle="tooltip" data-bs-title="square meters"}), [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}19.75 Dec square yards, or 100 [x]{.tool data-bs-toggle="tooltip" data-bs-title="hexamilliares"}.

A cubic [decizem]{.tool data-bs-toggle="tooltip" data-bs-title="a tenth of a zone equatorial meter"} ([dz^3^]{.tool data-bs-toggle="tooltip" data-bs-title="cubic decizem"}) is 1 cubic [nanotaur]{.tool data-bs-toggle="tooltip" data-bs-title="a millionth of a taur"} ([nc^3^]{.tool data-bs-toggle="tooltip" data-bs-title="cubic nanotaur"}), 2 Dec ounces, or 64 [milliliters]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a liter"} ([mL]{.tool data-bs-toggle="tooltip" data-bs-title="milliliters"}). A [dz^3^]{.tool data-bs-toggle="tooltip" data-bs-title="cubic decizem"} of water🌊weighs 64 grams ([g]{.tool data-bs-toggle="tooltip" data-bs-title="grams"}). Even though a Dec ounce of water🌊weighs close to a sixteenth of a Dec pound, Dec does not measure weights in ounces. A [z^3^]{.tool data-bs-toggle="tooltip" data-bs-title="cubic zem"} is 16 Dec gallons or 64 [liters](https://en.wikipedia.org/wiki/Litre#:~:text=is%20equal%20to-,1%20cubic%20decimetre,-(dm3)%2C%201000%20cubic) ([L]{.tool data-bs-toggle="tooltip" data-bs-title="liters"}). A [z^3^]{.tool data-bs-toggle="tooltip" data-bs-title="cubic zem"} of water🌊weighs 64 [kilograms]{.tool data-bs-toggle="tooltip" data-bs-title="thousands of grams"} ([kg]{.tool data-bs-toggle="tooltip" data-bs-title="kilograms"}) or 128 Dec pounds.

:::{.column-margin fig-align="center" style="text-align:center;"}
![](../asset/vitruvianMan.svg){#vitruvian}
[Wikimedia](https://commons.wikimedia.org/wiki/File:Da_Vinci_Vitruve_Luc_Viatour_2.svg)
:::

## Body mass index (bmi) {.hiddenheading #bmi}

If [Leonardo da Vinci](https://en.wikipedia.org/wiki/Leonardo_da_Vinci#:~:text=an%20Italian%20polymath%20of%20the%20High%20Renaissance)'s [Vitruvian Man](https://en.wikipedia.org/wiki/Vitruvian_Man#:~:text=a%20drawing%20by%20the%20Italian%20Renaissance%20artist%20and%20scientist%20Leonardo%20da%20Vinci) were 4 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zems"} tall, we could measure 1 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"} from his knees to his feet🦶or from his elbows💪to his fingertips. If he also weighed 64 [kg]{.tool data-bs-toggle="tooltip" data-bs-title="kilograms"}, his [Body Mass Index](https://en.wikipedia.org/wiki/Body_mass_index#:~:text=the%20body%20mass%20divided%20by%20the%20square%20of%20the%20body%20height) ([BMI]{.tool data-bs-toggle="tooltip" data-bs-title="body mass index"}) would be 4 $\text {kg}\over\text z^2$ or 25 $\text {kg}\over\text m^2$. A normal [BMI]{.tool data-bs-toggle="tooltip" data-bs-title="body mass index"} ranges from 2.96 to 4 $\text {kg}\over\text z^2$ or 18.5 to 25 $\text {kg}\over\text m^2$. A [BMI]{.tool data-bs-toggle="tooltip" data-bs-title="body mass index"} of \${kg} kg &div; \${zem2} z^2^ = \${bmi} $\text {kg}\over\text z^2$ = ${bmim2} $\text {kg}\over\text m^2$ is considered \${bmiStr}.

```{ojs}
//| echo: false
//| label: kginput
viewof kilograms = Inputs.range([0, 1000], {label: "Kilograms", value: 64, step: .1})
```

```{ojs}
//| echo: false
//| label: zinput
viewof zems = Inputs.range([0, 10], {label: "Zems", value: 4, step: 0.01})
```

## Centizem centimeter inch {.hiddenheading #cci}

::: {.column-page-right fig-align="left" style="text-align:center;font-size:.825rem;"}
![](../asset/ruler1dz.svg){#ruler}
[Wikimedia](https://commons.wikimedia.org/wiki/File:Ruler_illustration.svg)
:::

The longest length depicted in the image of a ruler📏above is 1 [dz]{.tool data-bs-toggle="tooltip" data-bs-title="decizem"}, 1 [nc]{.tool data-bs-toggle="tooltip" data-bs-title="nanotaur"}, 4 [centimeters]{.tool data-bs-toggle="tooltip" data-bs-title="hundredths of a meter"} ([cm]{.tool data-bs-toggle="tooltip" data-bs-title="centimeters"}), or $8\over5$ Dec inches, and the shortest length is $1\over2$ [mz]{.tool data-bs-toggle="tooltip" data-bs-title="millizems"}, $1\over5$ [millimeters]{.tool data-bs-toggle="tooltip" data-bs-title="thousandths of a meter"} ([mm]{.tool data-bs-toggle="tooltip" data-bs-title="millimeters"}), $1\over125$ Dec inches, or $1\over127$ [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary inches. A [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary inch is $127\over2$ [mz]{.tool data-bs-toggle="tooltip" data-bs-title="millizems"}, $127\over5$ [mm]{.tool data-bs-toggle="tooltip" data-bs-title="millimeters"}, or $127\over125$ Dec inches. A Dec inch is $5\over2$ [cm]{.tool data-bs-toggle="tooltip" data-bs-title="centimeters"}. A [cm]{.tool data-bs-toggle="tooltip" data-bs-title="centimeter"} is $5\over2$ [cz]{.tool data-bs-toggle="tooltip" data-bs-title="centizems"}. A [z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"} is 4 [dm]{.tool data-bs-toggle="tooltip" data-bs-title="decimeters"}. A [dm]{.tool data-bs-toggle="tooltip" data-bs-title="decimeter"} is 4 Dec inches.

# Summary {#tldr}

This article introduces the Dec measurement system and describes how Dec uses metric prefixes and the properties of the planet Earth🌍to define units based on turns for geographic coordinates, compass🧭directions, dates, times, speeds, distances, areas, volumes, and weights. Each unit has a unique name, such as [$\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="parallel"}, [$\phi$]{.tool data-bs-toggle="tooltip" data-bs-title="meridian"}, [$\alpha$]{.tool data-bs-toggle="tooltip" data-bs-title="windrose"}, [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"}, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}, [b]{.tool data-bs-toggle="tooltip" data-bs-title="beat"}, [v]{.tool data-bs-toggle="tooltip" data-bs-title="omegar"}, [c]{.tool data-bs-toggle="tooltip" data-bs-title="taur"}, [z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"}, or [x]{.tool data-bs-toggle="tooltip" data-bs-title="hexamilliare"}.

Dec attempts to bridge the gap, improve interoperability, and faciliate conversion between the [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary and [SI]{.tool data-bs-toggle="tooltip" data-bs-title="International System of Units"} measurement systems by redefining [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary units. Redefinition of [US]{.tool data-bs-toggle="tooltip" data-bs-title="United States"} customary units makes inches [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[1.58%]{.color0158} shorter, miles [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[3.56%]{.colorMile} longer, pints [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[5.67%]{.colorPint} larger, ounces [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[8.21%]{.colorFlOz} larger, and pounds [~]{.tool data-bs-toggle="tooltip" data-bs-title="approximately"}[10.23%]{.colorAvLb} heavier.

Dec color🎨labels🏷️can convey an impression of many different kinds of values at a glance. Moreover, color🎨labels🏷️help avoid confusion when dealing with different metric prefixes. The current [tod]{.tool data-bs-toggle="tooltip" data-bs-title="time-of-day"} in Zone \${decOffsetHsl3} can be expressed as \${decTimeOffHsl1} [dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"}, \${decTimeOffHsl2} days, or \${decTimeOffHsl3} [b]{.tool data-bs-toggle="tooltip" data-bs-title="beats"}. Metric prefixes allow us to shift the [decimal separator](https://en.wikipedia.org/wiki/Decimal_separator#:~:text=In%20English%2Dspeaking%20countries%2C%20the%20decimal%20point%20is%20usually%20a%20small%20dot%20%28.%29%20placed%20either%20on%20the%20baseline) in [decimal](https://en.wikipedia.org/wiki/Decimal) numbers.

# Next{#next}

Now that you have had a taste of Dec, I hope that you are hungry for more! If so, dive🤿deeper into Dec [dates](/dec/date) and [times](/dec/time) before tackling Dec [snaps](/dec/snap)🫰and [spans](/dec/span)🌈. My [filter](/quarto/filter), [include](/quarto/include), and [script](/quarto/script) articles discuss the [Quarto](/quarto) publishing system and how I display Dec [dates](/dec/date) in the [navigation bar](https://en.wikipedia.org/wiki/Navigation_bar#:~:text=a%20section%20of%20a%20graphical%20user%20interface%20intended%20to%20aid%20visitors%20in%20accessing%20information), [title block](https://quarto.org/docs/authoring/title-blocks.html), and [citation section](#citation) of each article on my website.

:::{#firstnav}
{{< include /asset/_decquanav.qmd >}}
:::

# Cite

Please support Dec by citing it as shown at the bottom of this article. Listed below are citations for the [Observable](http://observablehq.com) notebooks that I adapted into the map🗺️, color🎨wheel compass🧭, and other visualizations above. The list also includes citations for three works that predate the [French Revolution](https://en.wikipedia.org/wiki/French_Revolution#:~:text=a%20period%20of%20political%20and%20societal%20change%20in%20France%20which%20began%20with%20the%20Estates%20General%20of%201789%20and%20ended%20with%20the%20Coup%20of%2018%20Brumaire%20on%209%20November%201799) and three more recent articles published on websites.

In his [1704]{.color704} book entitled [Optiks](https://en.wikipedia.org/wiki/Opticks#:~:text=a%20collection%20of%20three%20books%20by%20Isaac%20Newton), [Isaac Newton](https://en.wikipedia.org/wiki/Isaac_Newton#:~:text=,an%20English%20polymath,-active%20as%20a) presented the first [color🎨wheel](https://en.wikipedia.org/wiki/Color_wheel#:~:text=Newton's%20asymmetric%20color%20wheel%20based%20on%20musical%20intervals) and linked its colors🎨to musical notes. On [[2025]{.color025}[+]{style="font-family:monospace;"}[080]{.colorD080}]{.tool data-bs-toggle="tooltip" data-bs-title="May 20, 2025"}, I read [The Color of Sound](https://www.flutopedia.com/sound_color.htm) by [Clint Goss](https://www.clintgoss.com), which presents a method of connecting musical notes to colors🎨via their frequencies. The note and color🎨pairs in that article are similar to those of the Dechromatic scale.

In [1754]{.color754}, [Jean le Rond d'Alembert](https://en.wikipedia.org/wiki/Jean_le_Rond_d%27Alembert#:~:text=French%20mathematician%2C%20mechanician%2C%20physicist%2C%20philosopher%2C%20and%20music%20theorist) lauded the benefits of [decimalisation](https://en.wikipedia.org/wiki/Decimalisation#:~:text=t-,he%20conversion%20of%20a%20system%20of%20currency%20or%20of%20weights%20and%20measures%20to%20units%20related%20by%20powers%20of%2010). In [1788]{.color788}, [Claude Boniface Collignon](https://en.wikipedia.org/wiki/Claude_Boniface_Collignon#:~:text=a%20French%20attorney%20who%20contributed%20to%20scientific%20and%20social%20reforms%20in%20the%20time%20of%20the%20French%20Revolution) proposed measuring length in [dz]{.tool data-bs-toggle="tooltip" data-bs-title="decizems"} or [nc]{.tool data-bs-toggle="tooltip" data-bs-title="nanotaurs"} and tracking time in [deks]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"}, [dd]{.tool data-bs-toggle="tooltip" data-bs-title="decidays"}, [md]{.tool data-bs-toggle="tooltip" data-bs-title="millidays"}, [$\micro\text d$]{.tool data-bs-toggle="tooltip" data-bs-title="microdays"}, and [nanodays]{.tool data-bs-toggle="tooltip" data-bs-title="billionths of a day"} ([nd]{.tool data-bs-toggle="tooltip" data-bs-title="nanodays"}). On [[2025]{.color025}[+]{style="font-family:monospace;"}[039]{.colorD039}]{.tool data-bs-toggle="tooltip" data-bs-title="April 9, 2025"}, I saw the definition of a [zem]{.tool data-bs-toggle="tooltip" data-bs-title="zone equatorial meter"}, 1 [z]{.tool data-bs-toggle="tooltip" data-bs-title="zem"} = [10^-8^]{.tool data-bs-toggle="tooltip" data-bs-title="a hundred millionth"} [c]{.tool data-bs-toggle="tooltip" data-bs-title="taurs"} = 40 [cm]{.tool data-bs-toggle="tooltip" data-bs-title="centimeters"}, in a table of [ten possible length units](https://www.roma1.infn.it/~dagos/history/sm/node12.html) from a [2004]{.color004} [arxiv](https://arxiv.org/abs/physics/0412078) [article](https://www.roma1.infn.it/~dagos/history/sm/sm.html).

The fundamental properties of Dec dates are defined by algorithms developed by [Howard Hinnant](https://howardhinnant.github.io) and described in his [2021]{.color021} article entitled [[`chrono`]{.mono .under}-Compatible Low-Level Date Algorithms](https://howardhinnant.github.io/date_algorithms.html).
On [[2024]{.color024}[+]{style="font-family:monospace;"}[285]{.colorD285}]{.tool data-bs-toggle="tooltip" data-bs-title="December 11, 2024"}, I found a [2014]{.color014} article which proposed a [decimal time](https://en.wikipedia.org/wiki/Decimal_time#:~:text=the%20representation%20of%20the%20time%20of%20day%20using%20units%20which%20are%20decimally%20related) system with twenty time zones, each five [cd]{.tool data-bs-toggle="tooltip" data-bs-title="centidays"} wide, based on [Longitude 05](https://en.wikipedia.org/wiki/Prime_meridian_(Greenwich)#:~:text=a%20geographical%20reference%20line%20that%20passes%20through%20the%20Royal%20Observatory%2C%20Greenwich%2C%20in%20London%2C%20England) ([50]{.color050} [$\text m\lambda$]{.tool data-bs-toggle="tooltip" data-bs-title="milliparallels"}).

::: {.column-page-right #citelist}
- [Agnoli, Paolo](http://www.paoloagnoli.it) & [D'Agostini, Giulio](https://www.roma1.infn.it/~dagos). [2004+330]{.tool data-bs-toggle="tooltip" data-bs-title="January 25, 2005"}. “Why does the meter beat the second?” \${decYearP0}+\${decDotyOff}. <https://arxiv.org/abs/physics/0412078>.
- [Armstrong, Zan](https://observablehq.com/@zanarmstrong) [2023+057]{.tool data-bs-toggle="tooltip" data-bs-title="April 27, 2023"}. “Text color annotations in markdown.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@observablehq/text-color-annotations-in-markdown>.
- [Bostock, Mike](https://observablehq.com/@mbostock) [2020+335]{.tool data-bs-toggle="tooltip" data-bs-title="January 30, 2021"}. “Time Zones.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@mbostock/time-zones>.
- [Bostock, Mike](https://observablehq.com/@mbostock) [2022+037]{.tool data-bs-toggle="tooltip" data-bs-title="April 7, 2022"}. “Solar Terminator.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@d3/solar-terminator>.
- [Bostock, Mike](https://observablehq.com/@mbostock) [2023+314]{.tool data-bs-toggle="tooltip" data-bs-title="January 9, 2024"}. “Input: Table.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@observablehq/input-table>.
- [Clements, John](https://www.brinckerhoff.org). [2014+091]{.tool data-bs-toggle="tooltip" data-bs-title="May 31, 2014"}, “Decimal Time Zones.” \${decYearP0}+\${decDotyOff}. <https://www.brinckerhoff.org/blog/2014/05/31/decimal-time-zones>.
- [Clint Goss](https://www.clintgoss.com). [2022+098]{.tool data-bs-toggle="tooltip" data-bs-title="June 7, 2022"}. “Color of Sound.” \${decYearP0}+\${decDotyOff}. <https://www.flutopedia.com/sound_color.htm>.
- [Collignon, Claude Boniface](https://en.wikipedia.org/wiki/Claude_Boniface_Collignon#:~:text=a%20French%20attorney%20who%20contributed%20to%20scientific%20and%20social%20reforms%20in%20the%20time%20of%20the%20French%20Revolution). 1788. “Découverte d'étalons justes, naturels, invariables et universels.” \${decYearP0}+\${decDotyOff}. <https://archive.org/details/dcouvertedtalon00collgoog/page/n68/mode/2up>.
- [Edwards, Paul](https://observablehq.com/@pjedwards). [2022+171]{.tool data-bs-toggle="tooltip" data-bs-title="August 19, 2022"}. “Compass Rose as legend with colors.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@pjedwards/compass-rose-as-legend-with-colors>.
- [Freedman, Dylan](https://observablehq.com/@freedmand). [2017+345]{.tool data-bs-toggle="tooltip" data-bs-title="February 9, 2018"}. “Sounds.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@freedmand/sounds>.
- [Gordon, Marcus A.](https://observablehq.com/@magfoto). [2018+288]{.tool data-bs-toggle="tooltip" data-bs-title="December 14, 2018"}. “Wavelengths and Spectral Colours.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@magfoto/wavelengths-and-spectral-colours>.
- [Harmath, Dénes](https://observablehq.com/user/@thsoft). [2018+104]{.tool data-bs-toggle="tooltip" data-bs-title="June 13, 2018"}. “ABC.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@thsoft/abc>.
- [Hinnant, Howard](https://howardhinnant.github.io). [2021+184]{.tool data-bs-toggle="tooltip" data-bs-title="September 1, 2021"}. “`chrono`-Compatible Low-Level Date Algorithms.” \${decYearP0}+\${decDotyOff}. <https://howardhinnant.github.io/date_algorithms.html>.
- [Johnson, Ian](https://observablehq.com/@enjalot) [2021+121]{.tool data-bs-toggle="tooltip" data-bs-title="June 30, 2021"}. “Draggable World Map Coordinates Input.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@enjalot/draggable-world-map-coordinates-input>.
- [Lim, Maddie](https://observablehq.com/@maddievision) [2018+330]{.tool data-bs-toggle="tooltip" data-bs-title="January 25, 2019"}. “Enneagram.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@maddievision/enneagram>.
- [Newton, Issac](https://en.wikipedia.org/wiki/Isaac_Newton#:~:text=,an%20English%20polymath,-active%20as%20a). 1704. “Opticks.” \${decYearP0}+\${decDotyOff}. <https://doi.org/10.5479/sil.302475.39088000644674>.
- [Paavanb](https://observablehq.com/@paavanb). [2024+006]{.tool data-bs-toggle="tooltip" data-bs-title="March 7, 2024"}. “Progressive Color Picker.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@paavanb/progressive-color-picker>.
- [Patel, Amit](https://observablehq.com/@redblobgames). [2021+290]{.tool data-bs-toggle="tooltip" data-bs-title="December 16, 2021"}. “Compass Rose.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@paavanb/progressive-color-picker>.
- [Pettiross, Jeff](https://observablehq.com/@pettiross) [2024+150]{.tool data-bs-toggle="tooltip" data-bs-title="July 19, 2024"}. “Categorical color scheme test tool.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@observablehq/categorical-palette-tool>
- [Rieder, Lukas](https://observablehq.com/@lukasrieder) [2023+032]{.tool data-bs-toggle="tooltip" data-bs-title="April 2, 2023"}. “Editable table.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@parlant/editable-table>.
- [Rivière, Philippe](https://observablehq.com/@fil) [2022+259]{.tool data-bs-toggle="tooltip" data-bs-title="November 15, 2022"}. “Add a class to an observable input.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@recifs/add-a-class-to-an-observable-input--support>.
- [Rivière, Philippe](https://observablehq.com/@fil) [2023+330]{.tool data-bs-toggle="tooltip" data-bs-title="January 25, 2024"}. “D3 Projections.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@fil/d3-projections>.
- [Yamahata, Christophe](https://observablehq.com/@christophe-yamahata) [2021+119]{.tool data-bs-toggle="tooltip" data-bs-title="June 28, 2022"}. “Great circle: shortest distance between two locations on Earth 🌏.” \${decYearP0}+\${decDotyOff}. <https://observablehq.com/@christophe-yamahata/great-circle-shortest-distance-between-two-locations-on-ea>.
- [d'Alembert, Jean le Rond ](https://en.wikipedia.org/wiki/Jean_le_Rond_d%27Alembert#:~:text=French%20mathematician%2C%20mechanician%2C%20physicist%2C%20philosopher%2C%20and%20music%20theorist). 1754. “Decimal.” [_Encyclopédie_](https://en.wikipedia.org/wiki/Encyclopédie#:~:text=a%20general%20encyclopedia%20published%20in%20France%20between%201751%20and%201772), _4_, 670. \${decYearP0}+\${decDotyOff}. <https://artflsrv04.uchicago.edu/philologic4.7/encyclopedie0922/navigate/4/3458>.
:::

{{< include /dec/_index.qmd >}}

© Copyright 2025, Martin Laptev

 
  • View source