const API_BASE_URL = "https://jvapi.haiyihy.com";
let headers = {
authorization: "Bearer undefined",
"req-app-intel": "version=1.0.0;build=1;model=SM-G9550;sysVersion=9;channel=Google",
"req-client": "Android",
"req-imei": "8fa54d728ab449e04f9292329ed44bda",
"req-lang": "id-ID",
"req-sys-origin": "origin=ATYOU;originChild=ATYOU",
"req-version": "V2",
"req-zone": "Asia/Shanghai"
};
const cfg = window.PAGE_CONFIG || {};
const $ = (selector, root = document) => root.querySelector(selector);
const money = (v) => {
const n = Number(v || 0);
return Number.isFinite(n) ? n.toFixed(2).replace(/\.00$/, "") : String(v || 0);
};
function lang() {
const value = new URLSearchParams(location.search).get("lang") || navigator.language || "en";
if (value.startsWith("ar")) return "AR";
if (value.startsWith("tr")) return "TR";
if (value.startsWith("bn")) return "BN";
return "EN";
}
function splitPairs(value) {
const result = {};
String(value || "").split(";").forEach((item) => {
const index = item.indexOf("=");
if (index > -1) result[item.slice(0, index)] = item.slice(index + 1);
});
return result;
}
function setAppHeaders(raw) {
if (!raw) return;
const data = typeof raw === "string" ? JSON.parse(raw) : raw;
const appIntel = splitPairs(data["Req-App-Intel"]);
const sysOrigin = splitPairs(data["Req-Sys-Origin"]);
headers = {
...headers,
authorization: data.Authorization || headers.authorization,
"req-lang": data["Req-Lang"] || headers["req-lang"],
"req-app-intel": [`version=${appIntel.version || "1.0.0"}`, `build=${appIntel.build || "1"}`, `channel=${appIntel.channel || "Web"}`].join(";"),
"req-imei": appIntel["Req-Imei"] || headers["req-imei"],
"req-sys-origin": [`origin=${sysOrigin.origin || "LIKEI"}`, `child=${sysOrigin.child || "LIKEI"}`].join(";")
};
}
async function connectApp() {
if (!(window.app || window.webkit || window.FlutterPageControl)) {
headers["req-lang"] = lang().toLowerCase();
return;
}
const raw = await new Promise((resolve) => {
window.renderData = resolve;
window.getIosAccessOriginParam = resolve;
let attempt = 0;
const poll = () => {
attempt += 1;
if (window.app && typeof window.app.getAccessOrigin === "function") return resolve(window.app.getAccessOrigin());
if (attempt < 50) return setTimeout(poll, 100);
if (window.FlutterApp && typeof window.FlutterApp.postMessage === "function") window.FlutterApp.postMessage("requestAccessOrigin");
resolve(null);
};
poll();
});
if (raw) setAppHeaders(raw);
}
async function request(method, path, body) {
const response = await fetch(`${API_BASE_URL}${path}`, {
method,
headers: { ...headers, "content-type": "application/json" },
body: body === undefined ? undefined : JSON.stringify(body)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
const error = new Error(data.errorMsg || data.message || `HTTP ${response.status}`);
error.response = data;
throw error;
}
return data;
}
const get = (path) => request("GET", path);
const post = (path, body) => request("POST", path, body);
function getTeamId() {
const keys = ["teamId", "TEAM_ID", "team_id"];
for (const key of keys) {
const value = localStorage.getItem(key);
if (value) return value.replace(/^"|"$/g, "");
}
for (const key of ["teamInfo", "userInfo", "identity"]) {
try {
const item = JSON.parse(localStorage.getItem(key) || "{}");
if (item.teamId || item.id) return item.teamId || item.id;
} catch {}
}
return "";
}
function getIdentity() {
try {
const value = JSON.parse(localStorage.getItem("identity") || "{}");
return value.identity || value.role || "BD";
} catch {
return "BD";
}
}
function toast(message) {
const node = $("#toast");
node.textContent = message || "Request failed";
node.hidden = false;
clearTimeout(toast.timer);
toast.timer = setTimeout(() => (node.hidden = true), 2500);
}
function setLoading(text = "Loading...") {
$("#app").innerHTML = `
${text}
`;
}
function row({ avatar, title, sub, side, tag, onClick }) {
const node = document.createElement("button");
node.type = "button";
node.className = "row";
node.innerHTML = `${avatar !== undefined ? `
` : ""}${tag ? `` : ""}`;
$(".title", node).textContent = title || "-";
$(".sub", node).textContent = sub || "";
$(".side", node).textContent = side || "";
if (tag) $(".tag", node).textContent = tag;
if (onClick) node.addEventListener("click", onClick);
return node;
}
function metrics(items) {
return `${items.map((item) => `${item.label}
${item.value}
`).join("")}`;
}
function showModal(title, content, center = false) {
const mask = $("#modalMask");
mask.innerHTML = ``;
$(".modal-title", mask).textContent = title || "";
$(".modal-body", mask).append(content);
mask.classList.add("show");
}
function closeModal() {
$("#modalMask").classList.remove("show");
}
function navigate(route) {
const url = new URL(route, location.origin);
const langParam = new URLSearchParams(location.search).get("lang");
if (langParam && !url.searchParams.has("lang")) url.searchParams.set("lang", langParam);
location.href = `${url.pathname}${url.search}${url.hash}`;
}
function renderShell() {
document.title = cfg.title || "Yumi H5";
document.body.innerHTML = `
`;
$("[data-back]").addEventListener("click", () => history.length > 1 ? history.back() : window.app?.closePage?.());
$("#modalMask").addEventListener("click", (event) => {
if (event.target.id === "modalMask") closeModal();
});
}
async function renderTeamHistory() {
setLoading();
const [listRes, historyRes] = await Promise.allSettled([get(cfg.listEndpoint), get(cfg.historyEndpoint)]);
const bill = listRes.value?.body || {};
const history = historyRes.value?.body || {};
$("#app").innerHTML = `
${metrics([
{ label: cfg.countLabel, value: bill.memberCount || 0 },
{ label: cfg.totalLabel, value: `$${money(bill.totalSalary || bill.teamSalary || bill.totalRecharge || 0)}` }
])}
${bill.billTitle || cfg.title}
${cfg.totalLabel}: $${money(bill.totalSalary || 0)}
`;
const list = $("#list");
(bill.memberBillList || []).forEach((item) => {
list.appendChild(row({
avatar: item.agentAvatar || item.userAvatar,
title: item.agentName || item.userName,
sub: `ID: ${item.agentAccount || item.account || "-"}`,
side: `${cfg.memberSide1}: $${money(item.teamSalaryAmount || item.salary || 0)}\n${cfg.memberSide2}: ${item.teamMemberCount || item.hostCount || item.agencyCount || 0}`
}));
});
if (!list.children.length) list.innerHTML = `No data
`;
$("#historyBtn").addEventListener("click", () => {
const body = document.createElement("div");
body.innerHTML = metrics([
{ label: "Total income", value: `$${money(history.totalIncome || 0)}` },
{ label: "Previous period", value: `$${money(history.previousPeriodIncome || 0)}` }
]);
const wrap = document.createElement("div");
wrap.className = "card";
(history.incomeDetails || []).forEach((item) => {
wrap.appendChild(row({
title: item.billTitle || item.settlementPeriod,
sub: `${cfg.countLabel}: ${item.agencyNumber || item.bdNumber || item.memberCount || 0}`,
side: `$${money(item.teamSalaryAmount || item.teamTotalIncome || item.settlementSalary || 0)}`,
tag: item.statusText || item.status,
onClick: async () => {
if (!cfg.moreEndpoint || !item.billBelong) return;
try {
const more = await get(`${cfg.moreEndpoint}${item.billBelong}`);
const detail = document.createElement("div");
const card = document.createElement("div");
card.className = "card";
(more.body?.memberDetails || more.body?.members || []).forEach((member) => {
card.appendChild(row({
avatar: member.userAvatar || member.bdUserAvatar || member.avatar,
title: member.userName || member.bdUserName || member.account,
sub: `ID: ${member.account || "-"}`,
side: `$${money(member.salary || member.income || 0)}`
}));
});
detail.appendChild(card);
showModal(more.body?.period || item.billTitle, detail);
} catch (error) {
toast(error.message);
}
}
}));
});
if (!wrap.children.length) wrap.innerHTML = `No data
`;
body.appendChild(wrap);
showModal("History", body);
});
}
async function renderAdminTeam() {
setLoading();
const res = await post("/bd/team/overview", { type: cfg.teamType });
const data = res.body || {};
$("#app").innerHTML = `
${metrics([
{ label: "Total income", value: `$${money(data.totalIncome || 0)}` },
{ label: "Previous period", value: `$${money(data.previousPeriodIncome || 0)}` },
{ label: cfg.memberTitle, value: data.memberCount || 0 },
{ label: "Team total income", value: `$${money(data.teamTotalIncome || 0)}` }
])}
`;
const members = $("#members");
(data.members || []).forEach((item) => {
members.appendChild(row({
avatar: item.avatar,
title: item.userName || "-",
sub: `ID: ${item.account || "-"}`,
side: `${cfg.subMemberLabel}: ${item.subMemberCount || 0}\n$${money(item.totalIncome || 0)}`,
tag: "More",
onClick: () => showAdminTeamDetail(item)
}));
});
if (!members.children.length) members.innerHTML = `No data
`;
}
async function showAdminTeamDetail(item) {
try {
const res = await post("/bd/team/member/detail", { targetId: item.userId, type: cfg.detailType || cfg.teamType });
const data = res.body || {};
const body = document.createElement("div");
body.innerHTML = metrics([
{ label: "Total income", value: `$${money(data.totalIncome || 0)}` },
{ label: "Previous period", value: `$${money(data.previousPeriodIncome || 0)}` }
]);
const card = document.createElement("div");
card.className = "card";
(data.incomeDetails || []).forEach((detail) => {
card.appendChild(row({
title: detail.settlementPeriod,
sub: `${cfg.subMemberLabel}: ${detail.memberCount || 0}`,
side: `$${money(detail.teamTotalIncome || 0)}`,
tag: detail.status || "More",
onClick: () => {
const detailBody = document.createElement("div");
const detailCard = document.createElement("div");
detailCard.className = "card";
(detail.members || []).forEach((member) => detailCard.appendChild(row({
avatar: member.avatar,
title: member.userName,
sub: `ID: ${member.account || "-"}`,
side: `$${money(member.income || 0)}`
})));
detailBody.appendChild(detailCard);
showModal(detail.settlementPeriod, detailBody);
}
}));
});
if (!card.children.length) card.innerHTML = `No data
`;
body.appendChild(card);
showModal(`${cfg.memberTitle} ${item.account || ""}`, body);
} catch (error) {
toast(error.message);
}
}
async function renderRechargeAgency() {
setLoading();
const [summary, list] = await Promise.allSettled([
get("/app/h5/recharge-summary"),
get("/app/h5/recharge-page?cursor=1&limit=20")
]);
const data = summary.value?.body || {};
const records = list.value?.body?.records || [];
$("#app").innerHTML = `${metrics([
{ label: "My total income", value: `$${money(data.totalIncome || 0)}` },
{ label: "This period recharge", value: `$${money(data.currentMonthRecharge || 0)}` }
])}Recharge agency list
`;
const root = $("#records");
records.forEach((item) => root.appendChild(row({
avatar: item.userAvatar,
title: item.userNickname,
sub: `ID: ${item.account || "-"}`,
side: `This: $${money(item.thisMonth || 0)}\nLast: $${money(item.lastMonth || 0)}`
})));
if (!root.children.length) root.innerHTML = `No data
`;
}
async function renderMessage() {
const teamId = getTeamId();
setLoading();
const res = await get(`/team/user/apply/record?teamId=${teamId}&status=WAIT`);
const records = (res.body || []).map((item) => ({
id: item.id,
account: item.createUserProfile?.account,
name: item.createUserProfile?.userNickname,
avatar: item.createUserProfile?.userAvatar
}));
$("#app").innerHTML = ``;
const root = $("#messages");
records.forEach((item) => {
const node = row({ avatar: item.avatar, title: item.name || "Unknown user", sub: `ID: ${item.account || "-"}` });
const actions = document.createElement("div");
actions.className = "toolbar";
actions.innerHTML = ``;
actions.children[0].addEventListener("click", async () => updateApply(item.id, "AGREE", node));
actions.children[1].addEventListener("click", async () => updateApply(item.id, "REJECT", node));
node.appendChild(actions);
root.appendChild(node);
});
if (!root.children.length) root.innerHTML = `No data
`;
}
async function updateApply(id, status, node) {
try {
await post("/team/user/apply/record/update", { id, status });
node.remove();
toast(status === "AGREE" ? "Approved" : "Rejected");
} catch (error) {
toast(error.message);
}
}
async function renderTeamMembers() {
const teamId = getTeamId();
setLoading();
const res = await get(`/team/members?id=${teamId}`);
const records = res.body || [];
$("#app").innerHTML = `
`;
const root = $("#members");
const draw = (items) => {
root.innerHTML = "";
items.forEach((member, index) => root.appendChild(row({
avatar: member.userProfile?.userAvatar,
title: `${index + 1}. ${member.userProfile?.userNickname || "-"}`,
sub: `ID: ${member.userProfile?.ownSpecialId?.account || member.userProfile?.account || "-"}`,
side: `${member.targetFormat || "-"}\n${member.timeHours || "-"}`
})));
if (!root.children.length) root.innerHTML = `No data
`;
};
draw(records);
$("#searchBtn").addEventListener("click", async () => {
const account = $("#search").value.trim();
if (!account) return draw(records);
try {
const searched = await get(`/team/search-members?account=${account}`);
draw(searched.body || []);
} catch (error) {
toast(error.message);
}
});
$("#cancelBtn").addEventListener("click", () => {
$("#search").value = "";
draw(records);
});
}
async function renderTeamBill() {
const teamId = getTeamId();
setLoading();
const res = await get(`/team/bill?id=${teamId}`);
const records = res.body || [];
let total = 0;
records.forEach((item) => {
if (item.status === "SETTLED") total += Number(item.settleResult?.totalSalary || 0);
});
$("#app").innerHTML = `${metrics([{ label: "History team income", value: `$${money(total)}` }])}Work report
`;
const root = $("#bills");
records.forEach((item) => root.appendChild(row({
title: item.billTitle,
sub: `Host salary: $${money(item.settleResult?.memberSalary || 0)} | Agent salary: $${money(item.settleResult?.ownSalary || 0)}`,
side: `$${money(item.settleResult?.totalSalary || 0)}`,
tag: ({ SETTLED: "Completed", UNPAID: "In Progress", HANG_UP: "Out of account", PAY_OUT: "Completed" })[item.status] || item.status,
onClick: async () => {
try {
const detail = await get(`/team/bill/work-members?id=${item.id}`);
const body = document.createElement("div");
const card = document.createElement("div");
card.className = "card";
(detail.body || []).forEach((member) => card.appendChild(row({
avatar: member.memberProfile?.userAvatar,
title: member.memberProfile?.userNickname,
sub: `ID: ${member.memberProfile?.account || "-"}`,
side: `Target: ${member.target?.acceptGiftValue || 0}\nDays: ${member.target?.effectiveDay || 0}`
})));
body.appendChild(card);
showModal(item.billTitle, body);
} catch (error) {
toast(error.message);
}
}
})));
if (!root.children.length) root.innerHTML = `No data
`;
}
function renderInviteProcess() {
$("#app").innerHTML = `
1
Invite users to download the app.
4
Enter team ID when joining.
`;
}
async function renderBankCards() {
setLoading();
const [cards, kyc] = await Promise.allSettled([get("/wallet/bank-card/list"), get("/wallet/withdraw-info/list")]);
const current = (cards.value?.body || []).find((item) => item.use);
const info = kyc.value?.body?.[0];
$("#app").innerHTML = `
Bank card
KYC
`;
$("#cardBox").appendChild(current ? row({ title: current.cardType, sub: `Card: ${current.cardNo}`, side: current.payee }) : row({ title: "Add payment method", sub: "No bank cards in use", tag: "Add", onClick: () => navigate("/bank-card") }));
$("#kycBox").appendChild(info ? row({ title: `Status: ${info.status}`, sub: `Contact: ${info.contactNumber || "-"}`, side: info.otherDescription || "", tag: "KYC", onClick: () => navigate("/KYC") }) : row({ title: "Complete information", sub: "No KYC info", tag: "KYC", onClick: () => navigate("/KYC") }));
}
async function renderWalletAction() {
setLoading();
const action = new URLSearchParams(location.search).get("activeAction") || cfg.action || "Exchange";
const balanceEndpoint = cfg.salaryType ? `/wallet/salary-account/balance?salaryType=${cfg.salaryType}` : "/wallet/bank/balance";
const balanceRes = await get(balanceEndpoint).catch(() => ({ body: 0 }));
const balance = typeof balanceRes.body === "number" ? balanceRes.body : balanceRes.body?.availableBalance || balanceRes.body?.balance || 0;
const amounts = [1, 5, 10, 50, 100, 200];
$("#app").innerHTML = `
${metrics([{ label: "Available salaries", value: `$${money(balance)}` }])}
`;
document.querySelectorAll("[data-act]").forEach((btn) => btn.addEventListener("click", () => navigate(`${location.pathname}?activeAction=${encodeURIComponent(btn.dataset.act)}&lang=${lang().toLowerCase()}`)));
const panel = $("#walletPanel");
if (action === "Cash out") return renderCashOutPanel(panel);
if (action === "Transfer") return renderTransferPanel(panel, amounts);
renderExchangePanel(panel, amounts);
}
function renderExchangePanel(panel, amounts) {
panel.innerHTML = `${amounts.map((amount) => ``).join("")}
`;
let selected = null;
panel.querySelectorAll("[data-amount]").forEach((node) => node.addEventListener("click", () => {
selected = Number(node.dataset.amount);
panel.querySelectorAll(".tile").forEach((tile) => tile.classList.remove("selected"));
node.classList.add("selected");
}));
$("#submit").addEventListener("click", async () => {
if (!selected) return toast("Please select amount");
try {
const path = cfg.salaryType ? "/wallet/salary-account/exchange/gold" : "/wallet/bank/exchange/gold";
await post(path, cfg.salaryType ? { amount: selected, salaryType: cfg.salaryType } : { amount: selected });
toast("Exchange success");
} catch (error) {
toast(error.message);
}
});
}
function renderTransferPanel(panel, amounts) {
panel.innerHTML = `${amounts.map((amount) => ``).join("")}
`;
let payee = null;
let selected = null;
$("#findPayee").addEventListener("click", async () => {
try {
const res = await get(`/user/user-profile/open-search?account=${encodeURIComponent($("#payee").value.trim())}`);
payee = res.body;
$("#payeeInfo").innerHTML = "";
$("#payeeInfo").appendChild(row({ avatar: payee.userAvatar, title: payee.userNickname || payee.name, sub: `ID: ${payee.account}`, side: "" }));
} catch (error) {
toast(error.message);
}
});
panel.querySelectorAll("[data-amount]").forEach((node) => node.addEventListener("click", () => {
selected = Number(node.dataset.amount);
panel.querySelectorAll(".tile").forEach((tile) => tile.classList.remove("selected"));
node.classList.add("selected");
}));
$("#submit").addEventListener("click", async () => {
if (!selected || !payee?.id) return toast("Please select amount and payee");
try {
const path = cfg.salaryType ? "/wallet/salary-account/transferGold" : "/wallet/bank/transferGold";
await post(path, cfg.salaryType ? { amount: selected, acceptUserId: payee.id, salaryType: cfg.salaryType } : { amount: selected, acceptUserId: payee.id, acceptMethod: "BANK_TRANSFER" });
toast("Transfer success");
} catch (error) {
toast(error.message);
}
});
}
async function renderCashOutPanel(panel) {
const [cards, kyc] = await Promise.allSettled([get("/wallet/bank-card/list"), get("/wallet/withdraw-info/list")]);
const card = (cards.value?.body || []).find((item) => item.use);
const info = kyc.value?.body?.[0];
panel.innerHTML = ``;
$("#card").appendChild(card ? row({ title: card.cardType, sub: `Card: ${card.cardNo}`, side: card.payee }) : row({ title: "No bank cards in use", sub: "Add bank card", tag: "Add", onClick: () => navigate("/bank-card") }));
$("#kyc").appendChild(info ? row({ title: `KYC: ${info.status}`, sub: `Contact: ${info.contactNumber || "-"}`, tag: "KYC" }) : row({ title: "Complete KYC", sub: "No KYC information", tag: "KYC", onClick: () => navigate("/KYC") }));
$("#submit").addEventListener("click", async () => {
const amount = Number($("#amount").value);
if (!card?.id || !amount || amount < 50) return toast("Please complete information and enter at least 50");
try {
await post("/wallet/bank/withdraw", { amount, acceptBankCardId: card.id, salaryType: cfg.salaryType || (getIdentity() === "HOST" ? "HOST_SALARY" : "BD_SALARY") });
toast("Cash withdrawal submitted");
} catch (error) {
toast(error.message);
}
});
}
async function renderItemDistribution() {
setLoading();
const permissionEndpoint = cfg.admin ? "/app/h5/own-permission?propsType=NOBLE_VIP" : "/sys/bd/list-permission";
const propsBase = cfg.admin ? "/sys/manager/props" : "/sys/bd/props";
const sendEndpoint = cfg.admin ? "/sys/manager/send" : "/sys/bd/send";
let tabs = cfg.admin ? [{ name: "frames", type: "AVATAR_FRAME" }, { name: "vehicles", type: "RIDE" }, { name: "vip", type: "NOBLE_VIP" }] : [];
if (!cfg.admin) {
const res = await get(permissionEndpoint);
const body = res.body || [];
if (body.includes("AVATAR_FRAME")) tabs.push({ name: "frames", type: "AVATAR_FRAME" });
if (body.includes("RIDE")) tabs.push({ name: "vehicles", type: "RIDE" });
if (body.some((x) => String(x).startsWith("NOBLE_VIP"))) tabs.push({ name: "vip", type: "NOBLE_VIP" });
}
if (!tabs.length) tabs = [{ name: "frames", type: "AVATAR_FRAME" }];
$("#app").innerHTML = `${tabs.map((tab, index) => ``).join("")}
`;
const load = async (tab) => {
const res = await get(`${propsBase}?propsType=${tab.type}¤cyType=GOLD`);
const root = $("#props");
root.innerHTML = "";
(res.body || []).forEach((item) => {
const tile = document.createElement("button");
tile.type = "button";
tile.className = "tile";
tile.innerHTML = `
${item.name || "Item"}Send`;
tile.addEventListener("click", () => openSendProps(item, sendEndpoint));
root.appendChild(tile);
});
if (!root.children.length) root.innerHTML = `No data
`;
};
document.querySelectorAll("[data-tab]").forEach((btn) => btn.addEventListener("click", () => {
document.querySelectorAll("[data-tab]").forEach((b) => b.classList.remove("active"));
btn.classList.add("active");
load(tabs[Number(btn.dataset.tab)]);
}));
await load(tabs[0]);
}
function openSendProps(item, endpoint) {
const body = document.createElement("div");
body.innerHTML = ``;
$("#confirmSend", body).addEventListener("click", async () => {
try {
const user = await get(`/user/user-profile/open-search?account=${encodeURIComponent($("#targetUser", body).value.trim())}`);
await post(endpoint, { propsId: item.id, acceptUserId: user.body.id });
closeModal();
toast("Gift delivery successful");
} catch (error) {
toast(error.message);
}
});
showModal(item.name || "Send", body, true);
}
function renderPolicy() {
$("#app").innerHTML = "";
}
async function renderPlatformPolicy() {
const teamId = getTeamId();
setLoading();
const res = await get(`/team/release/policy?id=${teamId}`);
const policies = res.body?.policy || [];
$("#app").innerHTML = ``;
const root = $("#policyList");
policies.forEach((item) => root.appendChild(row({
title: `Lv.${item.level}`,
sub: `Time: ${item.onlineTime || 0}h | Target: ${item.target || 0}`,
side: `Host: $${money(item.memberSalary || 0)}\nAgent: $${money(item.ownSalary || 0)}`
})));
if (!root.children.length) root.innerHTML = `No policy data available
`;
}
async function init() {
renderShell();
try {
await connectApp();
const handlers = {
teamHistory: renderTeamHistory,
adminTeam: renderAdminTeam,
rechargeAgency: renderRechargeAgency,
message: renderMessage,
teamMembers: renderTeamMembers,
teamBill: renderTeamBill,
inviteProcess: renderInviteProcess,
bankCards: renderBankCards,
walletAction: renderWalletAction,
itemDistribution: renderItemDistribution,
platformPolicy: renderPlatformPolicy,
policy: renderPolicy
};
await (handlers[cfg.mode] || renderPolicy)();
} catch (error) {
console.error(error);
$("#app").innerHTML = `${error.message || "Failed to load data"}
`;
}
}
init();