{"id":499,"date":"2026-04-01T10:55:34","date_gmt":"2026-04-01T08:55:34","guid":{"rendered":"https:\/\/www.aivotec.cz\/?page_id=499"},"modified":"2026-04-01T10:55:34","modified_gmt":"2026-04-01T08:55:34","slug":"databaze","status":"publish","type":"page","link":"https:\/\/www.aivotec.cz\/?page_id=499","title":{"rendered":"Databaze"},"content":{"rendered":"<p><meta charset=\"UTF-8\"><br \/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><br \/>\n<title>KESTO Bond Registry<\/title><\/p>\n<style>\n  :root {<br \/>\n    --bg: #0a0f1a; --surface: #111827; --border: #1e293b;<br \/>\n    --text: #e2e8f0; --muted: #8a9bb0; --dim: #5a6a80;<br \/>\n    --blue: #2563eb; --blue-light: #60a5fa;<br \/>\n    --green: #10b981; --green-light: #34d399;<br \/>\n    --amber: #f59e0b; --red: #ef4444;<br \/>\n    --mono: 'Courier New', monospace;<br \/>\n    --sans: system-ui, -apple-system, sans-serif;<br \/>\n  }<br \/>\n  * { margin:0; padding:0; box-sizing:border-box; }<br \/>\n  body { background:var(--bg); color:var(--text); font-family:var(--sans); font-size:14px; min-height:100vh; }<\/p>\n<p>.header { background:var(\u2013surface); border-bottom:1px solid var(\u2013border); padding:0 20px; display:flex; align-items:center; justify-content:space-between; height:52px; }<br \/>\n.logo { font:800 18px var(\u2013mono); color:var(\u2013blue-light); letter-spacing:-0.02em; }<br \/>\n.logo-sub { font-size:10px; color:var(\u2013dim); text-transform:uppercase; letter-spacing:0.12em; margin-left:10px; border-left:1px solid var(\u2013border); padding-left:10px; }<\/p>\n<p>.nav { background:var(\u2013surface); border-bottom:1px solid var(\u2013border); display:flex; overflow-x:auto; padding:0 20px; }<br \/>\n.nav button { background:none; border:none; border-bottom:2px solid transparent; padding:10px 14px; color:var(\u2013dim); font:600 11px var(\u2013sans); cursor:pointer; text-transform:uppercase; letter-spacing:0.08em; white-space:nowrap; transition:all .15s; }<br \/>\n.nav button.active { color:var(\u2013text); border-bottom-color:var(\u2013blue); }<br \/>\n.nav button:hover { color:var(\u2013text); }<\/p>\n<p>.content { padding:20px; max-width:1100px; margin:0 auto; }<\/p>\n<p>.card { background:var(\u2013surface); border:1px solid var(\u2013border); border-radius:10px; padding:20px; margin-bottom:16px; }<br \/>\n.card-accent { border-top:3px solid var(\u2013blue); }<br \/>\n.card h3 { font:700 13px var(\u2013sans); text-transform:uppercase; letter-spacing:0.1em; margin-bottom:16px; color:var(\u2013text); }<\/p>\n<p>.stats { display:flex; gap:16px; flex-wrap:wrap; margin-bottom:20px; }<br \/>\n.stat-card { flex:1; min-width:180px; border:1px solid var(\u2013border); border-radius:10px; padding:18px; }<br \/>\n.stat-label { font-size:10px; color:var(\u2013muted); text-transform:uppercase; letter-spacing:0.1em; margin-bottom:6px; }<br \/>\n.stat-value { font:800 24px var(\u2013mono); line-height:1; }<\/p>\n<p>.progress-bar { background:#0a0f1a; border-radius:8px; height:10px; overflow:hidden; margin:8px 0; }<br \/>\n.progress-fill { height:100%; background:linear-gradient(90deg,var(\u2013blue),var(\u2013blue-light)); border-radius:8px; transition:width .5s; }<\/p>\n<p>table { width:100%; border-collapse:collapse; font-size:13px; }<br \/>\nth { text-align:left; padding:8px 10px; font:700 10px var(\u2013sans); color:var(\u2013muted); text-transform:uppercase; letter-spacing:0.1em; border-bottom:1px solid var(\u2013border); }<br \/>\ntd { padding:10px; color:#cbd5e1; border-bottom:1px solid #131c2e; white-space:nowrap; }<\/p>\n<p>.btn { padding:6px 14px; border-radius:6px; border:none; cursor:pointer; font:600 12px var(\u2013mono); text-transform:uppercase; letter-spacing:0.05em; transition:all .15s; }<br \/>\n.btn-primary { background:var(\u2013blue); color:#fff; }<br \/>\n.btn-secondary { background:#1e293b; color:#94a3b8; border:1px solid #334155; }<br \/>\n.btn-success { background:#064e3b; color:#6ee7b7; }<br \/>\n.btn-danger { background:#7f1d1d; color:#fca5a5; }<br \/>\n.btn:disabled { opacity:0.4; cursor:not-allowed; }<\/p>\n<p>.form-group { margin-bottom:12px; }<br \/>\n.form-label { display:block; font-size:10px; font-weight:600; color:var(\u2013muted); text-transform:uppercase; letter-spacing:0.08em; margin-bottom:4px; }<br \/>\n.form-input, .form-select { width:100%; padding:8px 10px; background:#0f1724; border:1px solid #263044; border-radius:6px; color:var(\u2013text); font:14px var(\u2013mono); outline:none; }<br \/>\n.form-grid { display:grid; grid-template-columns:1fr 1fr; gap:0 16px; }<\/p>\n<p>.coupon-row { display:flex; align-items:center; gap:12px; padding:10px 14px; background:#0a0f1a; border-radius:6px; margin-bottom:6px; }<br \/>\n.coupon-dot { width:26px; height:26px; border-radius:50%; display:flex; align-items:center; justify-content:center; font:700 11px var(\u2013mono); flex-shrink:0; }<br \/>\n.badge { font-size:10px; font-weight:700; padding:3px 8px; border-radius:4px; }<\/p>\n<p>.modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,.7); display:flex; align-items:center; justify-content:center; z-index:1000; }<br \/>\n.modal { background:var(\u2013surface); border:1px solid #263044; border-radius:12px; padding:24px; width:440px; max-width:95vw; max-height:85vh; overflow:auto; }<br \/>\n.modal h3 { margin-bottom:16px; }<\/p>\n<p>.param-row { display:flex; justify-content:space-between; border-bottom:1px solid #1a2234; padding:8px 0; }<br \/>\n.param-key { font-size:12px; color:var(\u2013dim); }<br \/>\n.param-val { font:600 12px var(\u2013mono); color:var(\u2013text); }<\/p>\n<p>.report-pre { font:12px\/1.8 var(\u2013mono); color:#cbd5e1; white-space:pre-wrap; }<\/p>\n<p>.empty { padding:20px; text-align:center; color:var(\u2013dim); font-size:13px; }<br \/>\n.flex-between { display:flex; justify-content:space-between; align-items:center; }<br \/>\n.gap-8 { display:flex; gap:8px; }<br \/>\n.hidden { display:none; }<br \/>\n<\/style>\n<div class=\"header\">\n<div style=\"display:flex;align-items:center;\">\n    <span class=\"logo\">\u2b21 KESTO<\/span><br \/>\n<span class=\"logo-sub\">Bond Registry<\/span><\/div>\n<p><button class=\"btn btn-danger\" onclick=\"resetAll()\">Reset<\/button><\/p>\n<\/div>\n<div class=\"nav\" id=\"nav\"><\/div>\n<div class=\"content\" id=\"content\"><\/div>\n<p><!-- Modal container --><\/p>\n<div id=\"modal-root\"><\/div>\n<p><script><br \/>\n\/\/ \u2500\u2500\u2500 STATE \u2500\u2500\u2500<br \/>\nconst TABS = [<br \/>\n  {id:\"dashboard\",label:\"Dashboard\",icon:\"\u25c9\"},<br \/>\n  {id:\"emission\",label:\"Emise\",icon:\"\u2b21\"},<br \/>\n  {id:\"owners\",label:\"Vlastn\u00edci\",icon:\"\u2b22\"},<br \/>\n  {id:\"transfers\",label:\"P\u0159evody\",icon:\"\u21c4\"},<br \/>\n  {id:\"coupons\",label:\"Kup\u00f3ny\",icon:\"\u229e\"},<br \/>\n  {id:\"report\",label:\"Report\",icon:\"\u25a4\"},<br \/>\n];<\/p>\n<p>const DEFAULT_EMISSION = {<br \/>\n  name:\"KESTO CAPITAL Serie A\", isin:\"\", currency:\"EUR\",<br \/>\n  totalNominal:1000000, bondNominal:10000, couponRate:7.0,<br \/>\n  couponFrequency:\"annual\", issueDate:\"2026-07-01\",<br \/>\n  maturityDate:\"2031-07-01\", issuer:\"LET.LI SE\", spv:\"\", status:\"prepared\"<br \/>\n};<\/p>\n<p>let STATE = {<br \/>\n  emission:{...DEFAULT_EMISSION}, owners:[], transfers:[], payments:[]<br \/>\n};<br \/>\nlet currentTab = \"dashboard\";<\/p>\n<p>const STATUS_MAP = {<br \/>\n  prepared:{label:\"P\u0159ipravena\",color:\"#f59e0b\"},<br \/>\n  active:{label:\"Aktivn\u00ed\",color:\"#10b981\"},<br \/>\n  matured:{label:\"Splacena\",color:\"#6b7280\"},<br \/>\n};<\/p>\n<p>const uid = () => Math.random().toString(36).slice(2,10);<br \/>\nconst fmtEUR = v => new Intl.NumberFormat(\"cs-CZ\",{style:\"currency\",currency:\"EUR\",minimumFractionDigits:0,maximumFractionDigits:0}).format(v);<br \/>\nconst fmtDate = d => d ? new Date(d).toLocaleDateString(\"cs-CZ\") : \"\u2014\";<br \/>\nconst esc = s => String(s).replace(\/&\/g,\"&amp;\").replace(\/<\/g,\"&lt;\").replace(\/>\/g,\"&gt;\").replace(\/\"\/g,\"&quot;\");<\/p>\n<p>\/\/ \u2500\u2500\u2500 STORAGE \u2500\u2500\u2500<br \/>\nasync function loadStorage() {<br \/>\n  if (!window.storage) return;<br \/>\n  try {<br \/>\n    const r = await window.storage.get(\"kesto-bonds\");<br \/>\n    if (r && r.value) STATE = JSON.parse(r.value);<br \/>\n  } catch(e) {}<br \/>\n}<br \/>\nasync function saveStorage() {<br \/>\n  if (!window.storage) return;<br \/>\n  try { await window.storage.set(\"kesto-bonds\", JSON.stringify(STATE)); } catch(e) {}<br \/>\n}<\/p>\n<p>\/\/ \u2500\u2500\u2500 COUPON SCHEDULE \u2500\u2500\u2500<br \/>\nfunction couponSchedule() {<br \/>\n  const em = STATE.emission;<br \/>\n  if (!em.issueDate || !em.maturityDate) return [];<br \/>\n  const dates = [], months = em.couponFrequency===\"semi-annual\"?6:12;<br \/>\n  let d = new Date(em.issueDate);<br \/>\n  d.setMonth(d.getMonth()+months);<br \/>\n  const end = new Date(em.maturityDate);<br \/>\n  while (d<=end) { dates.push(new Date(d).toISOString().slice(0,10)); d.setMonth(d.getMonth()+months); }\n  return dates;\n}\n\n\/\/ \u2500\u2500\u2500 NAV \u2500\u2500\u2500\nfunction renderNav() {\n  document.getElementById(\"nav\").innerHTML = TABS.map(t =><br \/>\n    `<button class=\"${t.id===currentTab?'active':''}\" onclick=\"switchTab('${t.id}')\">${t.icon} ${t.label}<\/button>`<br \/>\n  ).join(\"\");<br \/>\n}<\/p>\n<p>function switchTab(id) {<br \/>\n  currentTab = id;<br \/>\n  renderNav();<br \/>\n  renderContent();<br \/>\n}<\/p>\n<p>\/\/ \u2500\u2500\u2500 MODAL \u2500\u2500\u2500<br \/>\nfunction showModal(title, html) {<br \/>\n  document.getElementById(\"modal-root\").innerHTML = `<\/p>\n<div class=\"modal-overlay\" onclick=\"closeModal()\">\n<div class=\"modal\" onclick=\"event.stopPropagation()\">\n<div class=\"flex-between\" style=\"margin-bottom:16px;\">\n<h3 style=\"font-size:15px;\">${title}<\/h3>\n<p>          <button class=\"btn btn-secondary\" onclick=\"closeModal()\">\u2715<\/button>\n        <\/div>\n<p>        ${html}\n      <\/p>\n<\/div>\n<\/div>\n<p>`;<br \/>\n}<br \/>\nfunction closeModal() { document.getElementById(\"modal-root\").innerHTML = \"\"; }<\/p>\n<p>\/\/ \u2500\u2500\u2500 PAGES \u2500\u2500\u2500<\/p>\n<p>function renderDashboard() {<br \/>\n  const em = STATE.emission;<br \/>\n  const total = Math.floor(em.totalNominal\/em.bondNominal);<br \/>\n  const issued = STATE.owners.reduce((s,o)=>s+o.quantity,0);<br \/>\n  const pct = total>0?((issued\/total)*100).toFixed(1):\"0\";<br \/>\n  const schedule = couponSchedule();<br \/>\n  const totalPaid = STATE.payments.reduce((s,p)=>s+p.amount,0);<br \/>\n  const activeOwners = STATE.owners.filter(o=>o.quantity>0).length;<br \/>\n  const couponPerBond = (em.bondNominal*em.couponRate)\/100;<\/p>\n<p>  return `<\/p>\n<div class=\"stats\">\n<div class=\"stat-card\" style=\"background:linear-gradient(135deg,#1e3a5f,#0f1724);\">\n<div class=\"stat-label\">Celkov\u00fd objem emise<\/div>\n<div class=\"stat-value\" style=\"color:#60a5fa;\">${fmtEUR(em.totalNominal)}<\/div>\n<\/p>\n<\/div>\n<div class=\"stat-card\" style=\"background:linear-gradient(135deg,#1a3a2a,#0f1724);\">\n<div class=\"stat-label\">Ups\u00e1no<\/div>\n<div class=\"stat-value\" style=\"color:#34d399;\">${fmtEUR(issued*em.bondNominal)}<\/div>\n<div style=\"font-size:11px;color:var(--dim);margin-top:4px;\">${issued} \/ ${total} dluhopis\u016f<\/div>\n<\/p>\n<\/div>\n<div class=\"stat-card\" style=\"background:linear-gradient(135deg,#2d1f3d,#0f1724);\">\n<div class=\"stat-label\">Vlastn\u00edci<\/div>\n<div class=\"stat-value\" style=\"color:#a78bfa;\">${activeOwners}<\/div>\n<div style=\"font-size:11px;color:var(--dim);margin-top:4px;\">${STATE.transfers.length} p\u0159evod\u016f<\/div>\n<\/p>\n<\/div>\n<\/div>\n<div style=\"display:flex;gap:16px;flex-wrap:wrap;\">\n<div style=\"flex:2;min-width:280px;\">\n<div class=\"card card-accent\">\n<h3>Stav emise<\/h3>\n<div style=\"display:flex;align-items:center;gap:12px;margin-bottom:12px;\">\n            <span style=\"width:10px;height:10px;border-radius:50%;background:${STATUS_MAP[em.status]?.color};display:inline-block;\"><\/span><br \/>\n            <span style=\"font-weight:600;\">${STATUS_MAP[em.status]?.label}<\/span><br \/>\n            <span style=\"margin-left:auto;font-size:12px;color:var(--dim);\">${esc(em.name)}<\/span>\n          <\/div>\n<div class=\"progress-bar\">\n<div class=\"progress-fill\" style=\"width:${pct}%\"><\/div>\n<\/div>\n<div style=\"display:flex;justify-content:space-between;font-size:11px;color:var(--dim);\">\n            <span>Ups\u00e1no ${pct}%<\/span><span>Zb\u00fdv\u00e1 ${fmtEUR((total-issued)*em.bondNominal)}<\/span>\n          <\/div>\n<\/p>\n<\/div>\n<div class=\"card\" style=\"border-top:3px solid var(--amber);\">\n<h3>Kup\u00f3nov\u00fd kalend\u00e1\u0159<\/h3>\n<p>          ${schedule.length===0 ? '<\/p>\n<div class=\"empty\">Nastavte data emise.<\/div>\n<p>' :<br \/>\n            schedule.map((date,i) => {<br \/>\n              const paid = STATE.payments.some(p=>p.couponDate===date);<br \/>\n              const past = new Date(date)<new Date();\n              const col = paid?\"#10b981\":past?\"#ef4444\":\"#f59e0b\";\n              const lbl = paid?\"ZAPLACENO\":past?\"NEZAPLACENO\":\"PL\u00c1NOV\u00c1NO\";\n              return `\n\n\n\n<div class=\"coupon-row\" style=\"border-left:3px solid ${col};\">\n                <span style=\"font:12px var(--mono);min-width:85px;color:var(--muted);\">${fmtDate(date)}<\/span><br \/>\n                <span style=\"font-size:12px;\">Kup\u00f3n #${i+1}<\/span><br \/>\n                <span style=\"margin-left:auto;font-size:10px;font-weight:700;color:${col};\">${lbl}<\/span>\n              <\/div>\n<p>`;<br \/>\n            }).join(\"\")}\n        <\/p>\n<\/div>\n<\/div>\n<div style=\"flex:1;min-width:220px;\">\n<div class=\"card\" style=\"border-top:3px solid #6366f1;\">\n<h3>Parametry<\/h3>\n<p>          ${[[\"Nomin\u00e1l\",fmtEUR(em.bondNominal)],[\"Kup\u00f3n\",em.couponRate+\"% p.a.\"],[\"Frekvence\",em.couponFrequency===\"annual\"?\"Ro\u010dn\u011b\":\"Pololetn\u011b\"],[\"Emise\",fmtDate(em.issueDate)],[\"Splatnost\",fmtDate(em.maturityDate)],[\"Emitent\",esc(em.issuer)]].map(([k,v])=><br \/>\n            `<\/p>\n<div class=\"param-row\"><span class=\"param-key\">${k}<\/span><span class=\"param-val\">${v}<\/span><\/div>\n<p>`<br \/>\n          ).join(\"\")}\n        <\/p>\n<\/div>\n<div class=\"card\" style=\"border-top:3px solid var(--green);\">\n<h3>Finan\u010dn\u00ed souhrn<\/h3>\n<div class=\"stat-label\">Celkem vyplaceno<\/div>\n<div class=\"stat-value\" style=\"color:#34d399;font-size:20px;margin-bottom:12px;\">${fmtEUR(totalPaid)}<\/div>\n<div class=\"stat-label\">Kup\u00f3n \/ dluhopis \/ rok<\/div>\n<div style=\"font:600 14px var(--mono);margin-bottom:12px;\">${fmtEUR(couponPerBond)}<\/div>\n<div class=\"stat-label\">Kup\u00f3nov\u00fdch v\u00fdplat<\/div>\n<div style=\"font:600 14px var(--mono);\">${STATE.payments.length} \/ ${schedule.length}<\/div>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>`;<br \/>\n}<\/p>\n<p>function renderEmission() {<br \/>\n  const em = STATE.emission;<br \/>\n  return `<\/p>\n<div class=\"card card-accent\">\n<div class=\"flex-between\">\n<h3>Parametry emise<\/h3>\n<p><button class=\"btn btn-primary\" onclick=\"saveEmission()\">Ulo\u017eit<\/button><\/div>\n<div class=\"form-grid\">\n<div class=\"form-group\"><label class=\"form-label\">N\u00e1zev emise<\/label><input class=\"form-input\" id=\"em-name\" value=\"${esc(em.name)}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">ISIN<\/label><input class=\"form-input\" id=\"em-isin\" value=\"${esc(em.isin)}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Celkov\u00fd objem (EUR)<\/label><input class=\"form-input\" type=\"number\" id=\"em-total\" value=\"${em.totalNominal}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Nomin\u00e1l dluhopisu (EUR)<\/label><input class=\"form-input\" type=\"number\" id=\"em-nominal\" value=\"${em.bondNominal}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Kup\u00f3nov\u00e1 sazba (%)<\/label><input class=\"form-input\" type=\"number\" step=\"0.1\" id=\"em-coupon\" value=\"${em.couponRate}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Frekvence kup\u00f3nu<\/label><br \/>\n          <select class=\"form-select\" id=\"em-freq\"><option value=\"annual\" ${em.couponFrequency===\"annual\"?\"selected\":\"\"}>Ro\u010dn\u011b<\/option><option value=\"semi-annual\" ${em.couponFrequency===\"semi-annual\"?\"selected\":\"\"}>Pololetn\u011b<\/option><\/select><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Datum emise<\/label><input class=\"form-input\" type=\"date\" id=\"em-issue\" value=\"${em.issueDate}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Datum splatnosti<\/label><input class=\"form-input\" type=\"date\" id=\"em-maturity\" value=\"${em.maturityDate}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Emitent<\/label><input class=\"form-input\" id=\"em-issuer\" value=\"${esc(em.issuer)}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">SPV (Luxembourg)<\/label><input class=\"form-input\" id=\"em-spv\" value=\"${esc(em.spv)}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Status<\/label><br \/>\n          <select class=\"form-select\" id=\"em-status\"><option value=\"prepared\" ${em.status===\"prepared\"?\"selected\":\"\"}>P\u0159ipravena<\/option><option value=\"active\" ${em.status===\"active\"?\"selected\":\"\"}>Aktivn\u00ed<\/option><option value=\"matured\" ${em.status===\"matured\"?\"selected\":\"\"}>Splacena<\/option><\/select><\/div>\n<\/p>\n<\/div>\n<\/div>\n<p>`;<br \/>\n}<\/p>\n<p>function saveEmission() {<br \/>\n  STATE.emission = {<br \/>\n    ...STATE.emission,<br \/>\n    name: document.getElementById(\"em-name\").value,<br \/>\n    isin: document.getElementById(\"em-isin\").value,<br \/>\n    totalNominal: Number(document.getElementById(\"em-total\").value),<br \/>\n    bondNominal: Number(document.getElementById(\"em-nominal\").value),<br \/>\n    couponRate: Number(document.getElementById(\"em-coupon\").value),<br \/>\n    couponFrequency: document.getElementById(\"em-freq\").value,<br \/>\n    issueDate: document.getElementById(\"em-issue\").value,<br \/>\n    maturityDate: document.getElementById(\"em-maturity\").value,<br \/>\n    issuer: document.getElementById(\"em-issuer\").value,<br \/>\n    spv: document.getElementById(\"em-spv\").value,<br \/>\n    status: document.getElementById(\"em-status\").value,<br \/>\n  };<br \/>\n  saveStorage();<br \/>\n  renderContent();<br \/>\n}<\/p>\n<p>function renderOwners() {<br \/>\n  const em = STATE.emission;<br \/>\n  const total = Math.floor(em.totalNominal\/em.bondNominal);<br \/>\n  const issued = STATE.owners.reduce((s,o)=>s+o.quantity,0);<\/p>\n<p>  let rows = STATE.owners.map(o => `<\/p>\n<tr>\n<td>${esc(o.name)}<\/td>\n<td>${esc(o.identifier)}<\/td>\n<td style=\"font-weight:700;color:#60a5fa;\">${o.quantity}<\/td>\n<td>${fmtEUR(o.quantity*em.bondNominal)}<\/td>\n<td>${((o.quantity\/total)*100).toFixed(1)}%<\/td>\n<td>\n<div class=\"gap-8\"><button class=\"btn btn-secondary\" onclick=\"editOwner('${o.id}')\">\u270e<\/button><button class=\"btn btn-danger\" onclick=\"removeOwner('${o.id}')\">\u2715<\/button><\/div>\n<\/td>\n<\/tr>\n<p>`).join(\"\");<\/p>\n<p>  return `<\/p>\n<div class=\"card\" style=\"border-top:3px solid #a78bfa;\">\n<div class=\"flex-between\">\n<h3>Registry vlastn\u00edk\u016f<\/h3>\n<p><button class=\"btn btn-primary\" onclick=\"addOwnerModal()\">+ P\u0159idat<\/button><\/div>\n<div class=\"stats\" style=\"margin-bottom:16px;\">\n<div>\n<div class=\"stat-label\">Vlastn\u00edk\u016f<\/div>\n<div class=\"stat-value\" style=\"font-size:20px;\">${STATE.owners.filter(o=>o.quantity>0).length}<\/div>\n<\/div>\n<div>\n<div class=\"stat-label\">Ups\u00e1no ks<\/div>\n<div class=\"stat-value\" style=\"font-size:20px;\">${issued}<span style=\"font-size:12px;color:var(--dim);\"> \/ ${total}<\/span><\/div>\n<\/div>\n<div>\n<div class=\"stat-label\">Voln\u00fdch<\/div>\n<div class=\"stat-value\" style=\"font-size:20px;color:${total-issued>0?'var(--amber)':'var(--green)'};\">${total-issued}<\/div>\n<\/div>\n<\/div>\n<p>      ${rows ? `<\/p>\n<table>\n<thead>\n<tr>\n<th>Jm\u00e9no<\/th>\n<th>I\u010cO\/R\u010c<\/th>\n<th>Ks<\/th>\n<th>Nomin\u00e1l<\/th>\n<th>Pod\u00edl<\/th>\n<th><\/th>\n<\/tr>\n<\/thead>\n<tbody>${rows}<\/tbody>\n<\/table>\n<p>` : '<\/p>\n<div class=\"empty\">Zat\u00edm \u017e\u00e1dn\u00ed vlastn\u00edci.<\/div>\n<p>'}\n    <\/p>\n<\/div>\n<p>`;<br \/>\n}<\/p>\n<p>function addOwnerModal() {<br \/>\n  showModal(\"Nov\u00fd vlastn\u00edk\", `<\/p>\n<div class=\"form-group\"><label class=\"form-label\">Jm\u00e9no \/ N\u00e1zev<\/label><input class=\"form-input\" id=\"ow-name\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">I\u010cO \/ Rodn\u00e9 \u010d\u00edslo<\/label><input class=\"form-input\" id=\"ow-id\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Adresa<\/label><input class=\"form-input\" id=\"ow-addr\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Email<\/label><input class=\"form-input\" id=\"ow-email\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Bankovn\u00ed \u00fa\u010det<\/label><input class=\"form-input\" id=\"ow-bank\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Po\u010det dluhopis\u016f (ks)<\/label><input class=\"form-input\" type=\"number\" id=\"ow-qty\" value=\"1\"><\/div>\n<div class=\"gap-8\" style=\"margin-top:16px;\">\n      <button class=\"btn btn-primary\" onclick=\"saveOwner()\">Ulo\u017eit<\/button><br \/>\n      <button class=\"btn btn-secondary\" onclick=\"closeModal()\">Zru\u0161it<\/button>\n    <\/div>\n<p>`);<br \/>\n}<\/p>\n<p>function editOwner(id) {<br \/>\n  const o = STATE.owners.find(x=>x.id===id);<br \/>\n  if (!o) return;<br \/>\n  showModal(\"Upravit vlastn\u00edka\", `<br \/>\n    <input type=\"hidden\" id=\"ow-edit-id\" value=\"${id}\"><\/p>\n<div class=\"form-group\"><label class=\"form-label\">Jm\u00e9no \/ N\u00e1zev<\/label><input class=\"form-input\" id=\"ow-name\" value=\"${esc(o.name)}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">I\u010cO \/ Rodn\u00e9 \u010d\u00edslo<\/label><input class=\"form-input\" id=\"ow-id\" value=\"${esc(o.identifier)}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Adresa<\/label><input class=\"form-input\" id=\"ow-addr\" value=\"${esc(o.address)}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Email<\/label><input class=\"form-input\" id=\"ow-email\" value=\"${esc(o.email||'')}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Bankovn\u00ed \u00fa\u010det<\/label><input class=\"form-input\" id=\"ow-bank\" value=\"${esc(o.bankAccount||'')}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Po\u010det dluhopis\u016f (ks)<\/label><input class=\"form-input\" type=\"number\" id=\"ow-qty\" value=\"${o.quantity}\"><\/div>\n<div class=\"gap-8\" style=\"margin-top:16px;\">\n      <button class=\"btn btn-primary\" onclick=\"saveOwner()\">Ulo\u017eit<\/button><br \/>\n      <button class=\"btn btn-secondary\" onclick=\"closeModal()\">Zru\u0161it<\/button>\n    <\/div>\n<p>`);<br \/>\n}<\/p>\n<p>function saveOwner() {<br \/>\n  const editEl = document.getElementById(\"ow-edit-id\");<br \/>\n  const data = {<br \/>\n    name: document.getElementById(\"ow-name\").value,<br \/>\n    identifier: document.getElementById(\"ow-id\").value,<br \/>\n    address: document.getElementById(\"ow-addr\").value,<br \/>\n    email: document.getElementById(\"ow-email\").value,<br \/>\n    bankAccount: document.getElementById(\"ow-bank\").value,<br \/>\n    quantity: Number(document.getElementById(\"ow-qty\").value),<br \/>\n  };<br \/>\n  if (!data.name) return;<br \/>\n  if (editEl) {<br \/>\n    const idx = STATE.owners.findIndex(o=>o.id===editEl.value);<br \/>\n    if (idx>=0) STATE.owners[idx] = {...STATE.owners[idx], ...data};<br \/>\n  } else {<br \/>\n    STATE.owners.push({...data, id:uid(), createdAt:new Date().toISOString()});<br \/>\n  }<br \/>\n  saveStorage(); closeModal(); renderContent();<br \/>\n}<\/p>\n<p>function removeOwner(id) {<br \/>\n  STATE.owners = STATE.owners.filter(o=>o.id!==id);<br \/>\n  saveStorage(); renderContent();<br \/>\n}<\/p>\n<p>function renderTransfers() {<br \/>\n  const getName = id => STATE.owners.find(o=>o.id===id)?.name || \"\u2014\";<br \/>\n  const rows = [...STATE.transfers].reverse().map(t => `<\/p>\n<tr>\n<td>${fmtDate(t.date)}<\/td>\n<td>${esc(getName(t.fromId))}<\/td>\n<td>${esc(getName(t.toId))}<\/td>\n<td style=\"font-weight:700;color:var(--amber);\">${t.quantity}<\/td>\n<td>${esc(t.note||'')}<\/td>\n<\/tr>\n<p>`).join(\"\");<\/p>\n<p>  const opts = STATE.owners.map(o=>`<option value=\"${o.id}\">${esc(o.name)} (${o.quantity} ks)<\/option>`).join(\"\");<\/p>\n<p>  return `<\/p>\n<div class=\"card\" style=\"border-top:3px solid var(--amber);\">\n<div class=\"flex-between\">\n<h3>P\u0159evody dluhopis\u016f<\/h3>\n<p>        <button class=\"btn btn-primary\" onclick=\"transferModal()\" ${STATE.owners.length<2?'disabled':''}>+ P\u0159evod<\/button><\/div>\n<p>      ${rows ? `<\/p>\n<table>\n<thead>\n<tr>\n<th>Datum<\/th>\n<th>Od<\/th>\n<th>Na<\/th>\n<th>Ks<\/th>\n<th>Pozn\u00e1mka<\/th>\n<\/tr>\n<\/thead>\n<tbody>${rows}<\/tbody>\n<\/table>\n<p>` : '<\/p>\n<div class=\"empty\">\u017d\u00e1dn\u00e9 p\u0159evody.<\/div>\n<p>'}\n    <\/p>\n<\/div>\n<p>`;<br \/>\n}<\/p>\n<p>function transferModal() {<br \/>\n  const opts = STATE.owners.map(o=>`<option value=\"${o.id}\">${esc(o.name)} (${o.quantity} ks)<\/option>`).join(\"\");<br \/>\n  const today = new Date().toISOString().slice(0,10);<br \/>\n  showModal(\"Nov\u00fd p\u0159evod\", `<\/p>\n<div class=\"form-group\"><label class=\"form-label\">Od (p\u0159evodce)<\/label><select class=\"form-select\" id=\"tr-from\"><option value=\"\">Vyberte...<\/option>${opts}<\/select><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Na (nabyvatel)<\/label><select class=\"form-select\" id=\"tr-to\"><option value=\"\">Vyberte...<\/option>${opts}<\/select><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Po\u010det ks<\/label><input class=\"form-input\" type=\"number\" id=\"tr-qty\" value=\"1\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Datum p\u0159evodu<\/label><input class=\"form-input\" type=\"date\" id=\"tr-date\" value=\"${today}\"><\/div>\n<div class=\"form-group\"><label class=\"form-label\">Pozn\u00e1mka<\/label><input class=\"form-input\" id=\"tr-note\"><\/div>\n<div class=\"gap-8\" style=\"margin-top:16px;\">\n      <button class=\"btn btn-primary\" onclick=\"execTransfer()\">Prov\u00e9st<\/button><br \/>\n      <button class=\"btn btn-secondary\" onclick=\"closeModal()\">Zru\u0161it<\/button>\n    <\/div>\n<p>`);<br \/>\n}<\/p>\n<p>function execTransfer() {<br \/>\n  const fromId = document.getElementById(\"tr-from\").value;<br \/>\n  const toId = document.getElementById(\"tr-to\").value;<br \/>\n  const qty = Number(document.getElementById(\"tr-qty\").value);<br \/>\n  if (!fromId || !toId || fromId===toId || qty<1) return;\n  const from = STATE.owners.find(o=>o.id===fromId);<br \/>\n  if (!from || from.quantity<qty) return alert(\"Nedostate\u010dn\u00fd po\u010det dluhopis\u016f.\");\n  STATE.owners = STATE.owners.map(o => {<br \/>\n    if (o.id===fromId) return {...o, quantity:o.quantity-qty};<br \/>\n    if (o.id===toId) return {...o, quantity:o.quantity+qty};<br \/>\n    return o;<br \/>\n  });<br \/>\n  STATE.transfers.push({id:uid(), fromId, toId, quantity:qty, date:document.getElementById(\"tr-date\").value, note:document.getElementById(\"tr-note\").value, createdAt:new Date().toISOString()});<br \/>\n  saveStorage(); closeModal(); renderContent();<br \/>\n}<\/p>\n<p>function renderCoupons() {<br \/>\n  const schedule = couponSchedule();<br \/>\n  const em = STATE.emission;<br \/>\n  if (!schedule.length) return '<\/p>\n<div class=\"card\" style=\"border-top:3px solid var(--green);\">\n<h3>Kup\u00f3ny<\/h3>\n<div class=\"empty\">Nastavte parametry emise.<\/div>\n<\/div>\n<p>';<\/p>\n<p>  return `<\/p>\n<div class=\"card\" style=\"border-top:3px solid var(--green);\">\n<h3>Kup\u00f3nov\u00fd kalend\u00e1\u0159 a platby<\/h3>\n<p>    ${schedule.map((date,i) => {<br \/>\n      const pmts = STATE.payments.filter(p=>p.couponDate===date);<br \/>\n      const paid = pmts.length>0;<br \/>\n      const past = new Date(date)<new Date();\n      const total = pmts.reduce((s,p)=>s+p.amount,0);<br \/>\n      const col = paid?\"#10b981\":past?\"#ef4444\":\"#f59e0b\";<br \/>\n      const lbl = paid?\"ZAPLACENO\":past?\"K \u00daHRAD\u011a\":\"PL\u00c1N\";<br \/>\n      const bgBadge = paid?\"#064e3b\":past?\"#7f1d1d\":\"#1a2234\";<br \/>\n      return `<\/p>\n<div class=\"coupon-row\" style=\"justify-content:space-between;\">\n<div style=\"display:flex;align-items:center;gap:12px;\">\n<div class=\"coupon-dot\" style=\"background:${bgBadge};color:${col};\">${i+1}<\/div>\n<div>\n<div style=\"font-size:13px;font-weight:600;\">Kup\u00f3n #${i+1}<\/div>\n<div style=\"font-size:11px;color:var(--dim);\">${fmtDate(date)}<\/div>\n<\/div>\n<\/div>\n<div style=\"display:flex;align-items:center;gap:10px;\">\n          ${paid?`<span style=\"font:700 13px var(--mono);color:#34d399;\">${fmtEUR(total)}<\/span>`:''}<br \/>\n          <span class=\"badge\" style=\"background:${bgBadge};color:${col};\">${lbl}<\/span><br \/>\n          ${!paid?`<button class=\"btn btn-success\" onclick=\"payCoupon('${date}')\">Zaplatit<\/button>`:`<button class=\"btn btn-secondary\" onclick=\"couponDetail('${date}')\">Detail<\/button>`}\n        <\/div>\n<\/p>\n<\/div>\n<p>`;<br \/>\n    }).join(\"\")}\n  <\/p>\n<\/div>\n<p>`;<br \/>\n}<\/p>\n<p>function payCoupon(date) {<br \/>\n  const em = STATE.emission;<br \/>\n  const active = STATE.owners.filter(o=>o.quantity>0);<br \/>\n  const rate = em.couponRate\/100\/(em.couponFrequency===\"semi-annual\"?2:1);<br \/>\n  active.forEach(o => {<br \/>\n    STATE.payments.push({id:uid(), ownerId:o.id, couponDate:date, amount:o.quantity*em.bondNominal*rate, paidAt:new Date().toISOString()});<br \/>\n  });<br \/>\n  saveStorage(); renderContent();<br \/>\n}<\/p>\n<p>function couponDetail(date) {<br \/>\n  const pmts = STATE.payments.filter(p=>p.couponDate===date);<br \/>\n  const getName = id => STATE.owners.find(o=>o.id===id)?.name||\"\u2014\";<br \/>\n  const rows = pmts.map(p=>`<\/p>\n<tr>\n<td>${esc(getName(p.ownerId))}<\/td>\n<td style=\"color:#34d399;font-weight:700;\">${fmtEUR(p.amount)}<\/td>\n<td>${fmtDate(p.paidAt)}<\/td>\n<\/tr>\n<p>`).join(\"\");<br \/>\n  showModal(\"Detail kup\u00f3nu \u2013 \"+fmtDate(date), `<\/p>\n<table>\n<thead>\n<tr>\n<th>Vlastn\u00edk<\/th>\n<th>\u010c\u00e1stka<\/th>\n<th>Zaplaceno<\/th>\n<\/tr>\n<\/thead>\n<tbody>${rows}<\/tbody>\n<\/table>\n<p>`);<br \/>\n}<\/p>\n<p>function renderReport() {<br \/>\n  const em = STATE.emission;<br \/>\n  const total = Math.floor(em.totalNominal\/em.bondNominal);<br \/>\n  const issued = STATE.owners.reduce((s,o)=>s+o.quantity,0);<br \/>\n  const schedule = couponSchedule();<br \/>\n  const totalPaid = STATE.payments.reduce((s,p)=>s+p.amount,0);<br \/>\n  const couponPerBond = (em.bondNominal*em.couponRate)\/100;<br \/>\n  const today = new Date().toLocaleDateString(\"cs-CZ\",{year:\"numeric\",month:\"long\",day:\"numeric\"});<br \/>\n  const next = schedule.find(d=>new Date(d)>=new Date());<br \/>\n  const remaining = schedule.filter(d=>!STATE.payments.some(p=>p.couponDate===d)).length;<\/p>\n<p>  const ownerLines = STATE.owners.filter(o=>o.quantity>0).map(o =><br \/>\n    `  \u00b7 ${o.name.padEnd(28)} ${String(o.quantity).padStart(4)} ks  ${fmtEUR(o.quantity*em.bondNominal).padStart(14)}  (${((o.quantity\/total)*100).toFixed(1)}%)`<br \/>\n  ).join(\"\\n\") || \"  \u017e\u00e1dn\u00ed\";<\/p>\n<p>  return `<\/p>\n<div class=\"card\" style=\"border-top:3px solid #6366f1;\">\n<h3>Souhrnn\u00fd report<\/h3>\n<pre class=\"report-pre\">\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  ${esc(em.name)}\n  Report ke dni ${today}\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nEMISE\n  Emitent:          ${esc(em.issuer)}\n  ISIN:             ${em.isin||\"nep\u0159id\u011blen\"}\n  Status:           ${STATUS_MAP[em.status]?.label}\n  Celkov\u00fd objem:    ${fmtEUR(em.totalNominal)}\n  Nomin\u00e1l:          ${fmtEUR(em.bondNominal)}\n  Celkem kus\u016f:      ${total}\n  Kup\u00f3n:            ${em.couponRate}% p.a. (${em.couponFrequency===\"annual\"?\"ro\u010dn\u00ed\":\"pololetn\u00ed\"})\n  Datum emise:      ${fmtDate(em.issueDate)}\n  Splatnost:        ${fmtDate(em.maturityDate)}\n\nUPS\u00c1N\u00cd\n  Ups\u00e1no:           ${issued} ks (${fmtEUR(issued*em.bondNominal)})\n  Voln\u00fdch:          ${total-issued} ks (${fmtEUR((total-issued)*em.bondNominal)})\n  Ups\u00e1n\u00ed:           ${total>0?((issued\/total)*100).toFixed(1):\"0\"}%\n\nVLASTN\u00cdCI (${STATE.owners.filter(o=>o.quantity>0).length})\n${ownerLines}\n\nP\u0158EVODY:            ${STATE.transfers.length}\n\nKUP\u00d3NY\n  Vyplaceno:        ${fmtEUR(totalPaid)}\n  Kup\u00f3n\/ks\/rok:     ${fmtEUR(couponPerBond)}\n  P\u0159\u00ed\u0161t\u00ed kup\u00f3n:     ${fmtDate(next)}\n  Zb\u00fdv\u00e1 v\u00fdplat:     ${remaining}\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<\/pre>\n<\/div>\n<p>`;<\/p>\n<p>}<\/p>\n<p>\/\/ \u2500\u2500\u2500 RENDER \u2500\u2500\u2500<br \/>\nfunction renderContent() {<br \/>\nconst pages = {<br \/>\ndashboard: renderDashboard,<br \/>\nemission: renderEmission,<br \/>\nowners: renderOwners,<br \/>\ntransfers: renderTransfers,<br \/>\ncoupons: renderCoupons,<br \/>\nreport: renderReport,<br \/>\n};<br \/>\ndocument.getElementById(\u201ccontent\u201d).innerHTML = pages[currentTab]();<br \/>\n}<\/p>\n<p>function resetAll() {<br \/>\nif (!window._resetConfirm) {<br \/>\nwindow._resetConfirm = true;<br \/>\ndocument.querySelector(\u201d.header .btn-danger\u201d).textContent = \u201cPotvrdit smaz\u00e1n\u00ed?\u201d;<br \/>\nsetTimeout(()=>{ window._resetConfirm=false; document.querySelector(\u201d.header .btn-danger\u201d).textContent=\u201cReset\u201d; },3000);<br \/>\nreturn;<br \/>\n}<br \/>\nSTATE = {emission:{\u2026DEFAULT_EMISSION}, owners:[], transfers:[], payments:[]};<br \/>\nsaveStorage(); window._resetConfirm=false;<br \/>\ndocument.querySelector(\u201d.header .btn-danger\u201d).textContent=\u201cReset\u201d;<br \/>\nrenderNav(); renderContent();<br \/>\n}<\/p>\n<p>\/\/ \u2500\u2500\u2500 INIT \u2500\u2500\u2500<br \/>\n(async function() {<br \/>\nawait loadStorage();<br \/>\nrenderNav();<br \/>\nrenderContent();<br \/>\n})();<br \/>\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>KESTO Bond Registry \u2b21 KESTO Bond Registry Reset<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=\/wp\/v2\/pages\/499"}],"collection":[{"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=499"}],"version-history":[{"count":1,"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=\/wp\/v2\/pages\/499\/revisions"}],"predecessor-version":[{"id":501,"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=\/wp\/v2\/pages\/499\/revisions\/501"}],"wp:attachment":[{"href":"https:\/\/www.aivotec.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=499"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}