PageSourceSearch

https://warriorlifepodcast.com/demo/demo-radio-setup.js?v=b6db0e8921ac

js warriorlifepodcast.com collected 2026-10-09 01:09:46 UTC 5,259 bytes, 77 lines download raw bytes

1/* In-memory adapter for the shared setup wizard. Never performs network I/O. */
2(() => {
3  "use strict";
4  if (!window.dccDemoMode) return;
5  const snapshot = window.dccDemoRadioCatalog;
6  if (!snapshot) throw new Error("The offline Hamlib catalog is missing");
7  const clone = value => JSON.parse(JSON.stringify(value));
8  const audio = ["DEMO_RADIO", "DEMO_INTERFACE"].map((device_id, index) => ({
9    device_id, label: index ? "Sample external audio interface" : "Sample radio USB audio",
10    capture_device: `plughw:CARD=${device_id},DEV=0`, playback_device: `plughw:CARD=${device_id},DEV=0`,
11    likely_radio_audio: true
12  }));
13  let current = {model_id: 3085, connection_type: "serial", rig_port: "/dev/ttyUSB0",
14    baud: "auto", ptt: "RIG", hamlib_settings: {}, audio_device: audio[0].capture_device,
15    playback_device: audio[0].playback_device};
16  const saved = window.dccReadDemoSetting?.("radio-configuration", null);
17  if (saved && snapshot.models.some(model => model.model_id === saved.model_id)) current = {...current, ...saved};
18  let status = {state: "idle", schema_version: 2, simulated: true};
19
20  function validate(request) {
21    const model = snapshot.models.find(item => item.model_id === request.model_id);
22    if (!model) throw new Error("Select a radio from the Hamlib catalog");
23    if (!request.rig_port?.trim()) throw new Error("Enter a sample CAT device or network address");
24    if (["network", "rigctld"].includes(request.connection_type) && !/^(?:[\w.-]+|\[[\da-f:.]+\]):\d{1,5}$/i.test(request.rig_port)) {
25      throw new Error("Use host:port or [IPv6]:port for a sample network connection");
26    }
27    const options = snapshot.details[String(request.model_id)]?.settings || [];
28    for (const [key, value] of Object.entries(request.hamlib_settings || {})) {
29      const option = options.find(item => item.name === key && item.editable);
30      if (!option) throw new Error(`Unsupported setting: ${key}`);
31      if (!value || /[\s,\x00]/.test(value) || new TextEncoder().encode(value).length > 99) throw new Error(`Invalid value for ${key}`);
32      if (option.type === "combo" && !option.choices.includes(value)) throw new Error(`Choose a supported value for ${key}`);
33      if (option.type === "number") {
34        const number = Number(value), step = Number(option.step);
35        if (!Number.isFinite(number) || number < Number(option.minimum) || number > Number(option.maximum) ||
36            (step > 0 && Math.abs((number - Number(option.minimum)) / step - Math.round((number - Number(option.minimum)) / step)) > 0.000001)) {
37          throw new Error(`${key} must be ${option.minimum}–${option.maximum}, step ${option.step}`);
38        }
39      }
40    }
41    if (!audio.some(item => item.capture_device === request.audio_device)) throw new Error("Select a sample receive audio device");
42    if (!audio.some(item => item.playback_device === request.playback_device)) throw new Error("Select a sample playback audio device");
43    return model;
44  }
45
46  window.dccDemoRadioApi = async (url, options = {}) => {
47    const route = String(url).split("?")[0];
48    if (route === "/api/v1/radio/setup/catalog") return clone({...snapshot, details: undefined,
49      serial_candidates: [{path: "/dev/ttyUSB0", likely_model: "Sample CAT interface", stable_path: false}],
50      audio_candidates: audio, suggestions: [], simulated: true});
51    if (route === "/api/v1/radio/detect") {
52      const selected = snapshot.models.find(model => model.display_name === window.dccDemoStation?.profile.radio);
53      if (selected && selected.model_id !== current.model_id) current = {...current, model_id: selected.model_id, hamlib_settings: {}};
54      return clone({configured: current, connected: true, hardware_connected: false, simulated: true});
55    }
56    const match = route.match(/^\/api\/v1\/radio\/setup\/models\/(\d+)$/);
57    if (match && snapshot.details[match[1]]) return clone(snapshot.details[match[1]]);
58    if (route === "/api/v1/radio/setup/status") return clone(status);
59    if (options.method === "POST" && ["/api/v1/radio/setup/probe", "/api/v1/radio/setup/apply"].includes(route)) {
60      const request = JSON.parse(options.body);
61      const model = validate(request);
62      if (route.endsWith("/probe")) return {simulated: true, ready_to_apply: true,
63        connection_detail: "Demo input validation only — hardware is not tested", checks: {
64          model_available: true, settings_valid: true, connection_present: true,
65          audio_device_detected: true, playback_device_detected: true, current_cat_connected: true
66        }, transmit_locked: false, ptt_test_performed: false};
67      current = {...clone(request), ptt: request.ptt_type};
68      window.localStorage?.setItem("radio-configuration", JSON.stringify(current));
69      const requestedAt = new Date().toISOString();
70      status = {state: "success", schema_version: 2, simulated: true, requested_at_utc: requestedAt,
71        radio_name: model.display_name, transmit_locked: false};
72      window.dispatchEvent?.(new CustomEvent("dcc-demo-radio-applied", {detail: {radio: model.display_name}}));
73      return {queued: true, requested_at_utc: requestedAt, simulated: true};
74    }
75    throw new Error("This operation is unavailable in the offline demo");
76  };
77})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.