(function (root, factory) { "use strict"; const api = Object.freeze(factory()); if (typeof module === "object" && module.exports) module.exports = api; if (root) root.MbnPlayoutSafety = api; })(typeof globalThis === "object" ? globalThis : this, function () { "use strict"; const connectionStates = new Set([ "disabled", "dry-run-ready", "disconnected", "connecting", "connected", "reconnecting", "disconnecting", "faulted", "outcome-unknown", "disposed" ]); function normalizeConnectionState(value) { const normalized = String(value || "unavailable") .trim() .toLocaleLowerCase("en-US") .replace(/[\s_]+/g, "-"); return connectionStates.has(normalized) ? normalized : "unavailable"; } function responseTimeoutFromNative(value) { const operationTimeout = Number(value); if (!Number.isFinite(operationTimeout) || operationTimeout < 100 || operationTimeout > 300000) { return 15000; } return Math.min(305000, Math.max(5100, Math.trunc(operationTimeout) + 5000)); } function commandBlockReason(snapshot, command) { if (!snapshot || snapshot.pending) return "busy"; if (snapshot.outcomeUnknown) return "outcome-unknown"; if (!snapshot.commandAvailable) return "unavailable"; if (snapshot.refreshFaulted && command !== "take-out") return "refresh-fault"; const onAir = snapshot.engineState === "PROGRAM" || Boolean(snapshot.onAirCode); const prepared = snapshot.engineState === "PREPARED" || Boolean(snapshot.preparedCode); if (command === "next" && !onAir) return "next-requires-on-air"; if (command === "take-in" && !prepared) return "take-in-requires-prepare"; if (command === "take-out" && !onAir && !prepared) return "nothing-to-take-out"; return null; } function legacyTakeInShortcutAction(snapshot) { if (!snapshot || snapshot.pending) return "blocked"; if (!snapshot.takeInAllowed) return "take-in-locked"; if (snapshot.engineState === "PROGRAM" || snapshot.onAirCode) return "next-required"; if (snapshot.engineState === "PREPARED" || snapshot.preparedCode) return "take-in"; return "prepare-then-take-in"; } function matchesPendingCommand(pending, payload) { return Boolean( pending && payload && payload.requestId === pending.requestId && payload.command === pending.command); } function canClearCommandError(error, sessionQuarantined) { if (sessionQuarantined || !error) return !sessionQuarantined; return error.outcomeUnknown !== true && error.code !== "WEB_TIMEOUT" && error.nonClearable !== true; } function playlistSnapshotLocked(snapshot) { return Boolean(snapshot && ( snapshot.pending || snapshot.outcomeUnknown || snapshot.engineState === "PREPARED" || snapshot.engineState === "PROGRAM" || snapshot.preparedCode || snapshot.onAirCode)); } function shouldClearRefreshError(error, refreshFaulted) { return !refreshFaulted && error?.isRefreshFault === true; } function normalizeRefreshBudget(payload) { const completed = Number.isSafeInteger(payload?.refreshCompletedCount) && payload.refreshCompletedCount >= 0 && payload.refreshCompletedCount <= 2147483647 ? payload.refreshCompletedCount : 0; const maximum = Number.isSafeInteger(payload?.refreshMaximumCount) && payload.refreshMaximumCount >= 0 && payload.refreshMaximumCount <= 1000000 ? payload.refreshMaximumCount : null; return { completed, maximum, limitReached: maximum !== null && completed >= maximum && payload?.refreshLimitReached === true && payload?.refreshActive !== true && payload?.playCompletionPending !== true && payload?.refreshFaulted !== true }; } function formatRefreshBudgetState(payload, nextLabel = "WAIT") { const budget = normalizeRefreshBudget(payload); const count = budget.maximum === null ? String(budget.completed) : `${budget.completed}/${budget.maximum}`; if (payload?.refreshFaulted === true) return "FAULT"; if (budget.limitReached) return `CAPPED · ${count}`; if (payload?.refreshActive === true) return `ACTIVE · ${count} · ${nextLabel}`; return budget.maximum === null && budget.completed === 0 ? "STOPPED" : `STOPPED · ${count}`; } function isNewerDatabaseStatusSequence(latestSequence, incomingSequence) { const latest = Number.isSafeInteger(latestSequence) && latestSequence >= 0 ? latestSequence : 0; return Number.isSafeInteger(incomingSequence) && incomingSequence > 0 && incomingSequence > latest; } function resolveStoredCatalogIndex(catalog, builderKey, cutCode) { if (!Array.isArray(catalog)) return -1; const exact = catalog.findIndex(item => item && item.reachable !== false && item.builderKey === builderKey); if (exact >= 0) return exact; const code = String(cutCode || ""); return catalog.findIndex(item => { if (!item || item.reachable === false) return false; const aliases = Array.isArray(item.aliases) ? item.aliases : [String(item.code || "")]; return aliases.includes(code); }); } return { normalizeConnectionState, responseTimeoutFromNative, commandBlockReason, legacyTakeInShortcutAction, matchesPendingCommand, canClearCommandError, playlistSnapshotLocked, shouldClearRefreshError, normalizeRefreshBudget, formatRefreshBudgetState, isNewerDatabaseStatusSequence, resolveStoredCatalogIndex }; });