// Chrome 155 vs 156: paste into the DevTools console on any https:// page and press Enter.
// Each line prints "<change> <check> = <value>". Expected values: clearcotelabs.com/chrome-releases/156
(async () => {
const checks = [
["grease-brand", () => navigator.userAgentData.brands.map((b) => `${b.brand};v=${b.version}`).join(', ')],
["tzdata-2026e", () => new Intl.DateTimeFormat('en-US', { timeZone: 'America/Inuvik', timeZoneName: 'longOffset' }).formatToParts(Date.UTC(2026, 10, 15)).find((p) => p.type === 'timeZoneName').value],
["tzdata-2026e", () => new Intl.DateTimeFormat('en-US', { timeZone: 'EST5EDT' }).resolvedOptions().timeZone],
["tzdata-2026e", () => new Date(Date.UTC(1992, 4, 2, 5, 30)).toLocaleString('en-US', { timeZone: 'America/Bogota' })],
["rtc-diagnostic-logging", () => typeof RTCPeerConnection.startDiagnosticLogging],
["rtc-diagnostic-logging", () => Object.getOwnPropertyNames(RTCPeerConnection).length],
["css-random", () => CSS.supports('width', 'random(1px, 2px)')],
["import-text", () => import('data:text/plain,cc156', { with: { type: 'text' } }).then((m) => m.default, (e) => e.name)],
["xml-parser-rust", () => new DOMParser().parseFromString('<a><b></a>', 'application/xml').querySelector('parsererror div').textContent.trim()],
["window-property-order", () => Object.getOwnPropertyNames(window)[Object.getOwnPropertyNames(window).indexOf('Clipboard') + 1]],
["window-property-order", () => Object.getOwnPropertyNames(window)[Object.getOwnPropertyNames(window).indexOf('ServiceWorkerContainer') + 1]],
["timezone-offset-fractional", () => Number.isInteger(new Date(Date.UTC(1653, 1, 10, 6, 13, 20)).getTimezoneOffset())],
["postmessage-delegate", () => (() => { let read = false; new MessageChannel().port1.postMessage(0, { get delegate() { read = true; } }); return read; })()],
["postmessage-delegate", () => (() => { const keys = []; window.postMessage(0, new Proxy({}, { get: (t, k) => { keys.push(String(k)); } })); return keys.join(); })()],
["css-scroll-snap-pair", () => CSS.supports('scroll-snap-type', 'pair mandatory')],
["css-single-axis-overflow", () => (() => { const d = document.body.appendChild(document.createElement('div')); d.style.overflow = 'clip auto'; const v = getComputedStyle(d).overflowX; d.remove(); return v; })()],
["css-navigation-source", () => CSS.supports('selector(:navigation-source)')],
["canvas-direction-inherit", () => document.createElement('canvas').getContext('2d').direction],
["radio-border-radius", () => (() => { const r = document.body.appendChild(document.createElement('input')); r.type = 'radio'; const v = getComputedStyle(r).borderTopLeftRadius; r.remove(); return v; })()],
["streams-pipeto-disturbed", () => (() => { const r = new Response('x'); r.body.pipeTo(new WritableStream({}, { highWaterMark: 0 })); return r.bodyUsed; })()],
["webcodecs-audio-config", () => AudioDecoder.isConfigSupported({ codec: 'flac', sampleRate: 48e3, numberOfChannels: 2 }).then((r) => r.supported, (e) => e.name)],
["regexp-fixes", () => /^Ā(..)\1$/iu.test('ĀßSsß')],
["regexp-fixes", () => /(?<=(ba|a|c))x/.exec('bax')[1]],
["regexp-fixes", () => /^(?:ſa|sb|ſc|sd)$/i.test('sb')],
["xslt-banner-transform", () => /This site uses XSLT/.test(new XMLSerializer().serializeToString(((p) => (p.importStylesheet(new DOMParser().parseFromString('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"><html><body><p><xsl:value-of select="r/v"/></p></body></html></xsl:template></xsl:stylesheet>', 'application/xml')), p.transformToDocument(new DOMParser().parseFromString('<r><v>1</v></r>', 'application/xml'))))(new XSLTProcessor())))],
["temporal-non-gregorian", () => Temporal.PlainDate.from('2026-08-27').toLocaleString('zh-CN-u-ca-chinese', { dateStyle: 'long' }) === new Date(Date.UTC(2026, 7, 27)).toLocaleDateString('zh-CN-u-ca-chinese', { dateStyle: 'long', timeZone: 'UTC' })],
["html-cdata-foreign-fragment", () => (() => { const p = document.createElementNS('http://www.w3.org/2000/svg', 'path'); p.innerHTML = '<![CDATA[y]]>'; return p.textContent; })()],
["capitalize-supplementary", () => (() => { const p = document.body.appendChild(document.createElement('p')); p.style.textTransform = 'capitalize'; p.innerHTML = '𝐀<span>bc def</span>'; const t = p.innerText; p.remove(); return t; })()],
["class-escaped-get-set", () => (() => { try { return Object.keys(new (eval('(class { g\\u0065t\n a; })'))()).join(); } catch (e) { return e.name; } })()],
];
const out = [];
for (const [id, f] of checks) {
let v;
try { v = await f(); } catch (e) { v = "throws " + e.name; }
const expr = f.toString().replace(/^\(\)\s*=>\s*/, "");
out.push(id.padEnd(28) + expr + " = " + (typeof v === "string" ? JSON.stringify(v) : String(v)));
}
console.log(out.join("\n"));
})();