/* DeerFlow generated-HTML runtime. Browser ES5; no module loader required. */
(function () {
"use strict";
function ready(fn) {
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", fn);
else fn();
}
function blocks(name) {
return document.querySelectorAll('script[type="application/json"][' + name + "]");
}
function parse(block, target) {
try {
return JSON.parse(block.textContent || "{}");
} catch (error) {
showError(target, "图形数据格式错误:" + (error && error.message ? error.message : "无法解析 JSON"));
return null;
}
}
function showError(target, message) {
var box = document.createElement("div");
box.className = "df-runtime-error";
box.setAttribute("role", "alert");
box.textContent = message;
if (target && target.parentNode) target.parentNode.insertBefore(box, target.nextSibling);
}
function size(target) {
if (target.clientHeight < 40) target.style.minHeight = "360px";
if (target.clientWidth < 40) target.style.width = "100%";
}
// 多页面门户会用 display:none 隐藏非当前页;此时 G6/ECharts 以 0 宽初始化,
// 即使稍后页面显示也只会在浏览器 resize 时才恢复。等容器真正可见后再
// 创建实例,并把之后的面板/iframe 尺寸变化同步给图表和流程图。
function closestLogicalPage(target) {
var node = target;
while (node && node !== document.body) {
if (node.classList && (node.classList.contains("page") || node.classList.contains("view"))) {
return node;
}
node = node.parentNode;
}
return null;
}
function whenVisible(target, callback) {
var observer = null;
var intersection = null;
var attempts = 0;
var timer = null;
var completed = false;
function cleanup() {
if (observer) observer.disconnect();
if (intersection) intersection.disconnect();
if (timer) window.clearTimeout(timer);
observer = null;
intersection = null;
timer = null;
window.removeEventListener("hashchange", check);
}
function check() {
if (completed || !target || target.clientWidth < 40 || target.clientHeight < 40) {
return false;
}
completed = true;
cleanup();
callback();
return true;
}
if (check()) return;
if (window.ResizeObserver) {
observer = new window.ResizeObserver(check);
observer.observe(target);
var page = closestLogicalPage(target);
if (page) observer.observe(page);
}
if (window.IntersectionObserver) {
intersection = new window.IntersectionObserver(function (entries) {
for (var i = 0; i < entries.length; i += 1) {
if (entries[i].isIntersecting) check();
}
}, { threshold: 0 });
intersection.observe(target);
}
window.addEventListener("hashchange", check);
if (window.ResizeObserver) return;
(function poll() {
if (check() || attempts >= 120) return;
attempts += 1;
timer = window.setTimeout(poll, 50);
})();
}
function bindCanvasResize(target, resize) {
var frame = null;
function schedule() {
if (frame !== null) {
window.cancelAnimationFrame(frame);
}
frame = window.requestAnimationFrame(function () {
frame = null;
if (target.clientWidth >= 40 && target.clientHeight >= 40) {
resize();
}
});
}
if (window.ResizeObserver) {
(new window.ResizeObserver(schedule)).observe(target);
}
window.addEventListener("resize", schedule);
window.addEventListener("hashchange", schedule);
}
function bindEChartsResize(target, chart) {
var frame = null;
function resize() {
if (frame !== null) {
window.cancelAnimationFrame(frame);
}
frame = window.requestAnimationFrame(function () {
frame = null;
if (target.clientWidth >= 40 && target.clientHeight >= 40 && !chart.isDisposed()) {
chart.resize();
}
});
}
bindCanvasResize(target, resize);
}
function escapeHtml(value) {
return String(value == null ? "" : value).replace(/[&<>"']/g, function (ch) {
return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[ch];
});
}
function geoPoint(value) {
if (!value || value.length < 2) return null;
var lng = Number(value[0]);
var lat = Number(value[1]);
if (!isFinite(lng) || !isFinite(lat) || lng < -180 || lng > 180 || lat < -90 || lat > 90) return null;
return [lng, lat];
}
function leafletPoint(value) {
var coordinate = geoPoint(value);
return coordinate ? [coordinate[1], coordinate[0]] : null;
}
function initCharts() {
var items = blocks("data-df-chart");
for (var i = 0; i < items.length; i += 1) {
var block = items[i];
var target = document.getElementById(block.getAttribute("data-df-chart"));
if (!target) continue;
var option = parse(block, target);
if (!option) continue;
if (!window.echarts) {
showError(target, "ECharts 运行库加载失败");
continue;
}
size(target);
(function (chartTarget, chartOption) {
whenVisible(chartTarget, function () {
try {
chartTarget.setAttribute("role", "img");
chartTarget.setAttribute("aria-label", chartOption.title && chartOption.title.text ? chartOption.title.text : "数据图表");
var chart = window.echarts.init(chartTarget);
chart.setOption(chartOption);
bindEChartsResize(chartTarget, chart);
} catch (error) {
showError(chartTarget, "图表渲染失败:" + (error && error.message ? error.message : "请检查图表数据"));
}
});
})(target, option);
}
}
var geoMapCache = {};
var geoMapLoads = {};
var geoMapDefaultViews = {
"us-states": { center: [-98, 38], zoom: 2.1 }
};
function geoMapUrl(mapId) {
var config = window.DEERFLOW_HTML_RUNTIME_CONFIG || {};
var maps = config.geoMaps || {};
return typeof maps[mapId] === "string" ? maps[mapId] : "";
}
function loadGeoMap(mapId) {
if (geoMapCache[mapId]) return Promise.resolve(geoMapCache[mapId]);
if (geoMapLoads[mapId]) return geoMapLoads[mapId];
var url = geoMapUrl(mapId);
if (!url) return Promise.reject(new Error("未配置地图资源:" + mapId));
if (!window.fetch) return Promise.reject(new Error("当前浏览器不支持加载本地 GeoJSON"));
geoMapLoads[mapId] = window.fetch(url, { credentials: "omit" }).then(function (response) {
if (!response.ok) throw new Error("地图资源加载失败(HTTP " + response.status + ")");
return response.json();
}).then(function (geoJson) {
if (!geoJson || !geoJson.type) throw new Error("地图资源不是有效 GeoJSON");
normalizeGeoJsonNames(geoJson);
geoMapCache[mapId] = geoJson;
return geoJson;
}).catch(function (error) {
delete geoMapLoads[mapId];
throw error;
});
return geoMapLoads[mapId];
}
function normalizeGeoJsonNames(geoJson) {
var features = geoJson && geoJson.features;
if (!features || !features.length) return;
for (var i = 0; i < features.length; i += 1) {
var feature = features[i] || {};
var properties = feature.properties || (feature.properties = {});
if (!properties.name) {
properties.name = properties.shapeName || properties.NAME_1 || properties.name_en || properties.id || "区域";
}
}
}
function geoRegions(data) {
var values = data.regions || [];
var output = [];
for (var i = 0; i < values.length; i += 1) {
var region = values[i];
if (!region || !region.name) continue;
var item = { name: String(region.name) };
if (isFinite(Number(region.value))) item.value = Number(region.value);
if (region.color) item.itemStyle = { areaColor: String(region.color) };
if (region.description) item.description = String(region.description);
if (region.selected === true) item.selected = true;
output.push(item);
}
return output;
}
function geoMarkers(data) {
var values = data.markers || [];
var output = [];
for (var i = 0; i < values.length; i += 1) {
var marker = values[i];
var coordinate = marker && geoPoint(marker.coordinate);
if (!coordinate) continue;
output.push({
name: marker.name || "地点", value: coordinate.concat([Number(marker.value) || 1]),
description: marker.description || "", itemStyle: marker.color ? { color: marker.color } : undefined
});
}
return output;
}
function geoLines(data) {
var values = data.lines || [];
var output = [];
for (var i = 0; i < values.length; i += 1) {
var line = values[i] || {};
var rawCoordinates = line.coordinates || [];
var coordinates = [];
for (var j = 0; j < rawCoordinates.length; j += 1) {
var coordinate = geoPoint(rawCoordinates[j]);
if (coordinate) coordinates.push(coordinate);
}
if (coordinates.length > 1) output.push({
name: line.name || "连接", coords: coordinates, description: line.description || "",
lineStyle: line.color ? { color: line.color } : undefined
});
}
return output;
}
function geoTooltip(params, data) {
var name = params.name || "地图区域";
var detail = geoDetail(data, name, params.data);
var description = detail.description || "";
return "" + escapeHtml(name) + "" +
(description ? "
" + escapeHtml(description) : "");
}
function geoDetail(data, name, itemData) {
var groups = [data.markers || [], data.regions || [], data.lines || []];
for (var groupIndex = 0; groupIndex < groups.length; groupIndex += 1) {
var group = groups[groupIndex];
for (var itemIndex = 0; itemIndex < group.length; itemIndex += 1) {
if (group[itemIndex] && group[itemIndex].name === name) return group[itemIndex];
}
}
return itemData || {};
}
function showGeoPopup(target, params, data) {
var name = params.name || "地图区域";
var detail = geoDetail(data, name, params.data);
var popup = target.querySelector(".df-geo-popup");
if (!popup) {
if (window.getComputedStyle && window.getComputedStyle(target).position === "static") {
target.style.position = "relative";
}
popup = document.createElement("section");
popup.className = "df-geo-popup";
popup.setAttribute("role", "dialog");
popup.setAttribute("aria-live", "polite");
popup.style.cssText = "position:absolute;z-index:10;max-width:280px;padding:16px 42px 16px 16px;border:1px solid #5aa8df;border-radius:12px;background:rgba(5,23,45,.96);box-shadow:0 16px 36px rgba(0,0,0,.34);color:#f8fbff;font:16px/1.55 -apple-system,BlinkMacSystemFont,'Segoe UI','Microsoft YaHei',sans-serif;";
target.appendChild(popup);
}
var description = detail.description || "暂无更多说明。";
var value = isFinite(Number(detail.value)) ? "