allyhub 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/commands/render.js +1 -1
  2. package/dist/commands/sheet.js +7 -7
  3. package/dist/commands/slides.js +1 -1
  4. package/dist/node_modules/@allyhub-next/audio/package.json +1 -1
  5. package/dist/node_modules/@allyhub-next/browser/package.json +1 -1
  6. package/dist/node_modules/@allyhub-next/build/package.json +1 -1
  7. package/dist/node_modules/@allyhub-next/chart/package.json +1 -1
  8. package/dist/node_modules/@allyhub-next/check/package.json +1 -1
  9. package/dist/node_modules/@allyhub-next/cloud/package.json +1 -1
  10. package/dist/node_modules/@allyhub-next/components/package.json +1 -1
  11. package/dist/node_modules/@allyhub-next/dev-server/dist/exports.js +1 -1
  12. package/dist/node_modules/@allyhub-next/dev-server/package.json +1 -1
  13. package/dist/node_modules/@allyhub-next/doc/package.json +1 -1
  14. package/dist/node_modules/@allyhub-next/export/dist/export.d.ts +2 -2
  15. package/dist/node_modules/@allyhub-next/export/dist/export.js +4 -4
  16. package/dist/node_modules/@allyhub-next/export/dist/names.d.ts +1 -1
  17. package/dist/node_modules/@allyhub-next/export/package.json +1 -1
  18. package/dist/node_modules/@allyhub-next/formats/dist/data/sheet.d.ts +179 -0
  19. package/dist/node_modules/@allyhub-next/formats/dist/data/sheet.js +1 -1
  20. package/dist/node_modules/@allyhub-next/formats/dist/data/slides.d.ts +303 -11
  21. package/dist/node_modules/@allyhub-next/formats/dist/data/slides.js +1 -1
  22. package/dist/node_modules/@allyhub-next/formats/dist/index.d.ts +1 -0
  23. package/dist/node_modules/@allyhub-next/formats/dist/index.js +1 -1
  24. package/dist/node_modules/@allyhub-next/formats/dist/items.js +1 -1
  25. package/dist/node_modules/@allyhub-next/formats/dist/schemas.d.ts +135 -3
  26. package/dist/node_modules/@allyhub-next/formats/dist/zip.d.ts +17 -0
  27. package/dist/node_modules/@allyhub-next/formats/dist/zip.js +2 -0
  28. package/dist/node_modules/@allyhub-next/formats/package.json +1 -1
  29. package/dist/node_modules/@allyhub-next/measure/package.json +1 -1
  30. package/dist/node_modules/@allyhub-next/media/package.json +1 -1
  31. package/dist/node_modules/@allyhub-next/model/package.json +1 -1
  32. package/dist/node_modules/@allyhub-next/project/package.json +1 -1
  33. package/dist/node_modules/@allyhub-next/protocol/dist/editor.d.ts +10 -0
  34. package/dist/node_modules/@allyhub-next/protocol/dist/editor.js +1 -1
  35. package/dist/node_modules/@allyhub-next/protocol/dist/notes.d.ts +2 -0
  36. package/dist/node_modules/@allyhub-next/protocol/dist/notes.js +1 -1
  37. package/dist/node_modules/@allyhub-next/protocol/package.json +1 -1
  38. package/dist/node_modules/@allyhub-next/registry/package.json +1 -1
  39. package/dist/node_modules/@allyhub-next/render/dist/exports.d.ts +2 -11
  40. package/dist/node_modules/@allyhub-next/render/dist/exports.js +2 -2
  41. package/dist/node_modules/@allyhub-next/render/dist/page.d.ts +1 -9
  42. package/dist/node_modules/@allyhub-next/render/package.json +1 -1
  43. package/dist/node_modules/@allyhub-next/runtime/package.json +1 -1
  44. package/dist/node_modules/@allyhub-next/runtimes/package.json +1 -1
  45. package/dist/node_modules/@allyhub-next/scaffold/package.json +1 -1
  46. package/dist/node_modules/@allyhub-next/scenery/package.json +1 -1
  47. package/dist/node_modules/@allyhub-next/scenery-host/package.json +1 -1
  48. package/dist/node_modules/@allyhub-next/sheet/dist/api/capabilities.js +1 -1
  49. package/dist/node_modules/@allyhub-next/sheet/dist/api/index.d.ts +1 -0
  50. package/dist/node_modules/@allyhub-next/sheet/dist/api/index.js +1 -1
  51. package/dist/node_modules/@allyhub-next/sheet/dist/api/page.d.ts +83 -0
  52. package/dist/node_modules/@allyhub-next/sheet/dist/api/page.js +2 -0
  53. package/dist/node_modules/@allyhub-next/sheet/dist/api/workbook.d.ts +40 -1
  54. package/dist/node_modules/@allyhub-next/sheet/dist/api/workbook.js +1 -1
  55. package/dist/node_modules/@allyhub-next/sheet/dist/check.js +1 -1
  56. package/dist/node_modules/@allyhub-next/sheet/dist/structure.js +1 -1
  57. package/dist/node_modules/@allyhub-next/sheet/dist/xlsx/charts.d.ts +2 -0
  58. package/dist/node_modules/@allyhub-next/sheet/dist/xlsx/charts.js +1 -1
  59. package/dist/node_modules/@allyhub-next/sheet/dist/xlsx/import.d.ts +3 -0
  60. package/dist/node_modules/@allyhub-next/sheet/dist/xlsx/import.js +1 -1
  61. package/dist/node_modules/@allyhub-next/sheet/dist/xlsx/read.d.ts +2 -1
  62. package/dist/node_modules/@allyhub-next/sheet/dist/xlsx/read.js +1 -1
  63. package/dist/node_modules/@allyhub-next/sheet/dist/xlsx/write.js +1 -1
  64. package/dist/node_modules/@allyhub-next/sheet/package.json +1 -1
  65. package/dist/node_modules/@allyhub-next/site/package.json +1 -1
  66. package/dist/node_modules/@allyhub-next/slides-core/dist/api.d.ts +64 -7
  67. package/dist/node_modules/@allyhub-next/slides-core/dist/api.js +2 -2
  68. package/dist/node_modules/@allyhub-next/slides-core/dist/capabilities.js +1 -1
  69. package/dist/node_modules/@allyhub-next/slides-core/dist/chart-api.d.ts +23 -0
  70. package/dist/node_modules/@allyhub-next/slides-core/dist/chart-api.js +1 -1
  71. package/dist/node_modules/@allyhub-next/slides-core/dist/chart-file.js +1 -1
  72. package/dist/node_modules/@allyhub-next/slides-core/dist/enums.d.ts +20 -0
  73. package/dist/node_modules/@allyhub-next/slides-core/dist/enums.js +1 -1
  74. package/dist/node_modules/@allyhub-next/slides-core/dist/index.d.ts +1 -0
  75. package/dist/node_modules/@allyhub-next/slides-core/dist/index.js +1 -1
  76. package/dist/node_modules/@allyhub-next/slides-core/dist/model.d.ts +37 -1
  77. package/dist/node_modules/@allyhub-next/slides-core/dist/office.d.ts +10 -0
  78. package/dist/node_modules/@allyhub-next/slides-core/dist/office.js +1 -1
  79. package/dist/node_modules/@allyhub-next/slides-core/dist/preset.d.ts +5 -0
  80. package/dist/node_modules/@allyhub-next/slides-core/dist/preset.js +2 -0
  81. package/dist/node_modules/@allyhub-next/slides-core/dist/resolve.d.ts +7 -2
  82. package/dist/node_modules/@allyhub-next/slides-core/dist/resolve.js +1 -1
  83. package/dist/node_modules/@allyhub-next/slides-core/package.json +1 -1
  84. package/dist/node_modules/@allyhub-next/slides-pptx/dist/charts.js +1 -1
  85. package/dist/node_modules/@allyhub-next/slides-pptx/dist/import.js +1 -1
  86. package/dist/node_modules/@allyhub-next/slides-pptx/dist/read.d.ts +2 -1
  87. package/dist/node_modules/@allyhub-next/slides-pptx/dist/read.js +2 -2
  88. package/dist/node_modules/@allyhub-next/slides-pptx/dist/shapes.d.ts +6 -1
  89. package/dist/node_modules/@allyhub-next/slides-pptx/dist/shapes.js +1 -1
  90. package/dist/node_modules/@allyhub-next/slides-pptx/dist/text.d.ts +11 -0
  91. package/dist/node_modules/@allyhub-next/slides-pptx/dist/text.js +1 -1
  92. package/dist/node_modules/@allyhub-next/slides-pptx/dist/write.js +2 -2
  93. package/dist/node_modules/@allyhub-next/slides-pptx/dist/xml.d.ts +10 -4
  94. package/dist/node_modules/@allyhub-next/slides-pptx/dist/xml.js +2 -2
  95. package/dist/node_modules/@allyhub-next/slides-pptx/package.json +1 -1
  96. package/dist/node_modules/@allyhub-next/slides-runtime/dist/draw.d.ts +3 -0
  97. package/dist/node_modules/@allyhub-next/slides-runtime/dist/draw.js +2 -2
  98. package/dist/node_modules/@allyhub-next/slides-runtime/dist/edit.js +1 -1
  99. package/dist/node_modules/@allyhub-next/slides-runtime/package.json +1 -1
  100. package/dist/node_modules/@allyhub-next/stage/dist/graphics.js +1 -1
  101. package/dist/node_modules/@allyhub-next/stage/package.json +1 -1
  102. package/dist/node_modules/@allyhub-next/stage-page/dist/page.js +19 -19
  103. package/dist/node_modules/@allyhub-next/stage-page/package.json +1 -1
  104. package/dist/node_modules/@allyhub-next/video-core/package.json +1 -1
  105. package/editor-web/assets/dist-BW2s9FMO.js +4 -0
  106. package/editor-web/assets/{dist-CuW84oPe.js → dist-C-6JmebI.js} +22 -22
  107. package/editor-web/assets/dist-CCYMLMKN.js +6 -0
  108. package/editor-web/assets/dist-CHzurjMx.js +33 -0
  109. package/editor-web/assets/{dist-Yi3sy7Ea.js → dist-DF7H1dxw.js} +1 -1
  110. package/editor-web/assets/dist-Da5AUSKX.js +2 -0
  111. package/editor-web/assets/index-CovQYWvD.js +69 -0
  112. package/editor-web/assets/minus-BrvjaJyO.js +1 -0
  113. package/editor-web/assets/react-DV5fPdiH.js +101 -0
  114. package/editor-web/assets/{textarea-CvxipnGW.js → textarea-B0vCGdZI.js} +2 -2
  115. package/editor-web/assets/{trash-2-Bq1Dt8XG.js → trash-2-B0dvc1cZ.js} +1 -1
  116. package/editor-web/assets/{undo-2-Djhvu4xt.js → undo-2-A1EPubPO.js} +1 -1
  117. package/editor-web/index.html +2 -2
  118. package/package.json +2 -2
  119. package/editor-web/assets/dist-Cg2PdedY.js +0 -6
  120. package/editor-web/assets/dist-CxAS_vp7.js +0 -2
  121. package/editor-web/assets/dist-DCVaj9i1.js +0 -4
  122. package/editor-web/assets/dist-DGVUuVPB.js +0 -33
  123. package/editor-web/assets/index-pwRfZ2Jv.js +0 -69
  124. package/editor-web/assets/minus-BizJdinJ.js +0 -1
  125. package/editor-web/assets/react-D54s6gwK.js +0 -101
@@ -1,2 +1,2 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{SHEET_DATA as G,SHEET_FILE as Q}from"@allyhub-next/formats";import{cellName as $,columnLetter as A,contains as z,overlaps as D,rangeName as x,readAddress as Z,readArea as ee}from"../address.js";import{rectangles as _}from"../api/rectangles.js";import{chartAfter as te}from"../chart.js";import{analyse as oe}from"../calc/analyse.js";import{FUNCTIONS as ne}from"../calc/functions/index.js";import{checkWorkbook as se}from"../check.js";import{writeCsv as I}from"../csv.js";import{isDateCode as W}from"../format.js";import{moveFormula as re,relativeKey as B}from"../formula/move.js";import{printFormula as M,sheetPrefix as ie}from"../formula/print.js";import{mapNode as le,walk as N}from"../formula/walk.js";import{CellError as T,isoOfSerial as fe,readTyped as F,writeTyped as P}from"../values.js";import{FormulaCell as ae,placeKey as g,validName as R}from"../workbook.js";import{writeYaml as ce}from"../write.js";import{readFileFormula as ue}from"./formula.js";import{hasDate as H}from"./numfmt.js";import{placesLine as J,readXlsx as de}from"./read.js";const K=100,he=.5,q=1462;export const COMPARE_TOLERANCE=1e-9;const me=f=>f.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/gu,"")||"rows",b=f=>Object.keys(f).length===0,V=(f,e)=>`${String(f)} ${e}${f===1?"":"s"}`,C=f=>({row:f.row,col:f.col});function X(f,e){const o=e.toLowerCase();return le(f,n=>n.kind!=="structured"||n.table?.toLowerCase()!==o?n:Object.fromEntries(Object.entries(n).filter(([i])=>i!=="table")))}function Y(f){return f.headers===0?"has no header row":f.columns.length!==f.ref.right-f.ref.left+1||!R(f.name)?"cannot be held as a table":new Set(f.columns.map(e=>e.name.toLowerCase())).size===f.columns.length?void 0:"has two columns of one name"}function U(f,e,o){let n;const i=new Set;N(f,t=>{t.kind==="call"&&(t.name==="LET"||t.name==="LAMBDA")&&t.args.forEach(r=>{r.kind==="name"&&i.add(r.name.toLowerCase())})});const s=t=>i.has(t)||o===void 0||o.names.has(t)||o.tables.has(t);return N(f,t=>{n===void 0&&(t.kind==="call"&&!ne.has(t.name)&&(s(t.written.toLowerCase())||(n=`no function ${t.name}`)),t.kind==="name"&&!s(t.name.toLowerCase())&&(n=`no name ${t.name}`),t.kind==="structured"&&t.table!==void 0&&!s(t.table.toLowerCase())&&(n=`no table ${t.table}`),(t.kind==="ref"||t.kind==="name"||t.kind==="error")&&t.sheet!==void 0&&(t.sheet.startsWith("[")?n="it reads another workbook":e.has(t.sheet.toLowerCase())||(n=`no sheet ${t.sheet}`)))}),n}function pe(f){const e=new Set(f.book.sheets.map(o=>o.name.toLowerCase()));for(const o of f.book.sheets){const n=new Map,i=(t,r)=>{const l=n.get(r),c=$(t);l?l.push(c):n.set(r,[c])},s=[];for(const t of o.cells){if(t.unread!==void 0){i(t,/^\[|[!']\[|\[\d+\]/u.test(t.unread)?"it reads another workbook":`it could not be read: ${t.unread}`);continue}if(!t.node)continue;const r=U(t.node,e,f);r!==void 0?(delete t.node,i(t,r)):(f.carried.set(t,o),t.array&&x(t.array)!==$(t)&&s.push(t))}we(f,o,s);for(const[t,r]of n)f.lost.push(`${o.name}: ${V(r.length,"formula")} kept as ${r.length===1?"its value":"their values"}, as ${t} (${J(r)})`)}}function we(f,e,o){if(o.length===0)return;const n=new Set;for(const i of o){const{array:s}=i;if(s)for(const t of e.cells)t!==i&&!t.node&&z(s,t.row,t.col)&&n.add(t)}e.cells=e.cells.filter(i=>!n.has(i));for(const i of n)f.spilled.set(i,e)}function O(f,e){const{value:o}=e;if(!f.book.date1904||typeof o!="number")return o;const n=f.book.looks[e.style]?.format;return W(n)&&n!==void 0&&H(n)?o+q:o}function j(f,e){if(typeof f!="number"||e===void 0||!W(e)||!H(e)||f<1)return;const o=fe(f);return F(o).value===f?o:void 0}const ge=(f,e)=>j(f,e)??P(f??null);function ke(f,e){const o=j(f,e);return o!==void 0?o:f==null?null:typeof f=="number"||typeof f=="boolean"?f:P(f)}function be(f){const e={top:1/0,left:1/0,bottom:-1,right:-1};for(const{row:o,col:n}of f)e.top=Math.min(e.top,o),e.left=Math.min(e.left,n),e.bottom=Math.max(e.bottom,o),e.right=Math.max(e.right,n);return e}class ye{ctx;read;byPlace=new Map;inTables=new Set;columnLooks=new Map;rowLooks=new Map;lookDone=new Set;tables=[];areas=[];filtered=[];constructor(e,o){this.ctx=e,this.read=o;for(const n of o.cells)this.byPlace.set(g(n.row,n.col),n)}look(e){return this.ctx.book.looks[e.style]??{}}code(e){return this.look(e).format}text(e){return e.node?M(e.node):ge(O(this.ctx,e),this.code(e))}baseLooks(){const{read:e}=this,{looks:o}=this.ctx.book,n=e.cells.reduce((s,t)=>Math.max(s,t.col),-1);for(const s of e.columns){if(s.style===void 0)continue;const t=o[s.style];if(!(!t||b(t)))for(let r=s.min;r<=Math.min(s.max,n);r++)this.columnLooks.set(r,t)}for(const s of e.rows){const t=s.style===void 0?void 0:o[s.style];t&&!b(t)&&this.rowLooks.set(s.row,t)}const i=(s,t)=>Object.keys(t).every(r=>r in s);for(const s of e.cells){const t=this.look(s),r=this.columnLooks.get(s.col);r&&!i(t,r)&&this.columnLooks.delete(s.col);const l=this.rowLooks.get(s.row);l&&!i(t,l)&&this.rowLooks.delete(s.row)}}ownLook(e){const o={...this.columnLooks.get(e.col),...this.rowLooks.get(e.row)},n={};for(const[s,t]of Object.entries(this.look(e)))JSON.stringify(t)!==JSON.stringify(o[s])&&(n[s]=t);const i=n.format;if(typeof i=="string"){const s=e.node?void 0:j(O(this.ctx,e),i);s!==void 0&&F(s).format===i&&delete n.format}return n}columnFormula(e,o,n){const i=new Map,s=n-o+1;for(let r=o;r<=n;r++){const l=this.byPlace.get(g(r,e));if(!l||l.value===void 0&&!l.node||l.value===null&&!l.node)return;if(!l.node)continue;l.key??=B(l.node,l.row,l.col);const c=i.get(l.key);c?c.n+=1:i.set(l.key,{n:1,cell:l})}let t;for(const r of i.values())(!t||r.n>t.n)&&(t=r);return t&&t.n*2>s?t.cell:void 0}table(e){const{read:o,ctx:n}=this,i=h=>n.lost.push(`${o.name}: table ${e.name} ${h}`),s=e.ref.right-e.ref.left+1,t=Y(e);if(t!==void 0)return i(`${t}, so its cells are kept and it is no table`),!1;const r=e.ref.top,l=r+1,c=e.ref.bottom-e.totals;e.totals>0&&i("has a totals row, kept as plain cells under it");const a=e.columns.map((h,m)=>c>=l?this.columnFormula(e.ref.left+m,l,c):void 0),u=h=>{const m=a[h];if(!m)return!1;for(let k=l;k<=c;k++)if(this.byPlace.get(g(k,e.ref.left+h))?.key!==m.key)return!1;return!0};let d=s;for(;d>1&&u(d-1);)d-=1;const w=[e.columns.slice(0,d).map(h=>h.name)],p={};for(let h=l;h<=c;h++){const m=[];for(let k=0;k<d;k++){const y=this.byPlace.get(g(h,e.ref.left+k)),v=a[k];y?v&&y.key===v.key?m.push(""):y.node?m.push(M(X(y.node,e.name))):m.push(this.text(y)):m.push("")}w.push(m)}for(let h=e.ref.top;h<=c;h++)for(let m=e.ref.left;m<=e.ref.right;m++)this.inTables.add(g(h,m));e.columns.forEach((h,m)=>{const k=e.ref.left+m,y=this.columnLook(k,l,c),v=a[m];v?.node&&(y.formula=M(X(re(v.node,l-v.row,0),e.name))),b(y)||(p[h.name]=y)});const L=this.path(e.name);n.files.set(L,I(w));const E=new Map;for(const[h,m]of e.filter?.columns??[]){const k=e.columns[h]?.name;k!==void 0&&E.set(k,m)}return(e.filter?.unread??0)>0&&i(`has ${V(e.filter?.unread??0,"filter")} by condition, its rows left as they were hidden`),this.tables.push({name:e.name,at:$({row:r,col:e.ref.left}),rows:L,...e.style!==void 0&&e.style!=="TableStyleMedium2"?{style:e.style}:{},...b(p)?{}:{columns:p},...e.filter===void 0?{filter:!1}:E.size>0?{filter:{columns:Object.fromEntries(E)}}:{}}),e.filter?.unread===0&&e.filter.columns.size>0&&this.filtered.push({...e.ref,bottom:c}),this.areas.push({...e.ref,bottom:c}),!0}columnLook(e,o,n){let i,s={};for(let t=o;t<=n;t++){const r=this.byPlace.get(g(t,e)),l=r?this.ownLook(r):{},c=JSON.stringify(l);if(i===void 0)i=c,s=l;else if(i!==c)return{}}if(b(s))return{};for(let t=o;t<=n;t++)this.lookDone.add(g(t,e));return{...s}}path(e){const o=`${G}/${me(e)}`;let n=`${o}.csv`;for(let i=2;this.ctx.files.has(n);i++)n=`${o}-${String(i)}.csv`;return n}loose(){const e=[],o=[];for(const n of this.read.cells)this.inTables.has(g(n.row,n.col))||(n.node?e.push(n):n.value!==void 0&&n.value!==null&&o.push(n));return{formulas:e,typed:o}}blockAreas(e,o){const n=new Map;e.forEach((a,u)=>n.set(g(a.row,a.col),u));const i=e.map((a,u)=>u),s=a=>{let u=a;for(;i[u]!==u;){const d=i[i[u]??u]??u;i[u]=d,u=d}return u};e.forEach((a,u)=>{for(const d of[n.get(g(a.row,a.col-1)),n.get(g(a.row-1,a.col))])d!==void 0&&(i[s(u)]=s(d))});const t=new Map;e.forEach((a,u)=>{const d=s(u),w=t.get(d);w?w.push(a):t.set(d,[a])});const r=[],l=a=>!r.some(u=>D(u,a))&&!this.areas.some(u=>D(u,a))&&!o.some(u=>z(a,u.row,u.col)),c=a=>(a.bottom-a.top+1)*(a.right-a.left+1);for(const a of t.values()){const u=be(a);if(!(c(u)<K)){if(a.length/c(u)>=he&&l(u)){r.push(u);continue}for(const d of _(a.map(C)))c(d)>=K&&l(d)&&r.push(d)}}return r.sort((a,u)=>a.top-u.top||a.left-u.left)}cells(e){const{formulas:o,typed:n}=this.loose(),i=this.blockAreas(n,o),s=l=>i.some(c=>z(c,l.row,l.col));i.length>0&&(e.blocks=i.map(l=>{const c=[];for(let u=l.top;u<=l.bottom;u++){const d=[];for(let w=l.left;w<=l.right;w++){const p=this.byPlace.get(g(u,w));d.push(p?this.text(p):"")}c.push(d)}const a=this.path(this.read.name);return this.ctx.files.set(a,I(c)),{at:$({row:l.top,col:l.left}),rows:a}}));const t=[],r=new Map;for(const l of o){if(!l.node)continue;l.key??=B(l.node,l.row,l.col);const c=r.get(l.key);c?c.push(l):r.set(l.key,[l])}for(const l of r.values())for(const c of _(l.map(C))){const a=this.byPlace.get(g(c.top,c.left));a?.node&&t.push([{row:c.top,col:c.left},x(c),M(a.node)])}for(const l of n)i.length>0&&s(l)||t.push([C(l),$(l),ke(O(this.ctx,l),this.code(l))]);t.sort(([l],[c])=>l.row-c.row||l.col-c.col),t.length>0&&(e.cells=Object.fromEntries(t.map(([,l,c])=>[l,c])))}formats(e){const o=new Map;for(const i of this.read.cells){if(this.lookDone.has(g(i.row,i.col)))continue;const s=this.ownLook(i);if(b(s))continue;const t=JSON.stringify(s),r=o.get(t);r?r.places.push(C(i)):o.set(t,{look:s,places:[C(i)]})}const n=[];for(const{look:i,places:s}of o.values())for(const t of _(s))n.push({range:x(t),...i});n.length>0&&(e.format=n)}columns(e){const{read:o}=this,n=new Map,i=o.cells.reduce((t,r)=>Math.max(t,r.col),0),s=[];for(const t of o.columns)if(!(t.width===void 0&&t.hidden!==!0)){t.max>i&&s.push(A(Math.max(t.min,i+1)));for(let r=t.min;r<=Math.min(t.max,i);r++)n.set(r,{...t.width===void 0?{}:{width:t.width},...t.hidden===!0?{hidden:!0}:{}})}for(const[t,r]of this.columnLooks)n.set(t,{...n.get(t),...r});n.size>0&&(e.columns=Object.fromEntries([...n.keys()].sort((t,r)=>t-r).map(t=>[A(t),n.get(t)??{}]))),s.some(Boolean)&&o.columns.some(t=>t.max>i&&t.hidden===!0)&&this.ctx.lost.push(`${o.name}: the size of the columns past its last used one`)}rows(e){const o={};for(const n of this.read.rows){const i=this.rowLooks.get(n.row),s=this.filtered.some(r=>n.row>r.top&&n.row<=r.bottom),t={...n.height===void 0?{}:{height:n.height},...n.hidden===!0&&!s?{hidden:!0}:{},...i};b(t)||(o[String(n.row+1)]=t)}b(o)||(e.rows=o)}build(){const{read:e}=this;this.baseLooks();for(const n of e.tables)this.table(n);const o={name:e.name};return e.state!=="visible"&&(o.hidden=!0),e.gridlines===!1&&(o.gridlines=!1),e.tab!==void 0&&(o.tab=e.tab),e.state==="veryHidden"&&this.ctx.lost.push(`${e.name}: being very hidden; it is hidden`),e.freeze&&(e.freeze.row>0||e.freeze.col>0)&&(o.freeze=$(e.freeze)),this.tables.length>0&&(o.tables=this.tables),this.filter(o),this.columns(o),this.rows(o),this.cells(o),e.merges.length>0&&(o.merges=e.merges.map(x)),this.formats(o),e.conditional.length>0&&(o.conditional=e.conditional),e.validations.length>0&&(o.validations=e.validations),e.charts.length>0&&(o.charts=e.charts.map(n=>this.chart(n))),o}chart(e){return te(e,o=>{const n=this.chartReference(o.replace(/^=/u,""));return o.startsWith("=")?`=${n}`:n})}chartReference(e){const o=e.lastIndexOf("!"),i=(o<0?this.read.name:e.slice(0,o)).replace(/^'|'$/gu,"").replaceAll("''","'"),s=ee(e.slice(o+1).replaceAll("$",""));if(!s)return e;const t=this.ctx.book.sheets.find(r=>r.name.toLowerCase()===i.toLowerCase());for(const r of t?.tables??[]){const l=r.ref.top+1,a=s.left===s.right&&s.top===l&&s.bottom===r.ref.bottom&&s.left>=r.ref.left&&s.left<=r.ref.right?r.columns[s.left-r.ref.left]:void 0;if(a&&this.ctx.tables.has(r.name.toLowerCase()))return`${r.name}[${a.name}]`}return`${t===this.read||o<0?"":`${e.slice(0,o)}!`}${x(s)}`}filter(e){const{filter:o}=this.read;if(!o)return;const n={};for(const[i,s]of o.columns)n[A(o.ref.left+i)]=s;e.filter={range:x(o.ref),...b(n)?{}:{columns:n}},o.unread===0&&!b(n)&&this.filtered.push(o.ref)}}function $e(f){const e={},{book:o,lost:n}=f,i=new Set(o.sheets.map(r=>r.name.toLowerCase())),s=new Set,t=new Set;for(const r of o.names){if(r.name.startsWith("_xlnm.")){r.name==="_xlnm.Print_Area"?t.add("print areas"):r.name==="_xlnm.Print_Titles"?t.add("print titles"):r.name!=="_xlnm._FilterDatabase"&&n.push(`Excel's name ${r.name}`);continue}if(/^_xl(?:fn|pm|ws|udf)/iu.test(r.name))continue;const l=r.name.toLowerCase();if(!R(r.name)||f.tables.has(l)){n.push(`the name ${r.name}, which cannot be held here`);continue}if(s.has(l)){n.push(`a second name ${r.name}, for one sheet: names here are the workbook's`);continue}const c=xe(r.text);if(c!==void 0)e[r.name]=typeof c=="string"?P(c):c,s.add(l),f.names.add(l);else{const a=ue(r.text,!0),u=a.ok?U(a.node,i):"it could not be read";if(!a.ok||u!==void 0||ve(a.node)){n.push(`the name ${r.name} (${r.text})${u===void 0?"":`: ${u}`}`);continue}e[r.name]=M(a.node),s.add(l),f.names.add(l)}r.sheet!==void 0&&n.push(`the name ${r.name} belonging to one sheet: here it is the workbook's`)}return t.size>0&&n.push([...t].join(" and ")),e}function Le(f,e){const o={},n=new Map;for(const[i,s]of Object.entries(e))typeof s=="string"&&s.startsWith("=")&&n.set(s.slice(1).replaceAll("$","").toLowerCase(),i);for(const i of f.book.sheets)for(const s of i.scenarios){const t={};let r=!0;for(const{at:l,value:c}of s.cells){const a=Z(l),u=a&&i.cells.find(p=>p.row===a.row&&p.col===a.col);String(u?.value??"")!==c&&(r=!1);const d=n.get(`${ie(i.name)}${l}`.toLowerCase())??n.get(l.toLowerCase()),w=F(c);d===void 0?f.lost.push(`${i.name}: scenario ${s.name}'s cell ${l}, which has no name`):t[d]=typeof w.value=="number"?w.value:c}!r&&!b(t)&&(o[s.name]={...o[s.name],...t})}return o}function ve(f){let e=!1;return N(f,o=>{e||=o.kind==="error"&&o.code==="#REF!"}),e}function xe(f){const e=f.trim();return/^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/u.test(e)?Number(e):/^true$/iu.test(e)?!0:/^false$/iu.test(e)?!1:/^"((?:[^"]|"")*)"$/u.exec(e)?.[1]?.replaceAll('""','"')}const S=f=>f instanceof T?f.code:f??null;export function sameValue(f,e,o){if(typeof f=="number"&&typeof e=="number")return f===e?!0:Math.abs(f-e)<=Math.max(Math.abs(f),Math.abs(e))*o;if(f instanceof T||e instanceof T)return f?.code===e?.code;if(f===null||e===null){const n=f??e;return n===null||n===""||n===0||n===!1}return f===e}function Me(f,e){const o=[];for(const s of e.sheets)for(const t of s.formulas)t.shared.node&&oe(e,t.shared).volatile&&o.push(t);const n=new Set(o),i=[...o];for(;;){const s=i.pop();if(!s)return n;for(const t of f.readers(s.sheet,s.row,s.col))n.has(t)||(n.add(t),i.push(t))}}function Ce(f,e,o,n){const i={formulas:0,same:0,uncached:0,moving:0,differences:[]},s=Me(o,e);for(const[t,r]of f.carried){if(!t.node)continue;const l=e.sheet(r.name);if(!l)continue;i.formulas+=1;const c=l.at(t.row,t.col);if(c instanceof ae&&s.has(c)){i.moving+=1;continue}const a=O(f,t);if(a===void 0){i.uncached+=1;continue}const u=o.value(l,t.row,t.col);sameValue(a,u,n)?i.same+=1:i.differences.push({sheet:r.name,cell:$(t),formula:M(t.node),file:S(a),engine:S(u)})}for(const[t,r]of f.spilled){const l=e.sheet(r.name);if(!l)continue;i.formulas+=1;const c=l.spillAt(t.row,t.col);if(c&&s.has(c)){i.moving+=1;continue}const a=O(f,t),u=o.value(l,t.row,t.col);a===void 0?i.uncached+=1:sameValue(a,u,n)?i.same+=1:i.differences.push({sheet:r.name,cell:$(t),formula:c?`${$(c)}#`:"",file:S(a),engine:S(u)})}return i}function Oe(f,e){const o=new Map,n=[];for(const i of f){const s=e.find(l=>i.startsWith(`${l}: `));if(s===void 0){n.push(i);continue}const t=i.slice(s.length+2),r=o.get(t);r?r.push(s):o.set(t,[s])}for(const[i,s]of o)n.push(s.length===1?`${s[0]??""}: ${i}`:`${i}, on ${String(s.length)} sheets (${J(s)})`);return n}export function importXlsx(f,e){const o=de(f);if(o.sheets.length===0)throw new Error("It holds no sheets.");const n={book:o,files:new Map,lost:[...o.lost],tables:new Set(o.sheets.flatMap(p=>p.tables.filter(L=>Y(L)===void 0).map(L=>L.name.toLowerCase()))),names:new Set,carried:new Map,spilled:new Map};o.date1904&&n.lost.push(`the 1904 date system: dates are moved to the 1900 one, ${String(q)} days on`),(o.font.name!==void 0&&o.font.name!=="Calibri"||o.font.size!==void 0&&o.font.size!==11)&&n.lost.push(`its default font, ${o.font.name??""} ${String(o.font.size??"")}`);const i=$e(n);pe(n);const s=o.sheets.map(p=>new ye(n,p).build()),t=Le(n,i),r={title:e.name,...b(i)?{}:{names:i},sheets:s,...b(t)?{}:{scenarios:t}},l=ce(r),c=new Map([[Q,l],...n.files]),a=se({text:l,read:p=>c.get(p)}),{workbook:u,calc:d,problems:w}=a;return{files:c,lost:Oe(n.lost,o.sheets.map(p=>p.name)),problems:w,compared:u&&d?Ce(n,u,d,e.tolerance??COMPARE_TOLERANCE):{formulas:0,same:0,uncached:0,moving:0,differences:[]},sheets:o.sheets.length,tables:n.tables.size}}
2
+ import{SHEET_DATA as G,SHEET_FILE as Q}from"@allyhub-next/formats";import{cellName as $,columnLetter as z,contains as A,overlaps as D,rangeName as x,readAddress as Z,readArea as ee}from"../address.js";import{rectangles as _}from"../api/rectangles.js";import{chartAfter as te}from"../chart.js";import{analyse as oe}from"../calc/analyse.js";import{FUNCTIONS as ne}from"../calc/functions/index.js";import{checkWorkbook as se}from"../check.js";import{writeCsv as I}from"../csv.js";import{isDateCode as W}from"../format.js";import{moveFormula as re,relativeKey as B}from"../formula/move.js";import{printFormula as M,sheetPrefix as ie}from"../formula/print.js";import{mapNode as le,walk as N}from"../formula/walk.js";import{CellError as T,isoOfSerial as fe,readTyped as F,writeTyped as P}from"../values.js";import{FormulaCell as ae,placeKey as g,validName as R}from"../workbook.js";import{writeYaml as ce}from"../write.js";import{readFileFormula as ue}from"./formula.js";import{hasDate as H}from"./numfmt.js";import{placesLine as J,readXlsx as de}from"./read.js";const K=100,he=.5,q=1462;export const COMPARE_TOLERANCE=1e-9;const me=f=>f.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/gu,"")||"rows",b=f=>Object.keys(f).length===0,V=(f,e)=>`${String(f)} ${e}${f===1?"":"s"}`,C=f=>({row:f.row,col:f.col});function X(f,e){const o=e.toLowerCase();return le(f,n=>n.kind!=="structured"||n.table?.toLowerCase()!==o?n:Object.fromEntries(Object.entries(n).filter(([i])=>i!=="table")))}function Y(f){return f.headers===0?"has no header row":f.columns.length!==f.ref.right-f.ref.left+1||!R(f.name)?"cannot be held as a table":new Set(f.columns.map(e=>e.name.toLowerCase())).size===f.columns.length?void 0:"has two columns of one name"}function U(f,e,o){let n;const i=new Set;N(f,t=>{t.kind==="call"&&(t.name==="LET"||t.name==="LAMBDA")&&t.args.forEach(r=>{r.kind==="name"&&i.add(r.name.toLowerCase())})});const s=t=>i.has(t)||o===void 0||o.names.has(t)||o.tables.has(t);return N(f,t=>{n===void 0&&(t.kind==="call"&&!ne.has(t.name)&&(s(t.written.toLowerCase())||(n=`no function ${t.name}`)),t.kind==="name"&&!s(t.name.toLowerCase())&&(n=`no name ${t.name}`),t.kind==="structured"&&t.table!==void 0&&!s(t.table.toLowerCase())&&(n=`no table ${t.table}`),(t.kind==="ref"||t.kind==="name"||t.kind==="error")&&t.sheet!==void 0&&(t.sheet.startsWith("[")?n="it reads another workbook":e.has(t.sheet.toLowerCase())||(n=`no sheet ${t.sheet}`)))}),n}function pe(f){const e=new Set(f.book.sheets.map(o=>o.name.toLowerCase()));for(const o of f.book.sheets){const n=new Map,i=(t,r)=>{const l=n.get(r),c=$(t);l?l.push(c):n.set(r,[c])},s=[];for(const t of o.cells){if(t.unread!==void 0){i(t,/^\[|[!']\[|\[\d+\]/u.test(t.unread)?"it reads another workbook":`it could not be read: ${t.unread}`);continue}if(!t.node)continue;const r=U(t.node,e,f);r!==void 0?(delete t.node,i(t,r)):(f.carried.set(t,o),t.array&&x(t.array)!==$(t)&&s.push(t))}we(f,o,s);for(const[t,r]of n)f.lost.push(`${o.name}: ${V(r.length,"formula")} kept as ${r.length===1?"its value":"their values"}, as ${t} (${J(r)})`)}}function we(f,e,o){if(o.length===0)return;const n=new Set;for(const i of o){const{array:s}=i;if(s)for(const t of e.cells)t!==i&&!t.node&&A(s,t.row,t.col)&&n.add(t)}e.cells=e.cells.filter(i=>!n.has(i));for(const i of n)f.spilled.set(i,e)}function O(f,e){const{value:o}=e;if(!f.book.date1904||typeof o!="number")return o;const n=f.book.looks[e.style]?.format;return W(n)&&n!==void 0&&H(n)?o+q:o}function j(f,e){if(typeof f!="number"||e===void 0||!W(e)||!H(e)||f<1)return;const o=fe(f);return F(o).value===f?o:void 0}const ge=(f,e)=>j(f,e)??P(f??null);function ke(f,e){const o=j(f,e);return o!==void 0?o:f==null?null:typeof f=="number"||typeof f=="boolean"?f:P(f)}function be(f){const e={top:1/0,left:1/0,bottom:-1,right:-1};for(const{row:o,col:n}of f)e.top=Math.min(e.top,o),e.left=Math.min(e.left,n),e.bottom=Math.max(e.bottom,o),e.right=Math.max(e.right,n);return e}class ye{ctx;read;byPlace=new Map;inTables=new Set;columnLooks=new Map;rowLooks=new Map;lookDone=new Set;tables=[];areas=[];filtered=[];constructor(e,o){this.ctx=e,this.read=o;for(const n of o.cells)this.byPlace.set(g(n.row,n.col),n)}look(e){return this.ctx.book.looks[e.style]??{}}code(e){return this.look(e).format}text(e){return e.node?M(e.node):ge(O(this.ctx,e),this.code(e))}baseLooks(){const{read:e}=this,{looks:o}=this.ctx.book,n=e.cells.reduce((s,t)=>Math.max(s,t.col),-1);for(const s of e.columns){if(s.style===void 0)continue;const t=o[s.style];if(!(!t||b(t)))for(let r=s.min;r<=Math.min(s.max,n);r++)this.columnLooks.set(r,t)}for(const s of e.rows){const t=s.style===void 0?void 0:o[s.style];t&&!b(t)&&this.rowLooks.set(s.row,t)}const i=(s,t)=>Object.keys(t).every(r=>r in s);for(const s of e.cells){const t=this.look(s),r=this.columnLooks.get(s.col);r&&!i(t,r)&&this.columnLooks.delete(s.col);const l=this.rowLooks.get(s.row);l&&!i(t,l)&&this.rowLooks.delete(s.row)}}ownLook(e){const o={...this.columnLooks.get(e.col),...this.rowLooks.get(e.row)},n={};for(const[s,t]of Object.entries(this.look(e)))JSON.stringify(t)!==JSON.stringify(o[s])&&(n[s]=t);const i=n.format;if(typeof i=="string"){const s=e.node?void 0:j(O(this.ctx,e),i);s!==void 0&&F(s).format===i&&delete n.format}return n}columnFormula(e,o,n){const i=new Map,s=n-o+1;for(let r=o;r<=n;r++){const l=this.byPlace.get(g(r,e));if(!l||l.value===void 0&&!l.node||l.value===null&&!l.node)return;if(!l.node)continue;l.key??=B(l.node,l.row,l.col);const c=i.get(l.key);c?c.n+=1:i.set(l.key,{n:1,cell:l})}let t;for(const r of i.values())(!t||r.n>t.n)&&(t=r);return t&&t.n*2>s?t.cell:void 0}table(e){const{read:o,ctx:n}=this,i=h=>n.lost.push(`${o.name}: table ${e.name} ${h}`),s=e.ref.right-e.ref.left+1,t=Y(e);if(t!==void 0)return i(`${t}, so its cells are kept and it is no table`),!1;const r=e.ref.top,l=r+1,c=e.ref.bottom-e.totals;e.totals>0&&i("has a totals row, kept as plain cells under it");const a=e.columns.map((h,m)=>c>=l?this.columnFormula(e.ref.left+m,l,c):void 0),u=h=>{const m=a[h];if(!m)return!1;for(let k=l;k<=c;k++)if(this.byPlace.get(g(k,e.ref.left+h))?.key!==m.key)return!1;return!0};let d=s;for(;d>1&&u(d-1);)d-=1;const w=[e.columns.slice(0,d).map(h=>h.name)],p={};for(let h=l;h<=c;h++){const m=[];for(let k=0;k<d;k++){const y=this.byPlace.get(g(h,e.ref.left+k)),v=a[k];y?v&&y.key===v.key?m.push(""):y.node?m.push(M(X(y.node,e.name))):m.push(this.text(y)):m.push("")}w.push(m)}for(let h=e.ref.top;h<=c;h++)for(let m=e.ref.left;m<=e.ref.right;m++)this.inTables.add(g(h,m));e.columns.forEach((h,m)=>{const k=e.ref.left+m,y=this.columnLook(k,l,c),v=a[m];v?.node&&(y.formula=M(X(re(v.node,l-v.row,0),e.name))),b(y)||(p[h.name]=y)});const L=this.path(e.name);n.files.set(L,I(w));const E=new Map;for(const[h,m]of e.filter?.columns??[]){const k=e.columns[h]?.name;k!==void 0&&E.set(k,m)}return(e.filter?.unread??0)>0&&i(`has ${V(e.filter?.unread??0,"filter")} by condition, its rows left as they were hidden`),this.tables.push({name:e.name,at:$({row:r,col:e.ref.left}),rows:L,...e.style!==void 0&&e.style!=="TableStyleMedium2"?{style:e.style}:{},...b(p)?{}:{columns:p},...e.filter===void 0?{filter:!1}:E.size>0?{filter:{columns:Object.fromEntries(E)}}:{}}),e.filter?.unread===0&&e.filter.columns.size>0&&this.filtered.push({...e.ref,bottom:c}),this.areas.push({...e.ref,bottom:c}),!0}columnLook(e,o,n){let i,s={};for(let t=o;t<=n;t++){const r=this.byPlace.get(g(t,e)),l=r?this.ownLook(r):{},c=JSON.stringify(l);if(i===void 0)i=c,s=l;else if(i!==c)return{}}if(b(s))return{};for(let t=o;t<=n;t++)this.lookDone.add(g(t,e));return{...s}}path(e){const o=`${G}/${me(e)}`;let n=`${o}.csv`;for(let i=2;this.ctx.files.has(n);i++)n=`${o}-${String(i)}.csv`;return n}loose(){const e=[],o=[];for(const n of this.read.cells)this.inTables.has(g(n.row,n.col))||(n.node?e.push(n):n.value!==void 0&&n.value!==null&&o.push(n));return{formulas:e,typed:o}}blockAreas(e,o){const n=new Map;e.forEach((a,u)=>n.set(g(a.row,a.col),u));const i=e.map((a,u)=>u),s=a=>{let u=a;for(;i[u]!==u;){const d=i[i[u]??u]??u;i[u]=d,u=d}return u};e.forEach((a,u)=>{for(const d of[n.get(g(a.row,a.col-1)),n.get(g(a.row-1,a.col))])d!==void 0&&(i[s(u)]=s(d))});const t=new Map;e.forEach((a,u)=>{const d=s(u),w=t.get(d);w?w.push(a):t.set(d,[a])});const r=[],l=a=>!r.some(u=>D(u,a))&&!this.areas.some(u=>D(u,a))&&!o.some(u=>A(a,u.row,u.col)),c=a=>(a.bottom-a.top+1)*(a.right-a.left+1);for(const a of t.values()){const u=be(a);if(!(c(u)<K)){if(a.length/c(u)>=he&&l(u)){r.push(u);continue}for(const d of _(a.map(C)))c(d)>=K&&l(d)&&r.push(d)}}return r.sort((a,u)=>a.top-u.top||a.left-u.left)}cells(e){const{formulas:o,typed:n}=this.loose(),i=this.blockAreas(n,o),s=l=>i.some(c=>A(c,l.row,l.col));i.length>0&&(e.blocks=i.map(l=>{const c=[];for(let u=l.top;u<=l.bottom;u++){const d=[];for(let w=l.left;w<=l.right;w++){const p=this.byPlace.get(g(u,w));d.push(p?this.text(p):"")}c.push(d)}const a=this.path(this.read.name);return this.ctx.files.set(a,I(c)),{at:$({row:l.top,col:l.left}),rows:a}}));const t=[],r=new Map;for(const l of o){if(!l.node)continue;l.key??=B(l.node,l.row,l.col);const c=r.get(l.key);c?c.push(l):r.set(l.key,[l])}for(const l of r.values())for(const c of _(l.map(C))){const a=this.byPlace.get(g(c.top,c.left));a?.node&&t.push([{row:c.top,col:c.left},x(c),M(a.node)])}for(const l of n)i.length>0&&s(l)||t.push([C(l),$(l),ke(O(this.ctx,l),this.code(l))]);t.sort(([l],[c])=>l.row-c.row||l.col-c.col),t.length>0&&(e.cells=Object.fromEntries(t.map(([,l,c])=>[l,c])))}formats(e){const o=new Map;for(const i of this.read.cells){if(this.lookDone.has(g(i.row,i.col)))continue;const s=this.ownLook(i);if(b(s))continue;const t=JSON.stringify(s),r=o.get(t);r?r.places.push(C(i)):o.set(t,{look:s,places:[C(i)]})}const n=[];for(const{look:i,places:s}of o.values())for(const t of _(s))n.push({range:x(t),...i});n.length>0&&(e.format=n)}columns(e){const{read:o}=this,n=new Map,i=o.cells.reduce((t,r)=>Math.max(t,r.col),0),s=[];for(const t of o.columns)if(!(t.width===void 0&&t.hidden!==!0)){t.max>i&&s.push(z(Math.max(t.min,i+1)));for(let r=t.min;r<=Math.min(t.max,i);r++)n.set(r,{...t.width===void 0?{}:{width:t.width},...t.hidden===!0?{hidden:!0}:{}})}for(const[t,r]of this.columnLooks)n.set(t,{...n.get(t),...r});n.size>0&&(e.columns=Object.fromEntries([...n.keys()].sort((t,r)=>t-r).map(t=>[z(t),n.get(t)??{}]))),s.some(Boolean)&&o.columns.some(t=>t.max>i&&t.hidden===!0)&&this.ctx.lost.push(`${o.name}: the size of the columns past its last used one`)}rows(e){const o={};for(const n of this.read.rows){const i=this.rowLooks.get(n.row),s=this.filtered.some(r=>n.row>r.top&&n.row<=r.bottom),t={...n.height===void 0?{}:{height:n.height},...n.hidden===!0&&!s?{hidden:!0}:{},...i};b(t)||(o[String(n.row+1)]=t)}b(o)||(e.rows=o)}build(){const{read:e}=this;this.baseLooks();for(const n of e.tables)this.table(n);const o={name:e.name};return e.state!=="visible"&&(o.hidden=!0),e.gridlines===!1&&(o.gridlines=!1),e.tab!==void 0&&(o.tab=e.tab),e.state==="veryHidden"&&this.ctx.lost.push(`${e.name}: being very hidden; it is hidden`),e.freeze&&(e.freeze.row>0||e.freeze.col>0)&&(o.freeze=$(e.freeze)),this.tables.length>0&&(o.tables=this.tables),this.filter(o),this.columns(o),this.rows(o),this.cells(o),e.merges.length>0&&(o.merges=e.merges.map(x)),this.formats(o),e.conditional.length>0&&(o.conditional=e.conditional),e.validations.length>0&&(o.validations=e.validations),e.charts.length>0&&(o.charts=e.charts.map(n=>this.chart(n))),o}chart(e){return te(e,o=>{const n=this.chartReference(o.replace(/^=/u,""));return o.startsWith("=")?`=${n}`:n})}chartReference(e){const o=e.lastIndexOf("!"),i=(o<0?this.read.name:e.slice(0,o)).replace(/^'|'$/gu,"").replaceAll("''","'"),s=ee(e.slice(o+1).replaceAll("$",""));if(!s)return e;const t=this.ctx.book.sheets.find(r=>r.name.toLowerCase()===i.toLowerCase());for(const r of t?.tables??[]){const l=r.ref.top+1,a=s.left===s.right&&s.top===l&&s.bottom===r.ref.bottom&&s.left>=r.ref.left&&s.left<=r.ref.right?r.columns[s.left-r.ref.left]:void 0;if(a&&this.ctx.tables.has(r.name.toLowerCase()))return`${r.name}[${a.name}]`}return`${t===this.read||o<0?"":`${e.slice(0,o)}!`}${x(s)}`}filter(e){const{filter:o}=this.read;if(!o)return;const n={};for(const[i,s]of o.columns)n[z(o.ref.left+i)]=s;e.filter={range:x(o.ref),...b(n)?{}:{columns:n}},o.unread===0&&!b(n)&&this.filtered.push(o.ref)}}function $e(f){const e={},{book:o,lost:n}=f,i=new Set(o.sheets.map(r=>r.name.toLowerCase())),s=new Set,t=new Set;for(const r of o.names){if(r.name.startsWith("_xlnm.")){r.name==="_xlnm.Print_Area"?t.add("print areas"):r.name==="_xlnm.Print_Titles"?t.add("print titles"):r.name!=="_xlnm._FilterDatabase"&&n.push(`Excel's name ${r.name}`);continue}if(/^_xl(?:fn|pm|ws|udf)/iu.test(r.name))continue;const l=r.name.toLowerCase();if(!R(r.name)||f.tables.has(l)){n.push(`the name ${r.name}, which cannot be held here`);continue}if(s.has(l)){n.push(`a second name ${r.name}, for one sheet: names here are the workbook's`);continue}const c=xe(r.text);if(c!==void 0)e[r.name]=typeof c=="string"?P(c):c,s.add(l),f.names.add(l);else{const a=ue(r.text,!0),u=a.ok?U(a.node,i):"it could not be read";if(!a.ok||u!==void 0||ve(a.node)){n.push(`the name ${r.name} (${r.text})${u===void 0?"":`: ${u}`}`);continue}e[r.name]=M(a.node),s.add(l),f.names.add(l)}r.sheet!==void 0&&n.push(`the name ${r.name} belonging to one sheet: here it is the workbook's`)}return t.size>0&&n.push([...t].join(" and ")),e}function Le(f,e){const o={},n=new Map;for(const[i,s]of Object.entries(e))typeof s=="string"&&s.startsWith("=")&&n.set(s.slice(1).replaceAll("$","").toLowerCase(),i);for(const i of f.book.sheets)for(const s of i.scenarios){const t={};let r=!0;for(const{at:l,value:c}of s.cells){const a=Z(l),u=a&&i.cells.find(p=>p.row===a.row&&p.col===a.col);String(u?.value??"")!==c&&(r=!1);const d=n.get(`${ie(i.name)}${l}`.toLowerCase())??n.get(l.toLowerCase()),w=F(c);d===void 0?f.lost.push(`${i.name}: scenario ${s.name}'s cell ${l}, which has no name`):t[d]=typeof w.value=="number"?w.value:c}!r&&!b(t)&&(o[s.name]={...o[s.name],...t})}return o}function ve(f){let e=!1;return N(f,o=>{e||=o.kind==="error"&&o.code==="#REF!"}),e}function xe(f){const e=f.trim();return/^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/u.test(e)?Number(e):/^true$/iu.test(e)?!0:/^false$/iu.test(e)?!1:/^"((?:[^"]|"")*)"$/u.exec(e)?.[1]?.replaceAll('""','"')}const S=f=>f instanceof T?f.code:f??null;export function sameValue(f,e,o){if(typeof f=="number"&&typeof e=="number")return f===e?!0:Math.abs(f-e)<=Math.max(Math.abs(f),Math.abs(e))*o;if(f instanceof T||e instanceof T)return f?.code===e?.code;if(f===null||e===null){const n=f??e;return n===null||n===""||n===0||n===!1}return f===e}function Me(f,e){const o=[];for(const s of e.sheets)for(const t of s.formulas)t.shared.node&&oe(e,t.shared).volatile&&o.push(t);const n=new Set(o),i=[...o];for(;;){const s=i.pop();if(!s)return n;for(const t of f.readers(s.sheet,s.row,s.col))n.has(t)||(n.add(t),i.push(t))}}function Ce(f,e,o,n){const i={formulas:0,same:0,uncached:0,moving:0,differences:[]},s=Me(o,e);for(const[t,r]of f.carried){if(!t.node)continue;const l=e.sheet(r.name);if(!l)continue;i.formulas+=1;const c=l.at(t.row,t.col);if(c instanceof ae&&s.has(c)){i.moving+=1;continue}const a=O(f,t);if(a===void 0){i.uncached+=1;continue}const u=o.value(l,t.row,t.col);sameValue(a,u,n)?i.same+=1:i.differences.push({sheet:r.name,cell:$(t),formula:M(t.node),file:S(a),engine:S(u)})}for(const[t,r]of f.spilled){const l=e.sheet(r.name);if(!l)continue;i.formulas+=1;const c=l.spillAt(t.row,t.col);if(c&&s.has(c)){i.moving+=1;continue}const a=O(f,t),u=o.value(l,t.row,t.col);a===void 0?i.uncached+=1:sameValue(a,u,n)?i.same+=1:i.differences.push({sheet:r.name,cell:$(t),formula:c?`${$(c)}#`:"",file:S(a),engine:S(u)})}return i}function Oe(f,e){const o=new Map,n=[];for(const i of f){const s=e.find(l=>i.startsWith(`${l}: `));if(s===void 0){n.push(i);continue}const t=i.slice(s.length+2),r=o.get(t);r?r.push(s):o.set(t,[s])}for(const[i,s]of o)n.push(s.length===1?`${s[0]??""}: ${i}`:`${i}, on ${String(s.length)} sheets (${J(s)})`);return n}export function importXlsx(f,e){const o=de(f,e.zip);if(o.sheets.length===0)throw new Error("It holds no sheets.");const n={book:o,files:new Map,lost:[...o.lost],tables:new Set(o.sheets.flatMap(p=>p.tables.filter(L=>Y(L)===void 0).map(L=>L.name.toLowerCase()))),names:new Set,carried:new Map,spilled:new Map};o.date1904&&n.lost.push(`the 1904 date system: dates are moved to the 1900 one, ${String(q)} days on`),(o.font.name!==void 0&&o.font.name!=="Calibri"||o.font.size!==void 0&&o.font.size!==11)&&n.lost.push(`its default font, ${o.font.name??""} ${String(o.font.size??"")}`);const i=$e(n);pe(n);const s=o.sheets.map(p=>new ye(n,p).build()),t=Le(n,i),r={title:e.name,...b(i)?{}:{names:i},sheets:s,...b(t)?{}:{scenarios:t}},l=ce(r),c=new Map([[Q,l],...n.files]),a=se({text:l,read:p=>c.get(p)}),{workbook:u,calc:d,problems:w}=a;return{files:c,lost:Oe(n.lost,o.sheets.map(p=>p.name)),problems:w,compared:u&&d?Ce(n,u,d,e.tolerance??COMPARE_TOLERANCE):{formulas:0,same:0,uncached:0,moving:0,differences:[]},sheets:o.sheets.length,tables:n.tables.size}}
@@ -1,3 +1,4 @@
1
+ import { type ZipLimits } from "@allyhub-next/formats";
1
2
  import type { SheetConditional, SheetFilterColumn, SheetValidation } from "@allyhub-next/formats";
2
3
  import { type Area, type Place } from "../address.js";
3
4
  import type { Node } from "../formula/ast.js";
@@ -113,5 +114,5 @@ export interface ReadBook {
113
114
  /** Places as a line: the first few and how many more. */
114
115
  export declare function placesLine(places: readonly string[]): string;
115
116
  /** What a .xlsx, .xlsm or .xltx file holds. */
116
- export declare function readXlsx(bytes: Uint8Array): ReadBook;
117
+ export declare function readXlsx(bytes: Uint8Array, zip?: Partial<ZipLimits>): ReadBook;
117
118
  //# sourceMappingURL=read.d.ts.map
@@ -1,2 +1,2 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{strFromU8 as ie,unzipSync as ae}from"fflate";import{SHEET_ICONS as le,SHEET_OPERATORS as ce,SHEET_VALIDATIONS as de}from"@allyhub-next/formats";import{cellName as J,readAddress as K,readArea as z,readAreas as Q}from"../address.js";import{SHEET_CHART_DEFAULTS as Y}from"../chart.js";import{moveFormula as ue,relativeKey as fe}from"../formula/move.js";import{printFormula as Z}from"../formula/print.js";import{ERR as me,errorOf as he,serialOfDate as pe}from"../values.js";import{OFFICE_THEME as be,colorOf as C,paletteOf as ee,themeColors as ge}from"./colors.js";import{chartAnchors as xe,readChart as ye}from"./charts.js";import{readFileFormula as P}from"./formula.js";import{BUILTIN_FORMATS as we}from"./numfmt.js";import{attr as d,flag as k,numberAttr as x,readXml as ve,readXstring as L,tag as l,tags as b,textOf as F}from"./xml.js";const te=7,ke=o=>Math.floor((256*o+Math.floor(128/te))/256*te),$e=o=>Math.round(o*4/3),B=5;export function placesLine(o){const e=o.slice(0,B).join(", ");return o.length>B?`${e} and ${String(o.length-B)} more`:e}const H=(o,e,t=`${e}s`)=>`${String(o)} ${o===1?e:t}`;class Se{parts;names;constructor(e){this.parts=ae(e),this.names=Object.keys(this.parts)}has(e){return this.parts[e]!==void 0}text(e){const t=this.parts[e];return t?ie(t):void 0}xml(e){const t=this.text(e);return t===void 0?void 0:ve(t)}rels(e){const t=e.lastIndexOf("/"),n=`${e.slice(0,t+1)}_rels/${e.slice(t+1)}.rels`,s=this.xml(n);return b(l(s?.Relationships)?.Relationship).map(r=>{const a=d(r,"Type")??"",c=d(r,"Target")??"",i=d(r,"TargetMode")==="External";return{id:d(r,"Id")??"",type:a.slice(a.lastIndexOf("/")+1),target:i?c:Te(e,c),external:i}})}count(e){return this.names.filter(t=>e.test(t)).length}}function Te(o,e){if(e.startsWith("/"))return e.slice(1);const t=o.split("/").slice(0,-1);for(const n of e.split("/"))n===".."?t.pop():n!=="."&&t.push(n);return t.join("/")}function Ee(o,e){const t=e===void 0?void 0:o.xml(e);return b(l(t?.sst)?.si).map(n=>{const s=b(n.r);return s.length>0?{text:L(s.map(r=>F(r.t)).join("")),rich:!0}:{text:L(F(n.t)),rich:!1}})}function M(o,e){const t=o[e];if(t===void 0)return!1;const n=d(l(t),"val");return n===void 0||n!=="0"&&n!=="false"}const Oe=new Set(["double","singleAccounting","doubleAccounting"]);function Ie(o,e,t){const n={},s=(i,m)=>d(l(i?.[m]),"val");if(M(o,"b")&&(n.bold=!0),M(o,"i")&&(n.italic=!0),M(o,"strike")&&(n.strike=!0),M(o,"u")){const i=s(o,"u");n.underline=i!==void 0&&Oe.has(i)?i:!0}const r=s(o,"name");r!==void 0&&r!==s(e,"name")&&(n.font=r);const a=s(o,"sz");a!==void 0&&a!==s(e,"sz")&&(n.size=Number(a));const c=C(l(o.color),t);return c!==void 0&&c!==C(l(e?.color),t)&&(n.color=c),n}function Ae(o,e){const t=l(o.patternFill),n=d(t,"patternType");if(n===void 0||n==="none")return;const s=C(l(t?.fgColor),e),r=C(l(t?.bgColor),e);return n==="solid"&&s!==void 0?s:{pattern:n,...s===void 0?{}:{color:s},...r===void 0?{}:{background:r}}}function ne(o,e){const t={};for(const n of["left","right","top","bottom"]){const s=l(o[n]),r=d(s,"style");if(r===void 0||r==="none")continue;const a=C(l(s?.color),e);t[n]={style:r,...a===void 0?{}:{color:a}}}return Object.keys(t).length===0?void 0:t}function Ce(o){const e={},t=d(o,"horizontal");t!==void 0&&t!=="general"&&(e.align=t);const n=d(o,"vertical");n!==void 0&&n!=="bottom"&&(e.valign=n),k(o,"wrapText")===!0&&(e.wrap=!0),k(o,"shrinkToFit")===!0&&(e.shrink=!0);const s=x(o,"indent");s!==void 0&&s>0&&(e.indent=s);const r=x(o,"textRotation");return r!==void 0&&r>0&&r<=180&&(e.rotation=r),e}function Fe(o,e){const t={},n=l(o.font);if(n){const i=(f,u)=>{n[f]!==void 0&&(t[u]=M(n,f))};i("b","bold"),i("i","italic"),i("strike","strike"),n.u!==void 0&&(t.underline=M(n,"u"));const m=C(l(n.color),e);m!==void 0&&(t.color=m)}const s=l(l(o.fill)?.patternFill),r=C(l(s?.bgColor),e)??C(l(s?.fgColor),e);r!==void 0&&(t.fill=r);const a=l(o.border),c=a&&ne(a,e);return c!==void 0&&(t.border=c),t}function Re(o,e){const t=l(o?.styleSheet),n=ee(e,t),s=new Map(b(l(t?.numFmts)?.numFmt).map(p=>[x(p,"numFmtId")??-1,d(p,"formatCode")??"General"])),r=b(l(t?.fonts)?.font),a=b(l(t?.fills)?.fill),c=b(l(t?.borders)?.border),i=b(l(t?.cellXfs)?.xf),m=r[x(i[0],"fontId")??0],f=new Set;a.some(p=>p.gradientFill!==void 0)&&f.add("gradient fills");const u=i.map(p=>{const y={},$=r[x(p,"fontId")??0];$&&(Object.assign(y,Ie($,m,n)),$.vertAlign!==void 0&&f.add("superscript and subscript"));const T=a[x(p,"fillId")??0],O=T&&Ae(T,n);O!==void 0&&(y.fill=O);const R=c[x(p,"borderId")??0],I=R&&ne(R,n);I!==void 0&&(y.border=I),R&&d(l(R.diagonal),"style")!==void 0&&f.add("diagonal borders");const w=l(p.alignment);w&&(Object.assign(y,Ce(w)),x(w,"textRotation")===255&&f.add("vertical text"));const S=x(p,"numFmtId")??0,A=s.get(S)??we[S];return A!==void 0&&A!=="General"&&(y.format=A),y}),h=d(l(m?.name),"val"),v=d(l(m?.sz),"val");return{looks:u,dxfs:b(l(t?.dxfs)?.dxf).map(p=>Fe(p,n)),font:{...h===void 0?{}:{name:h},...v===void 0?{}:{size:Number(v)}},lost:[...f]}}function oe(o){const e=new Map;let t=0;for(const n of b(o.filterColumn)){const s=x(n,"colId")??0,r=l(n.filters);if(!r){Object.keys(n).some(c=>c!=="colId"&&c!=="hiddenButton")&&(t+=1);continue}if(r.dateGroupItem!==void 0){t+=1;continue}const a=b(r.filter).map(c=>L(d(c,"val")??""));e.set(s,{...a.length===0?{}:{values:a},...k(r,"blank")===!0?{blanks:!0}:{}})}return{columns:e,unread:t}}function Le(o){const e=l(o?.table),t=z(d(e,"ref")??""),n=d(e,"displayName")??d(e,"name");if(!t||n===void 0)return;const s=l(e?.tableStyleInfo),r=l(e?.autoFilter);return{name:n,ref:t,headers:x(e,"headerRowCount")??1,totals:x(e,"totalsRowCount")??0,columns:b(l(e?.tableColumns)?.tableColumn).map(a=>({name:L(d(a,"name")??"").trim(),calculated:a.calculatedColumnFormula!==void 0})),style:d(s,"name")??"none",...r?{filter:oe(r)}:{}}}function W(o){const e=o.trim();if(e==="")return;const t=/^"((?:[^"]|"")*)"$/u.exec(e);if(t)return(t[1]??"").replaceAll('""','"');const n=Number(e);if(!Number.isNaN(n))return n;const s=P(e,!0);return s.ok?Z(s.node):void 0}const re=o=>o!==void 0&&ce.includes(o);function q(o){const e=d(o,"type")??"num",t=d(o,"val"),n=t===void 0?void 0:W(t);return{at:e,...n===void 0?{}:{value:n}}}const Ne=le;function je(o,e,t,n){const s=d(o,"type")??"",r={range:e,...k(o,"stopIfTrue")===!0?{stop:!0}:{}},a=x(o,"dxfId"),c=a===void 0?{}:t[a]??{},i={...c.bold===void 0?{}:{bold:c.bold},...c.italic===void 0?{}:{italic:c.italic},...c.underline===void 0?{}:{underline:c.underline!==!1},...c.strike===void 0?{}:{strike:c.strike},...c.color===void 0?{}:{color:c.color},...typeof c.fill=="string"?{fill:c.fill}:{},...c.border===void 0?{}:{border:c.border}},m=o.formula,f=(Array.isArray(m)?m:m===void 0?[]:[m]).map(F);switch(s){case"cellIs":{const u=d(o,"operator"),h=f.flatMap(v=>{const p=W(v);return p===void 0?[]:[p]});return!re(u)||h.length===0?`a cellIs rule of ${u??"no operator"}`:{...r,...i,type:"cellIs",operator:u,formula:h}}case"containsText":case"notContainsText":case"beginsWith":case"endsWith":{const u=d(o,"text");return u===void 0?`a ${s} rule with no text`:{...r,...i,type:"containsText",...s==="containsText"?{}:{operator:s==="notContainsText"?"notContains":s},text:L(u)}}case"duplicateValues":case"uniqueValues":return{...r,...i,type:s};case"top10":return{...r,...i,type:"top10",rank:x(o,"rank")??10,...k(o,"percent")===!0?{percent:!0}:{},...k(o,"bottom")===!0?{bottom:!0}:{}};case"aboveAverage":return{...r,...i,type:"aboveAverage",...k(o,"aboveAverage")===!1?{below:!0}:{},...k(o,"equalAverage")===!0?{equal:!0}:{}};case"expression":{const u=f[0]===void 0?void 0:P(f[0],!0);return u?.ok?{...r,...i,type:"expression",formula:Z(u.node)}:"an expression rule that cannot be read"}case"dataBar":{const u=l(o.dataBar),h=C(l(u?.color),n),[v,p]=b(u?.cfvo).map(q);return h===void 0?"a data bar with no colour":{...r,type:"dataBar",color:h,...v&&v.at!=="min"?{min:v}:{},...p&&p.at!=="max"?{max:p}:{},...k(u,"showValue")===!1?{show:!1}:{}}}case"colorScale":{const u=l(o.colorScale),h=b(u?.cfvo).map(q),v=b(u?.color).map(y=>C(y,n)),p=h.flatMap((y,$)=>{const T=v[$];return T===void 0?[]:[{...y,color:T}]});return p.length<2?"a colour scale with too few stops":{...r,type:"colorScale",stops:p.slice(0,3)}}case"iconSet":{const u=l(o.iconSet),h=d(u,"iconSet")??"3TrafficLights1";if(!Ne.includes(h))return`the icon set ${h}`;const v=b(u?.cfvo).map(q);return{...r,type:"iconSet",icons:h,...v.length>=3?{stops:v.slice(0,5)}:{},...k(u,"reverse")===!0?{reverse:!0}:{},...k(u,"showValue")===!1?{show:!1}:{}}}default:return`a ${s} rule`}}function Me(o,e,t){const n=[],s=[];for(const r of b(o.conditionalFormatting)){const a=d(r,"sqref")??"";if(!Q(a)){s.push(`a rule on ${a}`);continue}for(const c of b(r.cfRule)){const i=je(c,a,e,t);typeof i=="string"?s.push(`${i} on ${a}`):n.push({priority:x(c,"priority")??0,rule:i})}}return{rules:n.sort((r,a)=>r.priority-a.priority).map(r=>r.rule),unread:s}}const De=de;function Ve(o){const e=[],t=[];for(const n of b(l(o.dataValidations)?.dataValidation)){const s=d(n,"sqref")??"",r=d(n,"type")??"none";if(r==="none"&&d(n,"prompt")===void 0)continue;if(!De.includes(r)||!Q(s)){t.push(`a ${r} rule on ${s}`);continue}const a=F(n.formula1),c=F(n.formula2),i=/^"((?:[^"]|"")*)"$/u.exec(a.trim()),m=r==="list"&&i?(i[1]??"").replaceAll('""','"').split(","):void 0,f=[a,c].flatMap(T=>{const O=W(T);return O===void 0?[]:[O]}),u=d(n,"operator"),h=T=>Object.fromEntries(Object.entries(T).filter(([,O])=>O!==void 0)),v=h({title:d(n,"promptTitle"),message:d(n,"prompt")}),p=h({style:d(n,"errorStyle"),title:d(n,"errorTitle"),message:d(n,"error")}),y=k(n,"showInputMessage")!==!0,$=k(n,"showErrorMessage")!==!0;e.push({range:s,type:r,...re(u)&&u!=="between"?{operator:u}:{},...m?{values:m}:{formula:f},...k(n,"allowBlank")===!0?{}:{blank:!1},...k(n,"showDropDown")===!0?{dropdown:!1}:{},...y||Object.keys(v).length>0?{prompt:{...v,...y?{show:!1}:{}}}:{},...$||Object.keys(p).length>0?{error:{...p,...$?{show:!1}:{}}}:{}})}return{rules:e,unread:t}}function U(o,e){const t=P(o,e);return t.ok?{node:t.node}:{unread:o}}class ze{cells=[];rich=[];masters=new Map;strings;constructor(e){this.strings=e}value(e,t){const n=d(e,"t")??"n",s=e.v;if(n==="inlineStr"){const a=l(e.is),c=b(a?.r);return c.length>0?{value:L(c.map(i=>F(i.t)).join("")),rich:!0}:{value:L(F(a?.t))}}if(s===void 0)return{value:void 0};const r=F(s);switch(n){case"s":{const a=this.strings[Number(r)];return a?{value:a.text,...a.rich?{rich:!0}:{}}:{value:""}}case"str":return{value:L(r)};case"b":return{value:r.trim()==="1"||r.trim()==="true"};case"e":return{value:he(r.trim())??me.VALUE};case"d":{const a=new Date(r.trim());return{value:Number.isNaN(a.getTime())?r:pe(a)}}default:{if(r.trim()==="")return{value:void 0};const a=Number(r);if(Number.isNaN(a))throw new Error(`${t} says it holds a number and holds ${r}.`);return{value:a}}}}formula(e,t,n,s){const r=e.f;if(r===void 0)return;const a=l(r),c=d(a,"t")??"normal",i=F(r);if(c==="dataTable"){s.unread=`a data table's {=TABLE(${d(a,"r1")??""})}`;return}if(c==="array"){const m=e.cm!==void 0;Object.assign(s,U(i,!0));const f=z(d(a,"ref")??"");f&&(s.array=f),m&&(s.dynamic=!0);return}if(c==="shared"){const m=d(a,"si")??"";if(i!==""){const u=U(i,!1);this.masters.set(m,{node:u.node,unread:u.unread,row:t,col:n,key:u.node?fe(u.node,t,n):"",dynamicArray:!1}),Object.assign(s,u),u.node&&(s.key=this.masters.get(m)?.key??"");return}const f=this.masters.get(m);if(!f){s.unread=`a shared formula of a group that has no first cell (${m})`;return}f.node?(s.node=ue(f.node,t-f.row,n-f.col),s.key=f.key):f.unread!==void 0&&(s.unread=f.unread);return}i!==""&&Object.assign(s,U(i,!1))}readRows(e){let t=0;for(const n of e){const s=x(n,"r"),r=s===void 0?t:s-1;t=r+1;let a=0;for(const c of b(n.c)){const i=d(c,"r"),f=(i===void 0?void 0:K(i))?.col??a;a=f+1;const u=i??J({row:r,col:f}),{value:h,rich:v}=this.value(c,u),p={row:r,col:f,value:h,style:x(c,"s")??0};v===!0&&(p.rich=!0,this.rich.push(u)),this.formula(c,r,f,p),this.cells.push(p)}}}}function He(o,e,t){const n=[],s=i=>n.push(`${o}: ${i}`);t.length>0&&s(`${H(t.length,"cell")} of rich text, kept as plain text (${placesLine(t)})`);const r=b(l(e.hyperlinks)?.hyperlink);r.length>0&&s(`${H(r.length,"hyperlink")} (${placesLine(r.map(i=>d(i,"ref")??""))})`),e.sortState!==void 0&&s("a sort"),k(l(e.sheetProtection),"sheet")===!0&&s("protection"),e.protectedRanges!==void 0&&s("protected ranges"),e.headerFooter!==void 0&&F(e.headerFooter).trim()!==""&&s("its print header and footer"),l(e.headerFooter)?.oddHeader!==void 0&&s("its print header"),l(e.headerFooter)?.oddFooter!==void 0&&s("its print footer"),(e.rowBreaks!==void 0||e.colBreaks!==void 0)&&s("its page breaks"),e.oleObjects!==void 0&&s("embedded objects"),e.controls!==void 0&&s("form controls"),e.dataConsolidate!==void 0&&s("a consolidation"),e.customSheetViews!==void 0&&s("custom views"),b(l(e.sheetViews)?.sheetView).some(i=>d(l(i.pane),"state")==="split")&&s("a split, not frozen, window");const c=JSON.stringify(e.extLst??"");return c.includes("sparklineGroups")&&s("sparklines"),X(e.extLst)&&s("conditional formats of Excel 2010 and later"),c.includes("dataValidations")&&s("data validations of Excel 2010 and later"),c.includes("slicerList")&&s("slicers"),n}function X(o){if(typeof o!="object"||o===null)return!1;if(Array.isArray(o))return o.some(X);const e=o;return b(e.cfRule).some(t=>d(t,"type")!=="dataBar")&&e.cfRule!==void 0?!0:Object.values(e).some(X)}function _e(o){const e=[],t=(n,s,r)=>{const a=o.count(n);a>0&&e.push(H(a,s,r))};return o.has("xl/vbaProject.bin")&&e.push("VBA macros"),t(/^xl\/pivotTables\/pivotTable\d*\.xml$/u,"pivot table"),t(/^xl\/chartsheets\/[^/]+\.xml$/u,"chart sheet"),t(/^xl\/dialogsheets\/[^/]+\.xml$/u,"dialog sheet"),t(/^xl\/macrosheets\/[^/]+\.xml$/u,"macro sheet"),t(/^xl\/media\//u,"image"),t(/^xl\/embeddings\//u,"embedded object"),t(/^xl\/comments\d*\.xml$/u,"sheet's comments","sheets' comments"),t(/^xl\/threadedComments\//u,"sheet's threaded comments","sheets' threaded comments"),t(/^xl\/slicers\/[^/]+\.xml$/u,"slicer part"),t(/^xl\/timelines\/[^/]+\.xml$/u,"timeline part"),t(/^xl\/ctrlProps\/[^/]+\.xml$/u,"form control"),t(/^xl\/activeX\/[^/]+\.xml$/u,"ActiveX control"),t(/^xl\/queryTables\/[^/]+\.xml$/u,"query table"),o.has("xl/connections.xml")&&e.push("data connections"),o.names.some(n=>n.startsWith("xl/richData/"))&&e.push("rich values (data types, pictures in cells)"),o.names.some(n=>/^customXml\/item\d+\.xml$/u.test(n)&&(o.text(n)??"").includes("DataMashup"))&&e.push("Power Query queries"),e}function Pe(o,e,t,n,s,r,a){const c=o.xml(e),i=l(c?.worksheet);if(!i)throw new Error(`${e} is not a worksheet.`);const m=new ze(s);m.readRows(b(l(i.sheetData)?.row));const f=b(l(i.cols)?.col).map(g=>{const E=x(g,"width"),D=x(g,"style");return{min:(x(g,"min")??1)-1,max:(x(g,"max")??1)-1,...E===void 0||k(g,"customWidth")===!1?{}:{width:ke(E)},...k(g,"hidden")===!0?{hidden:!0}:{},...D===void 0||D===0?{}:{style:D}}}),u=[];let h=b(l(i.cols)?.col).some(g=>(x(g,"outlineLevel")??0)>0);b(l(i.sheetData)?.row).forEach((g,E)=>{const D=(x(g,"r")??E+1)-1;(x(g,"outlineLevel")??0)>0&&(h=!0);const G=x(g,"ht"),_=x(g,"s"),V={row:D};G!==void 0&&k(g,"customHeight")===!0&&(V.height=$e(G)),k(g,"hidden")===!0&&(V.hidden=!0),_!==void 0&&_!==0&&k(g,"customFormat")===!0&&(V.style=_),Object.keys(V).length>1&&u.push(V)});const v=b(l(i.mergeCells)?.mergeCell).flatMap(g=>{const E=z(d(g,"ref")??"");return E?[E]:[]}),p=b(l(i.sheetViews)?.sheetView)[0],y=l(p?.pane);let $;const T=d(y,"state");if(T==="frozen"||T==="frozenSplit"){const g=K(d(p,"topLeftCell")??"A1")??{row:0,col:0};$={row:g.row+(x(y,"ySplit")??0),col:g.col+(x(y,"xSplit")??0)}}const O=o.rels(e).filter(g=>g.type==="table").flatMap(g=>{const E=Le(o.xml(g.target));return E?[E]:[]}),R=C(l(l(i.sheetPr)?.tabColor),r),I=He(t,i,m.rich);h&&I.push(`${t}: its grouped rows or columns, left ungrouped`);const w=Me(i,a,r),S=Ve(i);for(const g of w.unread)I.push(`${t}: a conditional format, ${g}`);for(const g of S.unread)I.push(`${t}: a data validation, ${g}`);const A=l(i.autoFilter),j=z(d(A,"ref")??""),N=A&&j?{ref:j,...oe(A)}:void 0;N&&N.unread>0&&I.push(`${t}: ${H(N.unread,"filter")} by condition on ${d(A,"ref")??""}, its rows left as they were hidden`);const se=qe(o,e,t,f,u,I);return{sheet:{name:t,state:n,cells:m.cells,merges:v,...$?{freeze:$}:{},...d(p,"showGridLines")==="0"?{gridlines:!1}:{},...R===void 0?{}:{tab:R},columns:f,rows:u,tables:O,conditional:w.rules,validations:S.rules,scenarios:b(l(i.scenarios)?.scenario).map(g=>({name:d(g,"name")??"",cells:b(g.inputCells).map(E=>({at:d(E,"r")??"",value:d(E,"val")??""}))})),...N?{filter:N}:{},charts:se},lost:I}}const Be=64,We=20;function qe(o,e,t,n,s,r){const a=m=>n.find(f=>m>=f.min&&m<=f.max)?.width??Be,c=m=>s.find(f=>f.row===m)?.height??We,i=[];for(const m of o.rels(e).filter(f=>f.type==="drawing")){const{anchors:f}=xe(o.xml(m.target),a,c),u=o.rels(m.target);for(const h of f){const v=u.find($=>$.id===h.id),p=ye(v?o.xml(v.target):void 0),y=J(h.at);if(typeof p=="string"){r.push(`${t}: the chart at ${y}, as ${p}`);continue}i.push({...p,at:y,...h.x===void 0?{}:{x:h.x},...h.y===void 0?{}:{y:h.y},...h.width===Y.width?{}:{width:h.width},...h.height===Y.height?{}:{height:h.height}})}}return i}export function readXlsx(o){let e;try{e=new Se(o)}catch{throw new Error("It is not a zip file, as an .xlsx file is.")}const n=e.rels("").find(w=>w.type==="officeDocument")?.target??"xl/workbook.xml";if(n.endsWith(".bin"))throw new Error("It is a binary workbook (.xlsb): save it as .xlsx.");const s=e.xml(n),r=l(s?.workbook);if(!r)throw new Error("It has no workbook part.");const a=e.rels(n),c=w=>a.find(S=>S.type===w)?.target,i=(()=>{const w=c("theme");return w===void 0?void 0:e.text(w)})(),m=i===void 0?be:ge(i),f=c("styles"),u=f===void 0?void 0:e.xml(f),h=Re(u,m),v=ee(m,l(u?.styleSheet)),p=Ee(e,c("sharedStrings")),y=[..._e(e)];for(const w of h.lost)y.push(w);const $=l(r.workbookPr),T=l(r.calcPr);k(T,"iterate")===!0&&y.push("iterative calculation");const O=l(r.workbookProtection);(k(O,"lockStructure")===!0||k(O,"lockWindows")===!0)&&y.push("the workbook's protection"),r.fileSharing!==void 0&&y.push("its write protection");const R=[],I=new Map(a.map(w=>[w.id,w]));for(const w of b(l(r.sheets)?.sheet)){const S=I.get(d(w,"id")??""),A=L(d(w,"name")??"");if(S?.type!=="worksheet"){S?.type!=="chartsheet"&&S?.type!=="dialogsheet"&&y.push(`${A}: a sheet of a kind this cannot read`);continue}const j=d(w,"state"),N=Pe(e,S.target,A,j==="hidden"||j==="veryHidden"?j:"visible",p,v,h.dxfs);R.push(N.sheet),y.push(...N.lost)}return{sheets:R,names:b(l(r.definedNames)?.definedName).map(w=>{const S=x(w,"localSheetId");return{name:d(w,"name")??"",text:L(F(w)),...S===void 0?{}:{sheet:S}}}),looks:h.looks,dxfs:h.dxfs,date1904:k($,"date1904")===!0,font:h.font,lost:y}}
2
+ import{strFromU8 as ie,unzipSync as ae}from"fflate";import{withinZip as le,ZipLimitError as ce}from"@allyhub-next/formats";import{SHEET_ICONS as de,SHEET_OPERATORS as ue,SHEET_VALIDATIONS as fe}from"@allyhub-next/formats";import{cellName as J,readAddress as K,readArea as H,readAreas as Q}from"../address.js";import{SHEET_CHART_DEFAULTS as Y}from"../chart.js";import{moveFormula as me,relativeKey as he}from"../formula/move.js";import{printFormula as ee}from"../formula/print.js";import{ERR as pe,errorOf as be,serialOfDate as ge}from"../values.js";import{OFFICE_THEME as xe,colorOf as A,paletteOf as te,themeColors as ye}from"./colors.js";import{chartAnchors as we,readChart as ve}from"./charts.js";import{readFileFormula as B}from"./formula.js";import{BUILTIN_FORMATS as ke}from"./numfmt.js";import{attr as d,flag as v,numberAttr as y,readXml as $e,readXstring as L,tag as l,tags as b,textOf as C}from"./xml.js";const ne=7,Se=n=>Math.floor((256*n+Math.floor(128/ne))/256*ne),Te=n=>Math.round(n*4/3),W=5;export function placesLine(n){const e=n.slice(0,W).join(", ");return n.length>W?`${e} and ${String(n.length-W)} more`:e}const _=(n,e,t=`${e}s`)=>`${String(n)} ${n===1?e:t}`;class Ee{parts;names;constructor(e,t){this.parts=ae(e,{filter:le(t)}),this.names=Object.keys(this.parts)}has(e){return this.parts[e]!==void 0}text(e){const t=this.parts[e];return t?ie(t):void 0}xml(e){const t=this.text(e);return t===void 0?void 0:$e(t)}rels(e){const t=e.lastIndexOf("/"),o=`${e.slice(0,t+1)}_rels/${e.slice(t+1)}.rels`,r=this.xml(o);return b(l(r?.Relationships)?.Relationship).map(s=>{const i=d(s,"Type")??"",c=d(s,"Target")??"",a=d(s,"TargetMode")==="External";return{id:d(s,"Id")??"",type:i.slice(i.lastIndexOf("/")+1),target:a?c:Oe(e,c),external:a}})}count(e){return this.names.filter(t=>e.test(t)).length}}function Oe(n,e){if(e.startsWith("/"))return e.slice(1);const t=n.split("/").slice(0,-1);for(const o of e.split("/"))o===".."?t.pop():o!=="."&&t.push(o);return t.join("/")}function Ie(n,e){const t=e===void 0?void 0:n.xml(e);return b(l(t?.sst)?.si).map(o=>{const r=b(o.r);return r.length>0?{text:L(r.map(s=>C(s.t)).join("")),rich:!0}:{text:L(C(o.t)),rich:!1}})}function j(n,e){const t=n[e];if(t===void 0)return!1;const o=d(l(t),"val");return o===void 0||o!=="0"&&o!=="false"}const Ae=new Set(["double","singleAccounting","doubleAccounting"]);function Ce(n,e,t){const o={},r=(a,m)=>d(l(a?.[m]),"val");if(j(n,"b")&&(o.bold=!0),j(n,"i")&&(o.italic=!0),j(n,"strike")&&(o.strike=!0),j(n,"u")){const a=r(n,"u");o.underline=a!==void 0&&Ae.has(a)?a:!0}const s=r(n,"name");s!==void 0&&s!==r(e,"name")&&(o.font=s);const i=r(n,"sz");i!==void 0&&i!==r(e,"sz")&&(o.size=Number(i));const c=A(l(n.color),t);return c!==void 0&&c!==A(l(e?.color),t)&&(o.color=c),o}function Fe(n,e){const t=l(n.patternFill),o=d(t,"patternType");if(o===void 0||o==="none")return;const r=A(l(t?.fgColor),e),s=A(l(t?.bgColor),e);return o==="solid"&&r!==void 0?r:{pattern:o,...r===void 0?{}:{color:r},...s===void 0?{}:{background:s}}}function oe(n,e){const t={};for(const o of["left","right","top","bottom"]){const r=l(n[o]),s=d(r,"style");if(s===void 0||s==="none")continue;const i=A(l(r?.color),e);t[o]={style:s,...i===void 0?{}:{color:i}}}return Object.keys(t).length===0?void 0:t}function Le(n){const e={},t=d(n,"horizontal");t!==void 0&&t!=="general"&&(e.align=t);const o=d(n,"vertical");o!==void 0&&o!=="bottom"&&(e.valign=o),v(n,"wrapText")===!0&&(e.wrap=!0),v(n,"shrinkToFit")===!0&&(e.shrink=!0);const r=y(n,"indent");r!==void 0&&r>0&&(e.indent=r);const s=y(n,"textRotation");return s!==void 0&&s>0&&s<=180&&(e.rotation=s),e}function Re(n,e){const t={},o=l(n.font);if(o){const a=(f,u)=>{o[f]!==void 0&&(t[u]=j(o,f))};a("b","bold"),a("i","italic"),a("strike","strike"),o.u!==void 0&&(t.underline=j(o,"u"));const m=A(l(o.color),e);m!==void 0&&(t.color=m)}const r=l(l(n.fill)?.patternFill),s=A(l(r?.bgColor),e)??A(l(r?.fgColor),e);s!==void 0&&(t.fill=s);const i=l(n.border),c=i&&oe(i,e);return c!==void 0&&(t.border=c),t}function Ne(n,e){const t=l(n?.styleSheet),o=te(e,t),r=new Map(b(l(t?.numFmts)?.numFmt).map(h=>[y(h,"numFmtId")??-1,d(h,"formatCode")??"General"])),s=b(l(t?.fonts)?.font),i=b(l(t?.fills)?.fill),c=b(l(t?.borders)?.border),a=b(l(t?.cellXfs)?.xf),m=s[y(a[0],"fontId")??0],f=new Set;i.some(h=>h.gradientFill!==void 0)&&f.add("gradient fills");const u=a.map(h=>{const k={},$=s[y(h,"fontId")??0];$&&(Object.assign(k,Ce($,m,o)),$.vertAlign!==void 0&&f.add("superscript and subscript"));const T=i[y(h,"fillId")??0],I=T&&Fe(T,o);I!==void 0&&(k.fill=I);const F=c[y(h,"borderId")??0],O=F&&oe(F,o);O!==void 0&&(k.border=O),F&&d(l(F.diagonal),"style")!==void 0&&f.add("diagonal borders");const N=l(h.alignment);N&&(Object.assign(k,Le(N)),y(N,"textRotation")===255&&f.add("vertical text"));const w=y(h,"numFmtId")??0,S=r.get(w)??ke[w];return S!==void 0&&S!=="General"&&(k.format=S),k}),p=d(l(m?.name),"val"),x=d(l(m?.sz),"val");return{looks:u,dxfs:b(l(t?.dxfs)?.dxf).map(h=>Re(h,o)),font:{...p===void 0?{}:{name:p},...x===void 0?{}:{size:Number(x)}},lost:[...f]}}function re(n){const e=new Map;let t=0;for(const o of b(n.filterColumn)){const r=y(o,"colId")??0,s=l(o.filters);if(!s){Object.keys(o).some(c=>c!=="colId"&&c!=="hiddenButton")&&(t+=1);continue}if(s.dateGroupItem!==void 0){t+=1;continue}const i=b(s.filter).map(c=>L(d(c,"val")??""));e.set(r,{...i.length===0?{}:{values:i},...v(s,"blank")===!0?{blanks:!0}:{}})}return{columns:e,unread:t}}function je(n){const e=l(n?.table),t=H(d(e,"ref")??""),o=d(e,"displayName")??d(e,"name");if(!t||o===void 0)return;const r=l(e?.tableStyleInfo),s=l(e?.autoFilter);return{name:o,ref:t,headers:y(e,"headerRowCount")??1,totals:y(e,"totalsRowCount")??0,columns:b(l(e?.tableColumns)?.tableColumn).map(i=>({name:L(d(i,"name")??"").trim(),calculated:i.calculatedColumnFormula!==void 0})),style:d(r,"name")??"none",...s?{filter:re(s)}:{}}}function q(n){const e=n.trim();if(e==="")return;const t=/^"((?:[^"]|"")*)"$/u.exec(e);if(t)return(t[1]??"").replaceAll('""','"');const o=Number(e);if(!Number.isNaN(o))return o;const r=B(e,!0);return r.ok?ee(r.node):void 0}const se=n=>n!==void 0&&ue.includes(n);function U(n){const e=d(n,"type")??"num",t=d(n,"val"),o=t===void 0?void 0:q(t);return{at:e,...o===void 0?{}:{value:o}}}const Me=de;function De(n,e,t,o){const r=d(n,"type")??"",s={range:e,...v(n,"stopIfTrue")===!0?{stop:!0}:{}},i=y(n,"dxfId"),c=i===void 0?{}:t[i]??{},a={...c.bold===void 0?{}:{bold:c.bold},...c.italic===void 0?{}:{italic:c.italic},...c.underline===void 0?{}:{underline:c.underline!==!1},...c.strike===void 0?{}:{strike:c.strike},...c.color===void 0?{}:{color:c.color},...typeof c.fill=="string"?{fill:c.fill}:{},...c.border===void 0?{}:{border:c.border}},m=n.formula,f=(Array.isArray(m)?m:m===void 0?[]:[m]).map(C);switch(r){case"cellIs":{const u=d(n,"operator"),p=f.flatMap(x=>{const h=q(x);return h===void 0?[]:[h]});return!se(u)||p.length===0?`a cellIs rule of ${u??"no operator"}`:{...s,...a,type:"cellIs",operator:u,formula:p}}case"containsText":case"notContainsText":case"beginsWith":case"endsWith":{const u=d(n,"text");return u===void 0?`a ${r} rule with no text`:{...s,...a,type:"containsText",...r==="containsText"?{}:{operator:r==="notContainsText"?"notContains":r},text:L(u)}}case"duplicateValues":case"uniqueValues":return{...s,...a,type:r};case"top10":return{...s,...a,type:"top10",rank:y(n,"rank")??10,...v(n,"percent")===!0?{percent:!0}:{},...v(n,"bottom")===!0?{bottom:!0}:{}};case"aboveAverage":return{...s,...a,type:"aboveAverage",...v(n,"aboveAverage")===!1?{below:!0}:{},...v(n,"equalAverage")===!0?{equal:!0}:{}};case"expression":{const u=f[0]===void 0?void 0:B(f[0],!0);return u?.ok?{...s,...a,type:"expression",formula:ee(u.node)}:"an expression rule that cannot be read"}case"dataBar":{const u=l(n.dataBar),p=A(l(u?.color),o),[x,h]=b(u?.cfvo).map(U);return p===void 0?"a data bar with no colour":{...s,type:"dataBar",color:p,...x&&x.at!=="min"?{min:x}:{},...h&&h.at!=="max"?{max:h}:{},...v(u,"showValue")===!1?{show:!1}:{}}}case"colorScale":{const u=l(n.colorScale),p=b(u?.cfvo).map(U),x=b(u?.color).map(k=>A(k,o)),h=p.flatMap((k,$)=>{const T=x[$];return T===void 0?[]:[{...k,color:T}]});return h.length<2?"a colour scale with too few stops":{...s,type:"colorScale",stops:h.slice(0,3)}}case"iconSet":{const u=l(n.iconSet),p=d(u,"iconSet")??"3TrafficLights1";if(!Me.includes(p))return`the icon set ${p}`;const x=b(u?.cfvo).map(U);return{...s,type:"iconSet",icons:p,...x.length>=3?{stops:x.slice(0,5)}:{},...v(u,"reverse")===!0?{reverse:!0}:{},...v(u,"showValue")===!1?{show:!1}:{}}}default:return`a ${r} rule`}}function Ve(n,e,t){const o=[],r=[];for(const s of b(n.conditionalFormatting)){const i=d(s,"sqref")??"";if(!Q(i)){r.push(`a rule on ${i}`);continue}for(const c of b(s.cfRule)){const a=De(c,i,e,t);typeof a=="string"?r.push(`${a} on ${i}`):o.push({priority:y(c,"priority")??0,rule:a})}}return{rules:o.sort((s,i)=>s.priority-i.priority).map(s=>s.rule),unread:r}}const ze=fe;function He(n){const e=[],t=[];for(const o of b(l(n.dataValidations)?.dataValidation)){const r=d(o,"sqref")??"",s=d(o,"type")??"none";if(s==="none"&&d(o,"prompt")===void 0)continue;if(!ze.includes(s)||!Q(r)){t.push(`a ${s} rule on ${r}`);continue}const i=C(o.formula1),c=C(o.formula2),a=/^"((?:[^"]|"")*)"$/u.exec(i.trim()),m=s==="list"&&a?(a[1]??"").replaceAll('""','"').split(","):void 0,f=[i,c].flatMap(T=>{const I=q(T);return I===void 0?[]:[I]}),u=d(o,"operator"),p=T=>Object.fromEntries(Object.entries(T).filter(([,I])=>I!==void 0)),x=p({title:d(o,"promptTitle"),message:d(o,"prompt")}),h=p({style:d(o,"errorStyle"),title:d(o,"errorTitle"),message:d(o,"error")}),k=v(o,"showInputMessage")!==!0,$=v(o,"showErrorMessage")!==!0;e.push({range:r,type:s,...se(u)&&u!=="between"?{operator:u}:{},...m?{values:m}:{formula:f},...v(o,"allowBlank")===!0?{}:{blank:!1},...v(o,"showDropDown")===!0?{dropdown:!1}:{},...k||Object.keys(x).length>0?{prompt:{...x,...k?{show:!1}:{}}}:{},...$||Object.keys(h).length>0?{error:{...h,...$?{show:!1}:{}}}:{}})}return{rules:e,unread:t}}function X(n,e){const t=B(n,e);return t.ok?{node:t.node}:{unread:n}}class _e{cells=[];rich=[];masters=new Map;strings;constructor(e){this.strings=e}value(e,t){const o=d(e,"t")??"n",r=e.v;if(o==="inlineStr"){const i=l(e.is),c=b(i?.r);return c.length>0?{value:L(c.map(a=>C(a.t)).join("")),rich:!0}:{value:L(C(i?.t))}}if(r===void 0)return{value:void 0};const s=C(r);switch(o){case"s":{const i=this.strings[Number(s)];return i?{value:i.text,...i.rich?{rich:!0}:{}}:{value:""}}case"str":return{value:L(s)};case"b":return{value:s.trim()==="1"||s.trim()==="true"};case"e":return{value:be(s.trim())??pe.VALUE};case"d":{const i=new Date(s.trim());return{value:Number.isNaN(i.getTime())?s:ge(i)}}default:{if(s.trim()==="")return{value:void 0};const i=Number(s);if(Number.isNaN(i))throw new Error(`${t} says it holds a number and holds ${s}.`);return{value:i}}}}formula(e,t,o,r){const s=e.f;if(s===void 0)return;const i=l(s),c=d(i,"t")??"normal",a=C(s);if(c==="dataTable"){r.unread=`a data table's {=TABLE(${d(i,"r1")??""})}`;return}if(c==="array"){const m=e.cm!==void 0;Object.assign(r,X(a,!0));const f=H(d(i,"ref")??"");f&&(r.array=f),m&&(r.dynamic=!0);return}if(c==="shared"){const m=d(i,"si")??"";if(a!==""){const u=X(a,!1);this.masters.set(m,{node:u.node,unread:u.unread,row:t,col:o,key:u.node?he(u.node,t,o):"",dynamicArray:!1}),Object.assign(r,u),u.node&&(r.key=this.masters.get(m)?.key??"");return}const f=this.masters.get(m);if(!f){r.unread=`a shared formula of a group that has no first cell (${m})`;return}f.node?(r.node=me(f.node,t-f.row,o-f.col),r.key=f.key):f.unread!==void 0&&(r.unread=f.unread);return}a!==""&&Object.assign(r,X(a,!1))}readRows(e){let t=0;for(const o of e){const r=y(o,"r"),s=r===void 0?t:r-1;t=s+1;let i=0;for(const c of b(o.c)){const a=d(c,"r"),f=(a===void 0?void 0:K(a))?.col??i;i=f+1;const u=a??J({row:s,col:f}),{value:p,rich:x}=this.value(c,u),h={row:s,col:f,value:p,style:y(c,"s")??0};x===!0&&(h.rich=!0,this.rich.push(u)),this.formula(c,s,f,h),this.cells.push(h)}}}}function Pe(n,e,t){const o=[],r=a=>o.push(`${n}: ${a}`);t.length>0&&r(`${_(t.length,"cell")} of rich text, kept as plain text (${placesLine(t)})`);const s=b(l(e.hyperlinks)?.hyperlink);s.length>0&&r(`${_(s.length,"hyperlink")} (${placesLine(s.map(a=>d(a,"ref")??""))})`),e.sortState!==void 0&&r("a sort"),v(l(e.sheetProtection),"sheet")===!0&&r("protection"),e.protectedRanges!==void 0&&r("protected ranges"),e.headerFooter!==void 0&&C(e.headerFooter).trim()!==""&&r("its print header and footer"),l(e.headerFooter)?.oddHeader!==void 0&&r("its print header"),l(e.headerFooter)?.oddFooter!==void 0&&r("its print footer"),(e.rowBreaks!==void 0||e.colBreaks!==void 0)&&r("its page breaks"),e.oleObjects!==void 0&&r("embedded objects"),e.controls!==void 0&&r("form controls"),e.dataConsolidate!==void 0&&r("a consolidation"),e.customSheetViews!==void 0&&r("custom views"),b(l(e.sheetViews)?.sheetView).some(a=>d(l(a.pane),"state")==="split")&&r("a split, not frozen, window");const c=JSON.stringify(e.extLst??"");return c.includes("sparklineGroups")&&r("sparklines"),G(e.extLst)&&r("conditional formats of Excel 2010 and later"),c.includes("dataValidations")&&r("data validations of Excel 2010 and later"),c.includes("slicerList")&&r("slicers"),o}function G(n){if(typeof n!="object"||n===null)return!1;if(Array.isArray(n))return n.some(G);const e=n;return b(e.cfRule).some(t=>d(t,"type")!=="dataBar")&&e.cfRule!==void 0?!0:Object.values(e).some(G)}function Be(n){const e=[],t=(o,r,s)=>{const i=n.count(o);i>0&&e.push(_(i,r,s))};return n.has("xl/vbaProject.bin")&&e.push("VBA macros"),t(/^xl\/pivotTables\/pivotTable\d*\.xml$/u,"pivot table"),t(/^xl\/chartsheets\/[^/]+\.xml$/u,"chart sheet"),t(/^xl\/dialogsheets\/[^/]+\.xml$/u,"dialog sheet"),t(/^xl\/macrosheets\/[^/]+\.xml$/u,"macro sheet"),t(/^xl\/media\//u,"image"),t(/^xl\/embeddings\//u,"embedded object"),t(/^xl\/comments\d*\.xml$/u,"sheet's comments","sheets' comments"),t(/^xl\/threadedComments\//u,"sheet's threaded comments","sheets' threaded comments"),t(/^xl\/slicers\/[^/]+\.xml$/u,"slicer part"),t(/^xl\/timelines\/[^/]+\.xml$/u,"timeline part"),t(/^xl\/ctrlProps\/[^/]+\.xml$/u,"form control"),t(/^xl\/activeX\/[^/]+\.xml$/u,"ActiveX control"),t(/^xl\/queryTables\/[^/]+\.xml$/u,"query table"),n.has("xl/connections.xml")&&e.push("data connections"),n.names.some(o=>o.startsWith("xl/richData/"))&&e.push("rich values (data types, pictures in cells)"),n.names.some(o=>/^customXml\/item\d+\.xml$/u.test(o)&&(n.text(o)??"").includes("DataMashup"))&&e.push("Power Query queries"),e}function We(n,e,t,o,r,s,i){const c=n.xml(e),a=l(c?.worksheet);if(!a)throw new Error(`${e} is not a worksheet.`);const m=new _e(r);m.readRows(b(l(a.sheetData)?.row));const f=b(l(a.cols)?.col).map(g=>{const E=y(g,"width"),D=y(g,"style");return{min:(y(g,"min")??1)-1,max:(y(g,"max")??1)-1,...E===void 0||v(g,"customWidth")===!1?{}:{width:Se(E)},...v(g,"hidden")===!0?{hidden:!0}:{},...D===void 0||D===0?{}:{style:D}}}),u=[];let p=b(l(a.cols)?.col).some(g=>(y(g,"outlineLevel")??0)>0);b(l(a.sheetData)?.row).forEach((g,E)=>{const D=(y(g,"r")??E+1)-1;(y(g,"outlineLevel")??0)>0&&(p=!0);const Z=y(g,"ht"),P=y(g,"s"),V={row:D};Z!==void 0&&v(g,"customHeight")===!0&&(V.height=Te(Z)),v(g,"hidden")===!0&&(V.hidden=!0),P!==void 0&&P!==0&&v(g,"customFormat")===!0&&(V.style=P),Object.keys(V).length>1&&u.push(V)});const x=b(l(a.mergeCells)?.mergeCell).flatMap(g=>{const E=H(d(g,"ref")??"");return E?[E]:[]}),h=b(l(a.sheetViews)?.sheetView)[0],k=l(h?.pane);let $;const T=d(k,"state");if(T==="frozen"||T==="frozenSplit"){const g=K(d(h,"topLeftCell")??"A1")??{row:0,col:0};$={row:g.row+(y(k,"ySplit")??0),col:g.col+(y(k,"xSplit")??0)}}const I=n.rels(e).filter(g=>g.type==="table").flatMap(g=>{const E=je(n.xml(g.target));return E?[E]:[]}),F=A(l(l(a.sheetPr)?.tabColor),s),O=Pe(t,a,m.rich);p&&O.push(`${t}: its grouped rows or columns, left ungrouped`);const N=Ve(a,i,s),w=He(a);for(const g of N.unread)O.push(`${t}: a conditional format, ${g}`);for(const g of w.unread)O.push(`${t}: a data validation, ${g}`);const S=l(a.autoFilter),M=H(d(S,"ref")??""),R=S&&M?{ref:M,...re(S)}:void 0;R&&R.unread>0&&O.push(`${t}: ${_(R.unread,"filter")} by condition on ${d(S,"ref")??""}, its rows left as they were hidden`);const z=Xe(n,e,t,f,u,O);return{sheet:{name:t,state:o,cells:m.cells,merges:x,...$?{freeze:$}:{},...d(h,"showGridLines")==="0"?{gridlines:!1}:{},...F===void 0?{}:{tab:F},columns:f,rows:u,tables:I,conditional:N.rules,validations:w.rules,scenarios:b(l(a.scenarios)?.scenario).map(g=>({name:d(g,"name")??"",cells:b(g.inputCells).map(E=>({at:d(E,"r")??"",value:d(E,"val")??""}))})),...R?{filter:R}:{},charts:z},lost:O}}const qe=64,Ue=20;function Xe(n,e,t,o,r,s){const i=m=>o.find(f=>m>=f.min&&m<=f.max)?.width??qe,c=m=>r.find(f=>f.row===m)?.height??Ue,a=[];for(const m of n.rels(e).filter(f=>f.type==="drawing")){const{anchors:f}=we(n.xml(m.target),i,c),u=n.rels(m.target);for(const p of f){const x=u.find($=>$.id===p.id),h=ve(x?n.xml(x.target):void 0),k=J(p.at);if(typeof h=="string"){s.push(`${t}: the chart at ${k}, as ${h}`);continue}a.push({...h,at:k,...p.x===void 0?{}:{x:p.x},...p.y===void 0?{}:{y:p.y},...p.width===Y.width?{}:{width:p.width},...p.height===Y.height?{}:{height:p.height}})}}return a}export function readXlsx(n,e){let t;try{t=new Ee(n,e)}catch(w){throw w instanceof ce?w:new Error("It is not a zip file, as an .xlsx file is.")}const r=t.rels("").find(w=>w.type==="officeDocument")?.target??"xl/workbook.xml";if(r.endsWith(".bin"))throw new Error("It is a binary workbook (.xlsb): save it as .xlsx.");const s=t.xml(r),i=l(s?.workbook);if(!i)throw new Error("It has no workbook part.");const c=t.rels(r),a=w=>c.find(S=>S.type===w)?.target,m=(()=>{const w=a("theme");return w===void 0?void 0:t.text(w)})(),f=m===void 0?xe:ye(m),u=a("styles"),p=u===void 0?void 0:t.xml(u),x=Ne(p,f),h=te(f,l(p?.styleSheet)),k=Ie(t,a("sharedStrings")),$=[...Be(t)];for(const w of x.lost)$.push(w);const T=l(i.workbookPr),I=l(i.calcPr);v(I,"iterate")===!0&&$.push("iterative calculation");const F=l(i.workbookProtection);(v(F,"lockStructure")===!0||v(F,"lockWindows")===!0)&&$.push("the workbook's protection"),i.fileSharing!==void 0&&$.push("its write protection");const O=[],N=new Map(c.map(w=>[w.id,w]));for(const w of b(l(i.sheets)?.sheet)){const S=N.get(d(w,"id")??""),M=L(d(w,"name")??"");if(S?.type!=="worksheet"){S?.type!=="chartsheet"&&S?.type!=="dialogsheet"&&$.push(`${M}: a sheet of a kind this cannot read`);continue}const R=d(w,"state"),z=We(t,S.target,M,R==="hidden"||R==="veryHidden"?R:"visible",k,h,x.dxfs);O.push(z.sheet),$.push(...z.lost)}return{sheets:O,names:b(l(i.definedNames)?.definedName).map(w=>{const S=y(w,"localSheetId");return{name:d(w,"name")??"",text:L(C(w)),...S===void 0?{}:{sheet:S}}}),looks:x.looks,dxfs:x.dxfs,date1904:v(T,"date1904")===!0,font:x.font,lost:$}}
@@ -1,2 +1,2 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{zipSync as se}from"fflate";import{cellName as R,columnIndex as ne,columnLetter as Y,rangeName as E}from"../address.js";import{parseFormula as oe}from"../formula/parse.js";import{sheetPrefix as re}from"../formula/print.js";import{fileCells as ie,isPicture as ae,pictureHeight as le,pictureSize as ce}from"../files.js";import{scenariosByCell as de}from"../scenario.js";import{CellError as P,readTyped as he}from"../values.js";import{FormulaCell as me}from"../workbook.js";import{chartPart as fe,drawingPart as ue}from"./charts.js";import{fileFormula as O,needsArray as V}from"./formula.js";import{Styles as pe}from"./styles.js";import{THEME_XML as ge}from"./theme.js";import{HEAD as g,NS as y,el as o,xstring as x}from"./xml.js";const $={sheet:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",worksheet:"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",styles:"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",strings:"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",theme:"application/vnd.openxmlformats-officedocument.theme+xml",table:"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",metadata:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",drawing:"application/vnd.openxmlformats-officedocument.drawing+xml",chart:"application/vnd.openxmlformats-officedocument.drawingml.chart+xml",core:"application/vnd.openxmlformats-package.core-properties+xml",app:"application/vnd.openxmlformats-officedocument.extended-properties+xml"},w=`${y.rel}/`,G=new Date(1980,0,1),xe=191029;export const DEFAULT_TABLE_STYLE="TableStyleMedium2";const $e=64,we=7,be=l=>Math.min(255,Math.floor(l/we*256)/256),ye=l=>Math.min(409.5,l*3/4),z=32767,B=255,Se=2e5,ke=o("metadata",{xmlns:y.main,"xmlns:xda":"http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray"},o("metadataTypes",{count:1},o("metadataType",{name:"XLDAPR",minSupportedVersion:12e4,copy:1,pasteAll:1,pasteValues:1,merge:1,splitFirst:1,rowColShift:1,clearFormats:1,clearComments:1,assign:1,coerce:1,cellMeta:1})),o("futureMetadata",{name:"XLDAPR",count:1},o("bk",{},o("extLst",{},o("ext",{uri:"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}"},o("xda:dynamicArrayProperties",{fDynamic:1,fCollapsed:0}))))),o("cellMetadata",{count:1},o("bk",{},o("rc",{t:1,v:0}))));class ve{index=new Map;count=0;of(t){this.count+=1;let e=this.index.get(t);return e===void 0&&(e=this.index.size,this.index.set(t,e)),e}xml(){const t=[...this.index.keys()].map(e=>`<si><t${/^\s|\s$|\n/u.test(e)?' xml:space="preserve"':""}>${x(e)}</t></si>`);return o("sst",{xmlns:y.main,count:this.count,uniqueCount:this.index.size},...t)}}const H=l=>x(l),Te="Base case";function Ce(l){const t=new Map;for(const n of l.scenarios)for(const r of n.cells)t.set(R(r),r);const e=(n,r)=>o("inputCells",{r:R(n),val:r===null||r instanceof P?"":typeof r=="boolean"?r?"1":"0":String(r)}),s=(n,r)=>o("scenario",{name:n,locked:!0,count:r.length,user:"AllyHub"},...r);return o("scenarios",{current:0,show:0,sqref:[...t.keys()].join(" ")},s(Te,[...t.values()].map(n=>e(n,n.base))),...l.scenarios.map(n=>s(n.name,n.cells.map(r=>e(r,r.value)))))}function Ae(l,t,e,s){const n=[];let r=0;for(const{row:d,col:h,paths:a,column:i}of ie(l,t)){let c=0;const u=le(i);for(const S of a){const b=ae(S)?e?.(S):void 0,k=b&&ce(b);if(!b||!k){r+=1;continue}const M=Math.round(k.width/k.height*u);n.push({row:d,col:h,x:c,width:M,height:u,name:S.split("/").pop()??S,file:`.${k.type==="jpeg"?"jpg":k.type}`,bytes:b}),c+=M+4}}return r>0&&s.push(`${l.name}: ${String(r)} file${r===1?"":"s"} in a cell, which stay${r===1?"s":""} a name`),n}class Ee{arrays=!1;places=new Map;sheet;calc;styles;strings;wb;cached;left;isTable;isRangeName;hiddenRows;tall;scenarios;drawn;constructor(t,e,s,n,r,d,h=[],a){this.sheet=t,this.calc=e,this.wb=e.wb,this.styles=s,this.strings=n,this.cached=r,this.left=d,this.isTable=c=>this.wb.table(c)!==void 0,this.isRangeName=c=>{const u=this.wb.name(c)?.formula?.node;return this.isTable(c)||u!==void 0&&V({kind:"unary",op:"-",arg:u})},this.hiddenRows=e.filtered(t),this.scenarios=a,this.drawn=t.charts.length>0||h.length>0;const i=new Map;for(const c of h)i.set(c.row,Math.max(i.get(c.row)??0,c.height));this.tall=i}add(t,e){let s=this.places.get(t);s||(s=new Set,this.places.set(t,s)),s.add(e)}gather(){const{sheet:t}=this;for(let e=0;e<t.columnsUsed;e++){const[s,n]=t.span(e,0,Number.MAX_SAFE_INTEGER);for(let r=s;r<=n;r++)(t.at(r,e)!==void 0||t.spillAt(r,e))&&this.add(r,e)}for(const{area:e}of t.styledAreas()){const s=(e.bottom-e.top+1)*(e.right-e.left+1);if(s>Se){this.left.push(`${t.name}!${E(e)}: its look on the cells that hold something, ${String(s)} cells being too many to write empty`);continue}for(let n=e.top;n<=e.bottom;n++)for(let r=e.left;r<=e.right;r++)this.add(n,r)}for(const e of t.keys.keys())this.add(Math.floor(e/16384),e%16384)}styleOf(t,e){const s=this.sheet.lookAt(t,e);return Object.keys(s).length===0?void 0:this.styles.xf(s)}held(t,e){return e.length<=z?e:(this.left.push(`${this.sheet.name}!${t} past Excel's ${String(z)} characters, of its ${String(e.length)}`),e.slice(0,z))}value(t,e,s){return s===null?o("c",{r:t,s:e}):typeof s=="number"?`<c r="${t}"${p(e)}><v>${String(s)}</v></c>`:typeof s=="boolean"?`<c r="${t}"${p(e)} t="b"><v>${s?"1":"0"}</v></c>`:s instanceof P?Z(s)?`<c r="${t}"${p(e)} t="e"><v>${s.code}</v></c>`:`<c r="${t}"${p(e)} t="s"><v>${String(this.strings.of(s.code))}</v></c>`:`<c r="${t}"${p(e)} t="s"><v>${String(this.strings.of(this.held(t,s)))}</v></c>`}table(t){return this.sheet.tableAt(t.row,t.col)?.name}formula(t,e,s){const n=this.calc.value(s.sheet,s.row,s.col),{node:r}=s.shared;if(!r)return`<c r="${t}"${p(e)} t="e"><v>#NAME?</v></c>`;const d=s.moved,h=s.array!==void 0||s.blocked!==void 0||V(d,this.isRangeName),a=O(d,{table:this.table(s),isTable:this.isTable,array:h});let i=`<f>${H(a)}</f>`,c="";if(h){this.arrays=!0;const u=s.spill??{top:s.row,left:s.col,bottom:s.row,right:s.col};i=`<f t="array" ref="${E(u)}">${H(a)}</f>`,c=' cm="1"'}return this.cached?n===null||typeof n=="number"?`<c r="${t}"${p(e)}${c}>${i}<v>${String(n??0)}</v></c>`:typeof n=="boolean"?`<c r="${t}"${p(e)} t="b"${c}>${i}<v>${n?"1":"0"}</v></c>`:n instanceof P?Z(n)?`<c r="${t}"${p(e)} t="e"${c}>${i}<v>${n.code}</v></c>`:`<c r="${t}"${p(e)}${c}>${i}<v>0</v></c>`:`<c r="${t}"${p(e)} t="str"${c}>${i}<v>${x(this.held(t,n))}</v></c>`:`<c r="${t}"${p(e)}${c}>${i}</c>`}cell(t,e){const s=R({row:t,col:e}),n=this.styleOf(t,e),r=this.sheet.at(t,e);return r instanceof me?this.formula(s,n,r):r===void 0&&this.sheet.spillAt(t,e)&&this.cached?this.value(s,n,this.calc.value(this.sheet,t,e)):this.value(s,n,r??null)}columns(){const{sheet:t}=this,{spec:e}=t,s=new Map,n=new Map;for(const a of t.tables)for(const i of a.columns)i.spec?.width!==void 0&&n.set(a.at.col+i.index,i.spec.width);const r=new Set(n.keys()),d=new Map;for(const[a,i]of Object.entries(e.columns??{})){const c=ne(a);c!==void 0&&(d.set(c,i),r.add(c))}for(const a of r){const i=d.get(a),c=i?.width??n.get(a),u=J(i);s.set(a,o("col",{min:a+1,max:a+1,width:be(c??$e),style:u===void 0?void 0:this.styles.xf(u),hidden:i?.hidden===!0?!0:void 0,customWidth:c===void 0?void 0:!0}))}const h=[...s.keys()].sort((a,i)=>a-i).map(a=>s.get(a)??"");return h.length===0?"":o("cols",{},...h)}rowAttrs(t){const e=this.sheet.spec.rows?.[String(t+1)],s=J(e),n=e?.height??this.tall.get(t);return{r:t+1,s:s===void 0?void 0:this.styles.xf(s),customFormat:s===void 0?void 0:!0,ht:n===void 0?void 0:ye(n),customHeight:n===void 0?void 0:!0,hidden:e?.hidden===!0||this.hiddenRows.has(t)?!0:void 0}}rows(){const{sheet:t}=this,e=new Set(this.places.keys());for(const n of Object.keys(t.spec.rows??{}))e.add(Number(n)-1);for(const n of this.hiddenRows)e.add(n);const s=[];for(const n of[...e].sort((r,d)=>r-d)){const r=[...this.places.get(n)??[]].sort((a,i)=>a-i),d=o("row",this.rowAttrs(n)).slice(4,-2);if(r.length===0){s.push(`<row${d}/>`);continue}let h=`<row${d}>`;for(const a of r)h+=this.cell(n,a);s.push(`${h}</row>`)}return s.join("")}view(t){const{freeze:e}=this.sheet;let s="";if(e&&(e.row>0||e.col>0)){const n=e.row>0&&e.col>0?"bottomRight":e.row>0?"bottomLeft":"topRight";s=o("pane",{xSplit:e.col>0?e.col:void 0,ySplit:e.row>0?e.row:void 0,topLeftCell:R(e),activePane:n,state:"frozen"})}return o("sheetViews",{},o("sheetView",{showGridLines:this.sheet.spec.gridlines===!1?!1:void 0,tabSelected:t?!0:void 0,workbookViewId:0},s))}write(t,e){const{sheet:s}=this;this.gather();const n=_e(this.places),r=this.rows(),d=s.merges.map(i=>o("mergeCell",{ref:E(i)})),h=s.tables.map((i,c)=>o("tablePart",{"r:id":`rId${String(c+1)}`}));return{xml:g+o("worksheet",{xmlns:y.main,"xmlns:r":y.rel},s.spec.tab===void 0?"":o("sheetPr",{},o("tabColor",{rgb:`FF${s.spec.tab.slice(1).toUpperCase()}`})),o("dimension",{ref:n?E(n):"A1"}),this.view(t),o("sheetFormatPr",{defaultRowHeight:15}),this.columns(),r===""?o("sheetData"):`<sheetData>${r}</sheetData>`,this.scenarios?Ce(this.scenarios):"",this.sheetFilter(),d.length>0?o("mergeCells",{count:d.length},...d):"",...s.conditions.map((i,c)=>this.condition(i,c+1)),this.validations(),o("pageMargins",{left:.7,right:.7,top:.75,bottom:.75,header:.3,footer:.3}),this.drawn?o("drawing",{"r:id":`rId${String(h.length+1)}`}):"",h.length>0?o("tableParts",{count:h.length},...h):""),tables:s.tables.map((i,c)=>this.tableXml(i,e+c))}}bound(t){if(t===void 0)return"";if(typeof t=="number")return String(t);if(!t.startsWith("=")){const s=he(t);return typeof s.value=="number"&&s.formula===void 0?String(s.value):`"${t.replaceAll('"','""')}"`}const e=oe(t);return e.ok?O(e.node,{isTable:this.isTable,array:!0}):t.slice(1)}cfvo(t){return o("cfvo",{type:t.at,val:t.value===void 0?void 0:typeof t.value=="number"?t.value:this.bound(t.value)})}condition(t,e){const{spec:s}=t,n=s.range,r=(i,...c)=>o("conditionalFormatting",{sqref:n},o("cfRule",{...i,priority:e,stopIfTrue:s.stop===!0?!0:void 0},...c)),d=()=>{const i=Me(s);return Object.keys(i).length===0?void 0:this.styles.dxf(i)},h=t.areas[0],a=h?R({row:h.top,col:h.left}):"A1";switch(s.type){case"cellIs":return r({type:"cellIs",dxfId:d(),operator:s.operator},...s.formula.map(i=>o("formula",{},x(this.bound(i)))));case"containsText":{const i=s.operator??"contains",c=`"${s.text.replaceAll('"','""')}"`,u=i==="contains"?`NOT(ISERROR(SEARCH(${c},${a})))`:i==="notContains"?`ISERROR(SEARCH(${c},${a}))`:i==="beginsWith"?`LEFT(${a},LEN(${c}))=${c}`:`RIGHT(${a},LEN(${c}))=${c}`;return r({type:i==="contains"?"containsText":i==="notContains"?"notContainsText":i,dxfId:d(),operator:i==="contains"?"containsText":i,text:s.text},o("formula",{},x(u)))}case"duplicateValues":case"uniqueValues":return r({type:s.type,dxfId:d()});case"top10":return r({type:"top10",dxfId:d(),percent:s.percent===!0?!0:void 0,bottom:s.bottom===!0?!0:void 0,rank:s.rank});case"aboveAverage":return r({type:"aboveAverage",dxfId:d(),aboveAverage:s.below===!0?!1:void 0,equalAverage:s.equal===!0?!0:void 0});case"expression":return r({type:"expression",dxfId:d()},o("formula",{},x(this.bound(s.formula.startsWith("=")?s.formula:`=${s.formula}`))));case"dataBar":return r({type:"dataBar"},o("dataBar",{showValue:s.show===!1?!1:void 0},this.cfvo(s.min??{at:"min"}),this.cfvo(s.max??{at:"max"}),o("color",{rgb:K(s.color)})));case"colorScale":return r({type:"colorScale"},o("colorScale",{},...s.stops.map(i=>this.cfvo(i)),...s.stops.map(i=>o("color",{rgb:K(i.color)}))));case"iconSet":{const i=Number.parseInt(s.icons,10),c=s.stops??Array.from({length:i},(u,S)=>({at:"percent",value:Math.round(S*100/i)}));return r({type:"iconSet"},o("iconSet",{iconSet:s.icons,showValue:s.show===!1?!1:void 0,reverse:s.reverse===!0?!0:void 0},...c.map(u=>this.cfvo(u))))}}}validation(t){const{spec:e}=t;let s="";if(e.values){const h=e.values.join(",");(h.length>B||e.values.some(a=>a.includes(",")))&&this.left.push(`${this.sheet.name}!${e.range}: a list a file's cell cannot spell out, its values longer than ${String(B)} characters or holding a comma`),s=`"${h.slice(0,B)}"`}else s=this.bound(e.formula?.[0]);const n=this.bound(e.formula?.[1]),{error:r,prompt:d}=e;return e.multiple===!0&&this.left.push(`${this.sheet.name}!${e.range}: several choices in a cell: its text stays, and Excel's list offers one at a time`),o("dataValidation",{type:e.type,errorStyle:r?.style===void 0||r.style==="stop"?void 0:r.style,operator:e.operator===void 0||e.operator==="between"?void 0:e.operator,allowBlank:e.blank===!1?void 0:!0,showDropDown:e.dropdown===!1?!0:void 0,showInputMessage:d?.show===!1?void 0:!0,showErrorMessage:r?.show===!1||e.multiple===!0?void 0:!0,errorTitle:r?.title,error:r?.message,promptTitle:d?.title,prompt:d?.message,sqref:e.range},s===""?"":o("formula1",{},x(s)),n===""?"":o("formula2",{},x(n)))}validations(){const t=this.sheet.validations;return t.length===0?"":o("dataValidations",{count:t.length},...t.map(e=>this.validation(e)))}filterColumns(t){return[...t.columns.entries()].sort(([e],[s])=>e-s).map(([e,s])=>Ie(e-t.area.left,s))}sheetFilter(){const t=this.sheet.filters.find(e=>!e.table);return t?o("autoFilter",{ref:E(t.area)},...this.filterColumns(t)):""}columnFormula(t,e){if(!e?.node)return"";const s=V(e.node,this.isRangeName),n=O(e.node,{table:t.name,isTable:this.isTable,array:s});return o("calculatedColumnFormula",{array:s?!0:void 0},H(n))}tableXml(t,e){const s=t.area,n=E({...s,bottom:Math.max(s.bottom,s.top+1)}),r=t.spec.style??DEFAULT_TABLE_STYLE,d=this.sheet.filters.find(h=>h.table===t);return g+o("table",{xmlns:y.main,id:e,name:t.name,displayName:t.name,ref:n,totalsRowShown:0},d?o("autoFilter",{ref:n},...this.filterColumns(d)):"",o("tableColumns",{count:t.columns.length},...t.columns.map((h,a)=>o("tableColumn",{id:a+1,name:h.name},this.columnFormula(t,h.formula)))),r==="none"?o("tableStyleInfo",{showFirstColumn:0,showLastColumn:0,showRowStripes:1,showColumnStripes:0}):o("tableStyleInfo",{name:r,showFirstColumn:0,showLastColumn:0,showRowStripes:1,showColumnStripes:0}))}}const K=l=>`FF${l.slice(1).toUpperCase()}`;function Me(l){if(l.type==="dataBar"||l.type==="colorScale"||l.type==="iconSet")return{};const t={};for(const e of["bold","italic","underline","strike","color","fill","border"])l[e]!==void 0&&(t[e]=l[e]);return t}function Ie(l,t){return o("filterColumn",{colId:l},o("filters",{blank:t.blanks===!0?!0:void 0},...(t.values??[]).map(e=>o("filter",{val:e}))))}const p=l=>l===void 0?"":` s="${String(l)}"`,Z=l=>l.code!=="#CYCLE!";function _e(l){let t;for(const[e,s]of l)for(const n of s)t?(t.top=Math.min(t.top,e),t.bottom=Math.max(t.bottom,e),t.left=Math.min(t.left,n),t.right=Math.max(t.right,n)):t={top:e,bottom:e,left:n,right:n};return t}const Re=new Set(["width","height","hidden"]);function J(l){if(!l)return;const t=Object.fromEntries(Object.entries(l).filter(([e])=>!Re.has(e)));return Object.keys(t).length===0?void 0:t}const D=l=>g+o("Relationships",{xmlns:y.pkg},...l.map(([t,e],s)=>o("Relationship",{Id:`rId${String(s+1)}`,Type:t,Target:e})));function Le(l,t){const e=l.name(t);if(!e)return;const s=e.formula?.node;if(s)return O(s,{isTable:r=>l.table(r)!==void 0,array:!0});const{value:n}=e;return n==null?'""':typeof n=="string"?`"${n.replaceAll('"','""')}"`:typeof n=="boolean"?n?"TRUE":"FALSE":n instanceof P?n.code:String(n)}const Fe=(l,t)=>l.length===t.length&&l.every((e,s)=>e===t[s]),Pe=l=>`$${Y(l.left)}$${String(l.top+1)}:$${Y(l.right)}$${String(l.bottom+1)}`;export function writeXlsx(l,t={}){const e=l.wb,s=[];e.checks.length>0&&s.push(`${String(e.checks.length)} check${e.checks.length===1?"":"s"}: a file has no such thing`);const n=de(l);s.push(...n.left);const r=new pe,d=new ve,h=new TextEncoder,a={},i=[["/xl/workbook.xml",$.sheet]],c=Math.max(0,e.sheets.findIndex(m=>m.spec.hidden!==!0));let u=1,S=!1;const b=new Map;let k=0,M=0;for(const[m,f]of e.sheets.entries()){const v=String(m+1),T=Ae(f,l,t.file,s),q=new Ee(f,l,r,d,t.cached!==!1,s,T,n.sheets.find(C=>C.sheet===f)),U=q.write(m===c,u);S||=q.arrays,a[`xl/worksheets/sheet${v}.xml`]=U.xml,i.push([`/xl/worksheets/sheet${v}.xml`,$.worksheet]);const L=[];for(const C of U.tables){const A=`table${String(u)}.xml`;u+=1,a[`xl/tables/${A}`]=C,i.push([`/xl/tables/${A}`,$.table]),L.push([`${w}table`,`../tables/${A}`])}if(f.charts.length>0||T.length>0){k+=1;const C=`drawing${String(k)}.xml`;a[`xl/drawings/${C}`]=ue(f.charts,T),i.push([`/xl/drawings/${C}`,$.drawing]),L.push([`${w}drawing`,`../drawings/${C}`]);const A=f.charts.map(_=>{M+=1;const F=`chart${String(M)}.xml`;return a[`xl/charts/${F}`]=fe(l,f,_),i.push([`/xl/charts/${F}`,$.chart]),[`${w}chart`,`../charts/${F}`]});for(const _ of T){const W=[...b].find(([,te])=>Fe(te,_.bytes))?.[0]??`image${String(b.size+1)}${_.file}`;b.set(W,_.bytes),A.push([`${w}image`,`../media/${W}`])}a[`xl/drawings/_rels/${C}.rels`]=D(A)}L.length>0&&(a[`xl/worksheets/_rels/sheet${v}.xml.rels`]=D(L))}const Q=e.sheets.length,I=e.sheets.map((m,f)=>[`${w}worksheet`,`worksheets/sheet${String(f+1)}.xml`]);I.push([`${w}theme`,"theme/theme1.xml"]),I.push([`${w}styles`,"styles.xml"]),I.push([`${w}sharedStrings`,"sharedStrings.xml"]),S&&(I.push([`${w}sheetMetadata`,"metadata.xml"]),a["xl/metadata.xml"]=g+ke,i.push(["/xl/metadata.xml",$.metadata]));const N=[...e.names.values()].flatMap(m=>{const f=Le(e,m.name);return f===void 0?[]:[o("definedName",{name:m.name},x(f))]});e.sheets.forEach((m,f)=>{const v=m.filters.find(T=>!T.table);v&&N.push(o("definedName",{name:"_xlnm._FilterDatabase",localSheetId:f,hidden:!0},x(`${re(m.name)}${Pe(v.area)}`)))}),a["xl/workbook.xml"]=g+o("workbook",{xmlns:y.main,"xmlns:r":y.rel},o("workbookPr",{}),o("bookViews",{},o("workbookView",{activeTab:c===0?void 0:c})),o("sheets",{},...e.sheets.map((m,f)=>o("sheet",{name:m.name,sheetId:f+1,state:m.spec.hidden===!0?"hidden":void 0,"r:id":`rId${String(f+1)}`}))),N.length>0?o("definedNames",{},...N):"",o("calcPr",{calcId:xe,fullCalcOnLoad:!0})),a["xl/_rels/workbook.xml.rels"]=D(I),a["xl/styles.xml"]=g+r.xml(),a["xl/sharedStrings.xml"]=g+d.xml(),a["xl/theme/theme1.xml"]=g+ge,a["docProps/core.xml"]=g+o("cp:coreProperties",{"xmlns:cp":"http://schemas.openxmlformats.org/package/2006/metadata/core-properties","xmlns:dc":"http://purl.org/dc/elements/1.1/"},e.title===void 0?"":o("dc:title",{},x(e.title))),a["docProps/app.xml"]=g+o("Properties",{xmlns:"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"},o("Application",{},"AllyHub")),a["_rels/.rels"]=D([[`${w}officeDocument`,"xl/workbook.xml"],["http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties","docProps/core.xml"],[`${w}extended-properties`,"docProps/app.xml"]]),i.push(["/xl/styles.xml",$.styles],["/xl/sharedStrings.xml",$.strings],["/xl/theme/theme1.xml",$.theme],["/docProps/core.xml",$.core],["/docProps/app.xml",$.app]),a["[Content_Types].xml"]=g+o("Types",{xmlns:y.types},o("Default",{Extension:"rels",ContentType:"application/vnd.openxmlformats-package.relationships+xml"}),o("Default",{Extension:"xml",ContentType:"application/xml"}),...[...new Set([...b.keys()].map(m=>m.split(".").pop()??""))].sort().map(m=>o("Default",{Extension:m,ContentType:`image/${m==="jpg"?"jpeg":m}`})),...i.map(([m,f])=>o("Override",{PartName:m,ContentType:f})));const X=["[Content_Types].xml","_rels/.rels","docProps/app.xml","docProps/core.xml","xl/workbook.xml","xl/_rels/workbook.xml.rels",...Array.from({length:Q},(m,f)=>`xl/worksheets/sheet${String(f+1)}.xml`)],ee=[...X,...Object.keys(a).filter(m=>!X.includes(m)).sort()],j={};for(const m of ee)j[m]=[h.encode(a[m]??""),{mtime:G}];for(const[m,f]of[...b].sort(([v],[T])=>v.localeCompare(T)))j[`xl/media/${m}`]=[f,{mtime:G}];return{bytes:se(j),left:s}}
2
+ import{zipSync as me}from"fflate";import{SHEET_PAPERS as fe}from"@allyhub-next/formats";import{cellName as j,columnIndex as ue,columnLetter as K,rangeName as L,readAddress as J,readArea as pe}from"../address.js";import{parseFormula as xe}from"../formula/parse.js";import{sheetPrefix as Q}from"../formula/print.js";import{fileCells as ge,isPicture as $e,pictureHeight as we,pictureSize as ee}from"../files.js";import{scenariosByCell as ye}from"../scenario.js";import{CellError as z,readTyped as be}from"../values.js";import{FormulaCell as ve}from"../workbook.js";import{chartPart as Se,drawingPart as ke}from"./charts.js";import{fileFormula as H,needsArray as X}from"./formula.js";import{Styles as Te}from"./styles.js";import{THEME_XML as Ce}from"./theme.js";import{HEAD as v,NS as A,el as s,xstring as x}from"./xml.js";const S={comments:"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",sheet:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",worksheet:"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",styles:"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",strings:"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",theme:"application/vnd.openxmlformats-officedocument.theme+xml",table:"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",metadata:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",drawing:"application/vnd.openxmlformats-officedocument.drawing+xml",chart:"application/vnd.openxmlformats-officedocument.drawingml.chart+xml",core:"application/vnd.openxmlformats-package.core-properties+xml",app:"application/vnd.openxmlformats-officedocument.extended-properties+xml"},$=`${A.rel}/`,te=new Date(1980,0,1),Ae=191029;export const DEFAULT_TABLE_STYLE="TableStyleMedium2";const Ee=64,Me=7,_e=l=>Math.min(255,Math.floor(l/Me*256)/256),Re=l=>Math.min(409.5,l*3/4),B=32767,q=255,Le=2e5,Ie=s("metadata",{xmlns:A.main,"xmlns:xda":"http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray"},s("metadataTypes",{count:1},s("metadataType",{name:"XLDAPR",minSupportedVersion:12e4,copy:1,pasteAll:1,pasteValues:1,merge:1,splitFirst:1,rowColShift:1,clearFormats:1,clearComments:1,assign:1,coerce:1,cellMeta:1})),s("futureMetadata",{name:"XLDAPR",count:1},s("bk",{},s("extLst",{},s("ext",{uri:"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}"},s("xda:dynamicArrayProperties",{fDynamic:1,fCollapsed:0}))))),s("cellMetadata",{count:1},s("bk",{},s("rc",{t:1,v:0}))));class Oe{index=new Map;count=0;of(n){this.count+=1;let e=this.index.get(n);return e===void 0&&(e=this.index.size,this.index.set(n,e)),e}xml(){const n=[...this.index.keys()].map(e=>`<si><t${/^\s|\s$|\n/u.test(e)?' xml:space="preserve"':""}>${x(e)}</t></si>`);return s("sst",{xmlns:A.main,count:this.count,uniqueCount:this.index.size},...n)}}const G=l=>x(l),Pe="Base case";function Fe(l){const n=new Map;for(const o of l.scenarios)for(const r of o.cells)n.set(j(r),r);const e=(o,r)=>s("inputCells",{r:j(o),val:r===null||r instanceof z?"":typeof r=="boolean"?r?"1":"0":String(r)}),t=(o,r)=>s("scenario",{name:o,locked:!0,count:r.length,user:"AllyHub"},...r);return s("scenarios",{current:0,show:0,sqref:[...n.keys()].join(" ")},t(Pe,[...n.values()].map(o=>e(o,o.base))),...l.scenarios.map(o=>t(o.name,o.cells.map(r=>e(r,r.value)))))}function De(l,n,e,t){const o=[];let r=0;for(const{row:d,col:h,paths:i,column:a}of ge(l,n)){let c=0;const u=we(a);for(const T of i){const w=$e(T)?e?.(T):void 0,E=w&&ee(w);if(!w||!E){r+=1;continue}const g=Math.round(E.width/E.height*u);o.push({row:d,col:h,x:c,width:g,height:u,name:T.split("/").pop()??T,file:`.${E.type==="jpeg"?"jpg":E.type}`,bytes:w}),c+=g+4}}for(const d of l.spec.pictures??[]){const h=J(d.at),i=e?.(d.file),a=i&&ee(i);if(!h||!i||!a)continue;const c=a.width/a.height,u=d.width??(d.height===void 0?a.width:d.height*c);o.push({row:h.row,col:h.col,x:d.x??0,y:d.y??0,width:Math.round(u),height:Math.round(d.height??u/c),name:d.file.split("/").pop()??d.file,file:`.${a.type==="jpeg"?"jpg":a.type}`,bytes:i})}return r>0&&t.push(`${l.name}: ${String(r)} file${r===1?"":"s"} in a cell, which stay${r===1?"s":""} a name`),o}class je{arrays=!1;places=new Map;sheet;calc;styles;strings;wb;cached;left;isTable;isRangeName;hiddenRows;tall;scenarios;drawn;constructor(n,e,t,o,r,d,h=[],i){this.sheet=n,this.calc=e,this.wb=e.wb,this.styles=t,this.strings=o,this.cached=r,this.left=d,this.isTable=c=>this.wb.table(c)!==void 0,this.isRangeName=c=>{const u=this.wb.name(c)?.formula?.node;return this.isTable(c)||u!==void 0&&X({kind:"unary",op:"-",arg:u})},this.hiddenRows=e.filtered(n),this.scenarios=i,this.drawn=n.charts.length>0||h.length>0;const a=new Map;for(const c of h)c.y===void 0&&a.set(c.row,Math.max(a.get(c.row)??0,c.height));this.tall=a}add(n,e){let t=this.places.get(n);t||(t=new Set,this.places.set(n,t)),t.add(e)}gather(){const{sheet:n}=this;for(let e=0;e<n.columnsUsed;e++){const[t,o]=n.span(e,0,Number.MAX_SAFE_INTEGER);for(let r=t;r<=o;r++)(n.at(r,e)!==void 0||n.spillAt(r,e))&&this.add(r,e)}for(const{area:e}of n.styledAreas()){const t=(e.bottom-e.top+1)*(e.right-e.left+1);if(t>Le){this.left.push(`${n.name}!${L(e)}: its look on the cells that hold something, ${String(t)} cells being too many to write empty`);continue}for(let o=e.top;o<=e.bottom;o++)for(let r=e.left;r<=e.right;r++)this.add(o,r)}for(const e of n.keys.keys())this.add(Math.floor(e/16384),e%16384)}styleOf(n,e){const t=this.sheet.lookAt(n,e);return Object.keys(t).length===0?void 0:this.styles.xf(t)}held(n,e){return e.length<=B?e:(this.left.push(`${this.sheet.name}!${n} past Excel's ${String(B)} characters, of its ${String(e.length)}`),e.slice(0,B))}value(n,e,t){return t===null?s("c",{r:n,s:e}):typeof t=="number"?`<c r="${n}"${k(e)}><v>${String(t)}</v></c>`:typeof t=="boolean"?`<c r="${n}"${k(e)} t="b"><v>${t?"1":"0"}</v></c>`:t instanceof z?ie(t)?`<c r="${n}"${k(e)} t="e"><v>${t.code}</v></c>`:`<c r="${n}"${k(e)} t="s"><v>${String(this.strings.of(t.code))}</v></c>`:`<c r="${n}"${k(e)} t="s"><v>${String(this.strings.of(this.held(n,t)))}</v></c>`}table(n){return this.sheet.tableAt(n.row,n.col)?.name}formula(n,e,t){const o=this.calc.value(t.sheet,t.row,t.col),{node:r}=t.shared;if(!r)return`<c r="${n}"${k(e)} t="e"><v>#NAME?</v></c>`;const d=t.moved,h=t.array!==void 0||t.blocked!==void 0||X(d,this.isRangeName),i=H(d,{table:this.table(t),isTable:this.isTable,array:h});let a=`<f>${G(i)}</f>`,c="";if(h){this.arrays=!0;const u=t.spill??{top:t.row,left:t.col,bottom:t.row,right:t.col};a=`<f t="array" ref="${L(u)}">${G(i)}</f>`,c=' cm="1"'}return this.cached?o===null||typeof o=="number"?`<c r="${n}"${k(e)}${c}>${a}<v>${String(o??0)}</v></c>`:typeof o=="boolean"?`<c r="${n}"${k(e)} t="b"${c}>${a}<v>${o?"1":"0"}</v></c>`:o instanceof z?ie(o)?`<c r="${n}"${k(e)} t="e"${c}>${a}<v>${o.code}</v></c>`:`<c r="${n}"${k(e)}${c}>${a}<v>0</v></c>`:`<c r="${n}"${k(e)} t="str"${c}>${a}<v>${x(this.held(n,o))}</v></c>`:`<c r="${n}"${k(e)}${c}>${a}</c>`}cell(n,e){const t=j({row:n,col:e}),o=this.styleOf(n,e),r=this.sheet.at(n,e);return r instanceof ve?this.formula(t,o,r):r===void 0&&this.sheet.spillAt(n,e)&&this.cached?this.value(t,o,this.calc.value(this.sheet,n,e)):this.value(t,o,r??null)}columns(){const{sheet:n}=this,{spec:e}=n,t=new Map,o=new Map;for(const i of n.tables)for(const a of i.columns)a.spec?.width!==void 0&&o.set(i.at.col+a.index,a.spec.width);const r=new Set(o.keys()),d=new Map;for(const[i,a]of Object.entries(e.columns??{})){const c=ue(i);c!==void 0&&(d.set(c,a),r.add(c))}for(const i of r){const a=d.get(i),c=a?.width??o.get(i),u=ae(a);t.set(i,s("col",{min:i+1,max:i+1,width:_e(c??Ee),style:u===void 0?void 0:this.styles.xf(u),hidden:a?.hidden===!0?!0:void 0,customWidth:c===void 0?void 0:!0,outlineLevel:a?.level}))}const h=[...t.keys()].sort((i,a)=>i-a).map(i=>t.get(i)??"");return h.length===0?"":s("cols",{},...h)}rowAttrs(n){const e=this.sheet.spec.rows?.[String(n+1)],t=ae(e),o=e?.height??this.tall.get(n);return{r:n+1,s:t===void 0?void 0:this.styles.xf(t),customFormat:t===void 0?void 0:!0,ht:o===void 0?void 0:Re(o),customHeight:o===void 0?void 0:!0,hidden:e?.hidden===!0||this.hiddenRows.has(n)?!0:void 0,outlineLevel:e?.level}}rows(){const{sheet:n}=this,e=new Set(this.places.keys());for(const o of Object.keys(n.spec.rows??{}))e.add(Number(o)-1);for(const o of this.hiddenRows)e.add(o);const t=[];for(const o of[...e].sort((r,d)=>r-d)){const r=[...this.places.get(o)??[]].sort((i,a)=>i-a),d=s("row",this.rowAttrs(o)).slice(4,-2);if(r.length===0){t.push(`<row${d}/>`);continue}let h=`<row${d}>`;for(const i of r)h+=this.cell(o,i);t.push(`${h}</row>`)}return t.join("")}view(n){const{freeze:e}=this.sheet;let t="";if(e&&(e.row>0||e.col>0)){const o=e.row>0&&e.col>0?"bottomRight":e.row>0?"bottomLeft":"topRight";t=s("pane",{xSplit:e.col>0?e.col:void 0,ySplit:e.row>0?e.row:void 0,topLeftCell:j(e),activePane:o,state:"frozen"})}return s("sheetViews",{},s("sheetView",{showGridLines:this.sheet.spec.gridlines===!1?!1:void 0,tabSelected:n?!0:void 0,workbookViewId:0},t))}write(n,e){const{sheet:t}=this;this.gather();const o=Xe(this.places),r=this.rows(),d=t.merges.map(g=>s("mergeCell",{ref:L(g)})),h=t.tables.map((g,y)=>s("tablePart",{"r:id":`rId${String(y+1)}`})),{print:i}=t.spec,a=i?.fit,c=Object.keys(t.spec.notes??{}).length>0,u=h.length+1+(this.drawn?1:0)+(c?2:0);let T=0;const w=Object.entries(t.spec.links??{}).map(([g,y])=>y.startsWith("#")?s("hyperlink",{ref:g,location:y.slice(1)}):s("hyperlink",{ref:g,"r:id":`rId${String(u+T++)}`}));return{xml:v+s("worksheet",{xmlns:A.main,"xmlns:r":A.rel},t.spec.tab===void 0&&a===void 0?"":s("sheetPr",{},t.spec.tab===void 0?"":s("tabColor",{rgb:`FF${t.spec.tab.slice(1).toUpperCase()}`}),a===void 0?"":s("pageSetUpPr",{fitToPage:!0})),s("dimension",{ref:o?L(o):"A1"}),this.view(n),s("sheetFormatPr",{defaultRowHeight:15,outlineLevelRow:ne(t.spec.rows),outlineLevelCol:ne(t.spec.columns)}),this.columns(),r===""?s("sheetData"):`<sheetData>${r}</sheetData>`,t.spec.protect===!0?s("sheetProtection",{sheet:!0,objects:!0,scenarios:!0}):"",this.scenarios?Fe(this.scenarios):"",this.sheetFilter(),d.length>0?s("mergeCells",{count:d.length},...d):"",...t.conditions.map((g,y)=>this.condition(g,y+1)),this.validations(),w.length>0?s("hyperlinks",{},...w):"",s("pageMargins",{...Ne,...i?.margins}),i?.orientation!==void 0||i?.paper!==void 0||a!==void 0?s("pageSetup",{paperSize:i?.paper===void 0?void 0:fe[i.paper],fitToWidth:a?.width,fitToHeight:a?.height,orientation:i?.orientation}):"",i?.header||i?.footer?s("headerFooter",{},i.header?s("oddHeader",{},x(se(i.header))):"",i.footer?s("oddFooter",{},x(se(i.footer))):""):"",this.drawn?s("drawing",{"r:id":`rId${String(h.length+1)}`}):"",c?s("legacyDrawing",{"r:id":`rId${String(h.length+(this.drawn?2:1))}`}):"",h.length>0?s("tableParts",{count:h.length},...h):""),tables:t.tables.map((g,y)=>this.tableXml(g,e+y))}}bound(n){if(n===void 0)return"";if(typeof n=="number")return String(n);if(!n.startsWith("=")){const t=be(n);return typeof t.value=="number"&&t.formula===void 0?String(t.value):`"${n.replaceAll('"','""')}"`}const e=xe(n);return e.ok?H(e.node,{isTable:this.isTable,array:!0}):n.slice(1)}cfvo(n){return s("cfvo",{type:n.at,val:n.value===void 0?void 0:typeof n.value=="number"?n.value:this.bound(n.value)})}condition(n,e){const{spec:t}=n,o=t.range,r=(a,...c)=>s("conditionalFormatting",{sqref:o},s("cfRule",{...a,priority:e,stopIfTrue:t.stop===!0?!0:void 0},...c)),d=()=>{const a=Ue(t);return Object.keys(a).length===0?void 0:this.styles.dxf(a)},h=n.areas[0],i=h?j({row:h.top,col:h.left}):"A1";switch(t.type){case"cellIs":return r({type:"cellIs",dxfId:d(),operator:t.operator},...t.formula.map(a=>s("formula",{},x(this.bound(a)))));case"containsText":{const a=t.operator??"contains",c=`"${t.text.replaceAll('"','""')}"`,u=a==="contains"?`NOT(ISERROR(SEARCH(${c},${i})))`:a==="notContains"?`ISERROR(SEARCH(${c},${i}))`:a==="beginsWith"?`LEFT(${i},LEN(${c}))=${c}`:`RIGHT(${i},LEN(${c}))=${c}`;return r({type:a==="contains"?"containsText":a==="notContains"?"notContainsText":a,dxfId:d(),operator:a==="contains"?"containsText":a,text:t.text},s("formula",{},x(u)))}case"duplicateValues":case"uniqueValues":return r({type:t.type,dxfId:d()});case"top10":return r({type:"top10",dxfId:d(),percent:t.percent===!0?!0:void 0,bottom:t.bottom===!0?!0:void 0,rank:t.rank});case"aboveAverage":return r({type:"aboveAverage",dxfId:d(),aboveAverage:t.below===!0?!1:void 0,equalAverage:t.equal===!0?!0:void 0});case"expression":return r({type:"expression",dxfId:d()},s("formula",{},x(this.bound(t.formula.startsWith("=")?t.formula:`=${t.formula}`))));case"dataBar":return r({type:"dataBar"},s("dataBar",{showValue:t.show===!1?!1:void 0},this.cfvo(t.min??{at:"min"}),this.cfvo(t.max??{at:"max"}),s("color",{rgb:re(t.color)})));case"colorScale":return r({type:"colorScale"},s("colorScale",{},...t.stops.map(a=>this.cfvo(a)),...t.stops.map(a=>s("color",{rgb:re(a.color)}))));case"iconSet":{const a=Number.parseInt(t.icons,10),c=t.stops??Array.from({length:a},(u,T)=>({at:"percent",value:Math.round(T*100/a)}));return r({type:"iconSet"},s("iconSet",{iconSet:t.icons,showValue:t.show===!1?!1:void 0,reverse:t.reverse===!0?!0:void 0},...c.map(u=>this.cfvo(u))))}}}validation(n){const{spec:e}=n;let t="";if(e.values){const h=e.values.join(",");(h.length>q||e.values.some(i=>i.includes(",")))&&this.left.push(`${this.sheet.name}!${e.range}: a list a file's cell cannot spell out, its values longer than ${String(q)} characters or holding a comma`),t=`"${h.slice(0,q)}"`}else t=this.bound(e.formula?.[0]);const o=this.bound(e.formula?.[1]),{error:r,prompt:d}=e;return e.multiple===!0&&this.left.push(`${this.sheet.name}!${e.range}: several choices in a cell: its text stays, and Excel's list offers one at a time`),s("dataValidation",{type:e.type,errorStyle:r?.style===void 0||r.style==="stop"?void 0:r.style,operator:e.operator===void 0||e.operator==="between"?void 0:e.operator,allowBlank:e.blank===!1?void 0:!0,showDropDown:e.dropdown===!1?!0:void 0,showInputMessage:d?.show===!1?void 0:!0,showErrorMessage:r?.show===!1||e.multiple===!0?void 0:!0,errorTitle:r?.title,error:r?.message,promptTitle:d?.title,prompt:d?.message,sqref:e.range},t===""?"":s("formula1",{},x(t)),o===""?"":s("formula2",{},x(o)))}validations(){const n=this.sheet.validations;return n.length===0?"":s("dataValidations",{count:n.length},...n.map(e=>this.validation(e)))}filterColumns(n){return[...n.columns.entries()].sort(([e],[t])=>e-t).map(([e,t])=>We(e-n.area.left,t))}sheetFilter(){const n=this.sheet.filters.find(e=>!e.table);return n?s("autoFilter",{ref:L(n.area)},...this.filterColumns(n)):""}columnFormula(n,e){if(!e?.node)return"";const t=X(e.node,this.isRangeName),o=H(e.node,{table:n.name,isTable:this.isTable,array:t});return s("calculatedColumnFormula",{array:t?!0:void 0},G(o))}tableXml(n,e){const t=n.area,o=L({...t,bottom:Math.max(t.bottom,t.top+1)}),r=n.spec.style??DEFAULT_TABLE_STYLE,d=this.sheet.filters.find(h=>h.table===n);return v+s("table",{xmlns:A.main,id:e,name:n.name,displayName:n.name,ref:o,totalsRowShown:0},d?s("autoFilter",{ref:o},...this.filterColumns(d)):"",s("tableColumns",{count:n.columns.length},...n.columns.map((h,i)=>s("tableColumn",{id:i+1,name:h.name},this.columnFormula(n,h.formula)))),r==="none"?s("tableStyleInfo",{showFirstColumn:0,showLastColumn:0,showRowStripes:1,showColumnStripes:0}):s("tableStyleInfo",{name:r,showFirstColumn:0,showLastColumn:0,showRowStripes:1,showColumnStripes:0}))}}const Ne={left:.7,right:.7,top:.75,bottom:.75,header:.3,footer:.3},ne=l=>{const n=Object.values(l??{}).flatMap(e=>e.level===void 0?[]:[e.level]);return n.length>0?Math.max(...n):void 0},se=l=>[l.left===void 0?"":`&L${l.left}`,l.center===void 0?"":`&C${l.center}`,l.right===void 0?"":`&R${l.right}`].join(""),ze=l=>typeof l=="string"?{text:l,author:oe}:{text:l.text,author:l.author??oe},oe="AllyHub";function He(l){const n=l.map(([t,o])=>({ref:t,...ze(o)})),e=[...new Set(n.map(t=>t.author))];return v+s("comments",{xmlns:A.main},s("authors",{},...e.map(t=>s("author",{},x(t)))),s("commentList",{},...n.map(t=>s("comment",{ref:t.ref,authorId:e.indexOf(t.author)},s("text",{},s("r",{},s("t",{},x(t.text))))))))}function Ve(l){return`<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout><v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe"><v:stroke joinstyle="miter"/><v:path gradientshapeok="t" o:connecttype="rect"/></v:shapetype>${l.flatMap(([e],t)=>{const o=J(e);return o?[`<v:shape id="_x0000_s${String(1025+t)}" type="#_x0000_t202" style="position:absolute;margin-left:80pt;margin-top:5pt;width:120pt;height:60pt;z-index:${String(t+1)};visibility:hidden" fillcolor="#ffffe1" o:insetmode="auto"><v:fill color2="#ffffe1"/><v:shadow on="t" color="black" obscured="t"/><v:path o:connecttype="none"/><v:textbox style="mso-direction-alt:auto"><div style="text-align:left"></div></v:textbox><x:ClientData ObjectType="Note"><x:MoveWithCells/><x:SizeWithCells/><x:Anchor>${String(o.col+1)}, 15, ${String(o.row)}, 2, ${String(o.col+3)}, 15, ${String(o.row+4)}, 4</x:Anchor><x:AutoFill>False</x:AutoFill><x:Row>${String(o.row)}</x:Row><x:Column>${String(o.col)}</x:Column></x:ClientData></v:shape>`]:[]}).join("")}</xml>`}const re=l=>`FF${l.slice(1).toUpperCase()}`;function Ue(l){if(l.type==="dataBar"||l.type==="colorScale"||l.type==="iconSet")return{};const n={};for(const e of["bold","italic","underline","strike","color","fill","border"])l[e]!==void 0&&(n[e]=l[e]);return n}function We(l,n){return s("filterColumn",{colId:l},s("filters",{blank:n.blanks===!0?!0:void 0},...(n.values??[]).map(e=>s("filter",{val:e}))))}const k=l=>l===void 0?"":` s="${String(l)}"`,ie=l=>l.code!=="#CYCLE!";function Xe(l){let n;for(const[e,t]of l)for(const o of t)n?(n.top=Math.min(n.top,e),n.bottom=Math.max(n.bottom,e),n.left=Math.min(n.left,o),n.right=Math.max(n.right,o)):n={top:e,bottom:e,left:o,right:o};return n}const Be=new Set(["width","height","hidden"]);function ae(l){if(!l)return;const n=Object.fromEntries(Object.entries(l).filter(([e])=>!Be.has(e)));return Object.keys(n).length===0?void 0:n}const V=l=>v+s("Relationships",{xmlns:A.pkg},...l.map(([n,e,t],o)=>s("Relationship",{Id:`rId${String(o+1)}`,Type:n,Target:e,TargetMode:t})));function qe(l,n){const e=l.name(n);if(!e)return;const t=e.formula?.node;if(t)return H(t,{isTable:r=>l.table(r)!==void 0,array:!0});const{value:o}=e;return o==null?'""':typeof o=="string"?`"${o.replaceAll('"','""')}"`:typeof o=="boolean"?o?"TRUE":"FALSE":o instanceof z?o.code:String(o)}const Ge=(l,n)=>l.length===n.length&&l.every((e,t)=>e===n[t]),le=l=>`$${K(l.left)}$${String(l.top+1)}:$${K(l.right)}$${String(l.bottom+1)}`;export function writeXlsx(l,n={}){const e=l.wb,t=[];e.checks.length>0&&t.push(`${String(e.checks.length)} check${e.checks.length===1?"":"s"}: a file has no such thing`);const o=ye(l);t.push(...o.left);const r=new Te,d=new Oe,h=new TextEncoder,i={},a=[["/xl/workbook.xml",S.sheet]],c=Math.max(0,e.sheets.findIndex(m=>m.spec.hidden!==!0));let u=1,T=!1;const w=new Map;let E=0,g=0,y=0;for(const[m,f]of e.sheets.entries()){const R=String(m+1),M=De(f,l,n.file,t),_=f.charts.filter(({spec:p})=>[p.categories,...p.series.flatMap(C=>[C.values,C.x])].some(C=>C?.endsWith("#"))).length;_>0&&t.push(`${f.name}: ${String(_)} chart${_===1?"":"s"} on a spill: ${_===1?"it reads":"they read"} the cells the spill covers now, and will not grow with it`);const P=new je(f,l,r,d,n.cached!==!1,t,M,o.sheets.find(p=>p.sheet===f)),F=P.write(m===c,u);T||=P.arrays,i[`xl/worksheets/sheet${R}.xml`]=F.xml,a.push([`/xl/worksheets/sheet${R}.xml`,S.worksheet]);const b=[];for(const p of F.tables){const C=`table${String(u)}.xml`;u+=1,i[`xl/tables/${C}`]=p,a.push([`/xl/tables/${C}`,S.table]),b.push([`${$}table`,`../tables/${C}`])}if(f.charts.length>0||M.length>0){E+=1;const p=`drawing${String(E)}.xml`;i[`xl/drawings/${p}`]=ke(f.charts,M),a.push([`/xl/drawings/${p}`,S.drawing]),b.push([`${$}drawing`,`../drawings/${p}`]);const C=f.charts.map(D=>{g+=1;const N=`chart${String(g)}.xml`;return i[`xl/charts/${N}`]=Se(l,f,D),a.push([`/xl/charts/${N}`,S.chart]),[`${$}chart`,`../charts/${N}`]});for(const D of M){const Z=[...w].find(([,he])=>Ge(he,D.bytes))?.[0]??`image${String(w.size+1)}${D.file}`;w.set(Z,D.bytes),C.push([`${$}image`,`../media/${Z}`])}i[`xl/drawings/_rels/${p}.rels`]=V(C)}const W=Object.entries(f.spec.notes??{});if(W.length>0){y+=1;const p=String(y);i[`xl/comments${p}.xml`]=He(W),a.push([`/xl/comments${p}.xml`,S.comments]),i[`xl/drawings/vmlDrawing${p}.vml`]=Ve(W),b.push([`${$}vmlDrawing`,`../drawings/vmlDrawing${p}.vml`]),b.push([`${$}comments`,`../comments${p}.xml`])}for(const p of Object.values(f.spec.links??{}))p.startsWith("#")||b.push([`${$}hyperlink`,p,"External"]);b.length>0&&(i[`xl/worksheets/_rels/sheet${R}.xml.rels`]=V(b))}const ce=e.sheets.length,I=e.sheets.map((m,f)=>[`${$}worksheet`,`worksheets/sheet${String(f+1)}.xml`]);I.push([`${$}theme`,"theme/theme1.xml"]),I.push([`${$}styles`,"styles.xml"]),I.push([`${$}sharedStrings`,"sharedStrings.xml"]),T&&(I.push([`${$}sheetMetadata`,"metadata.xml"]),i["xl/metadata.xml"]=v+Ie,a.push(["/xl/metadata.xml",S.metadata]));const O=[...e.names.values()].flatMap(m=>{const f=qe(e,m.name);return f===void 0?[]:[s("definedName",{name:m.name},x(f))]});e.sheets.forEach((m,f)=>{const R=m.filters.find(b=>!b.table);R&&O.push(s("definedName",{name:"_xlnm._FilterDatabase",localSheetId:f,hidden:!0},x(`${Q(m.name)}${le(R.area)}`)));const M=Q(m.name),_=m.spec.print,P=_?.area===void 0?void 0:pe(_.area);P&&O.push(s("definedName",{name:"_xlnm.Print_Area",localSheetId:f},x(`${M}${le(P)}`)));const F=[_?.title_cols?.toUpperCase().replace(/([A-Z]+):([A-Z]+)/u,"$$$1:$$$2"),_?.title_rows?.replace(/(\d+):(\d+)/u,"$$$1:$$$2")].flatMap(b=>b===void 0?[]:[`${M}${b}`]);F.length>0&&O.push(s("definedName",{name:"_xlnm.Print_Titles",localSheetId:f},x(F.join(","))))}),i["xl/workbook.xml"]=v+s("workbook",{xmlns:A.main,"xmlns:r":A.rel},s("workbookPr",{}),s("bookViews",{},s("workbookView",{activeTab:c===0?void 0:c})),s("sheets",{},...e.sheets.map((m,f)=>s("sheet",{name:m.name,sheetId:f+1,state:m.spec.hidden===!0?"hidden":void 0,"r:id":`rId${String(f+1)}`}))),O.length>0?s("definedNames",{},...O):"",s("calcPr",{calcId:Ae,fullCalcOnLoad:!0})),i["xl/_rels/workbook.xml.rels"]=V(I),i["xl/styles.xml"]=v+r.xml(),i["xl/sharedStrings.xml"]=v+d.xml(),i["xl/theme/theme1.xml"]=v+Ce,i["docProps/core.xml"]=v+s("cp:coreProperties",{"xmlns:cp":"http://schemas.openxmlformats.org/package/2006/metadata/core-properties","xmlns:dc":"http://purl.org/dc/elements/1.1/"},e.title===void 0?"":s("dc:title",{},x(e.title))),i["docProps/app.xml"]=v+s("Properties",{xmlns:"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"},s("Application",{},"AllyHub")),i["_rels/.rels"]=V([[`${$}officeDocument`,"xl/workbook.xml"],["http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties","docProps/core.xml"],[`${$}extended-properties`,"docProps/app.xml"]]),a.push(["/xl/styles.xml",S.styles],["/xl/sharedStrings.xml",S.strings],["/xl/theme/theme1.xml",S.theme],["/docProps/core.xml",S.core],["/docProps/app.xml",S.app]),i["[Content_Types].xml"]=v+s("Types",{xmlns:A.types},s("Default",{Extension:"rels",ContentType:"application/vnd.openxmlformats-package.relationships+xml"}),s("Default",{Extension:"xml",ContentType:"application/xml"}),y>0?s("Default",{Extension:"vml",ContentType:"application/vnd.openxmlformats-officedocument.vmlDrawing"}):"",...[...new Set([...w.keys()].map(m=>m.split(".").pop()??""))].sort().map(m=>s("Default",{Extension:m,ContentType:`image/${m==="jpg"?"jpeg":m}`})),...a.map(([m,f])=>s("Override",{PartName:m,ContentType:f})));const Y=["[Content_Types].xml","_rels/.rels","docProps/app.xml","docProps/core.xml","xl/workbook.xml","xl/_rels/workbook.xml.rels",...Array.from({length:ce},(m,f)=>`xl/worksheets/sheet${String(f+1)}.xml`)],de=[...Y,...Object.keys(i).filter(m=>!Y.includes(m)).sort()],U={};for(const m of de)U[m]=[h.encode(i[m]??""),{mtime:te}];for(const[m,f]of[...w].sort(([R],[M])=>R.localeCompare(M)))U[`xl/media/${m}`]=[f,{mtime:te}];return{bytes:me(U),left:t}}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allyhub-next/sheet",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allyhub-next/site",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./assets": {
@@ -1,8 +1,8 @@
1
- import type { AnimationEffect, AnimationFile, LineDash, TransitionFile, LineEnd, ShapeGeometry, TextAlign, ThemeColor } from "@allyhub-next/formats";
1
+ import type { Numbering, AnimationEffect, AnimationFile, LineDash, TransitionFile, LineEnd, ShapeGeometry, TextAlign, ThemeColor } from "@allyhub-next/formats";
2
2
  import type { Anchor, AutoSize, FillType, PlaceholderType, ShapeType } from "./enums.js";
3
- import type { Color, ComponentContext, DeckDef, FontDef, Frame, FreeformPath, GeneratedSlideDef, GeneratorContext, LayoutDef, MasterDef, ParagraphDef, TableCellDef, TableDef, ParagraphFormatDef, PropSpec, RunDef, ShapeDef, TextFrameDef } from "./model.js";
4
- import type { ChartType } from "@allyhub-next/formats";
5
- import { Chart, type CategoryChartData } from "./chart-api.js";
3
+ import type { Color, ComponentContext, DeckDef, FontDef, Frame, GradientDef, FreeformPath, GeneratedSlideDef, GeneratorContext, LayoutDef, MasterDef, ParagraphDef, TableCellDef, TableDef, ParagraphFormatDef, PropSpec, RunDef, ShapeDef, TextFrameDef } from "./model.js";
4
+ import type { SheetChartType } from "@allyhub-next/formats";
5
+ import { Chart, type CategoryChartData, type XyChartData } from "./chart-api.js";
6
6
  import type { ThemeInput } from "./theme.js";
7
7
  import { type Length, type SlideSizeName } from "./units.js";
8
8
  /** python-pptx's `RGBColor(r, g, b)` and `RGBColor.from_string("3C2F80")`: a colour as `#RRGGBB`. */
@@ -25,6 +25,15 @@ export declare class Font {
25
25
  private readonly def;
26
26
  constructor(def: FontDef);
27
27
  private _set;
28
+ /** A line through it (PowerPoint's Strikethrough). */
29
+ get strike(): boolean | undefined;
30
+ set strike(v: boolean | undefined);
31
+ /** Raised or lowered, a share of its size: superscript 0.3, subscript -0.25. */
32
+ get baseline(): number | undefined;
33
+ set baseline(v: number | undefined);
34
+ /** The colour behind it, as RGBColor gives one. */
35
+ get highlight(): string | undefined;
36
+ set highlight(v: string | undefined);
28
37
  get name(): string | undefined;
29
38
  set name(v: string | undefined);
30
39
  get size(): Length | undefined;
@@ -42,12 +51,20 @@ export declare class Font {
42
51
  get color(): ColorFormat;
43
52
  }
44
53
  /** python-pptx's `_Run`. */
54
+ /** python-pptx's `_Hyperlink`: what a run opens. */
55
+ export declare class Hyperlink {
56
+ private readonly def;
57
+ constructor(def: RunDef);
58
+ get address(): string | undefined;
59
+ set address(v: string | undefined);
60
+ }
45
61
  export declare class Run {
46
62
  private readonly def;
47
63
  constructor(def: RunDef);
48
64
  get text(): string;
49
65
  set text(v: string);
50
66
  get font(): Font;
67
+ get hyperlink(): Hyperlink;
51
68
  }
52
69
  /** What a paragraph and a list style's level share: alignment, spacing, its runs' font. */
53
70
  declare abstract class Format {
@@ -89,6 +106,9 @@ export declare class Paragraph extends Format {
89
106
  export declare class ListLevel extends Format {
90
107
  protected readonly fmt: ParagraphFormatDef;
91
108
  constructor(def: ParagraphFormatDef);
109
+ /** Counted in place of a bullet (`a:buAutoNum`): "arabicPeriod", "alphaLcPeriod"… */
110
+ get numbered(): Numbering | undefined;
111
+ set numbered(v: Numbering | undefined);
92
112
  /** Its bullet character, or null for none (`a:buChar`, `a:buNone`). */
93
113
  get bullet(): string | null | undefined;
94
114
  set bullet(v: string | null | undefined);
@@ -154,16 +174,52 @@ export declare class FillFormat {
154
174
  private readonly read;
155
175
  private readonly write;
156
176
  private readonly start;
157
- constructor(read: () => Color | null | undefined, write: (v: Color | null) => void, start?: Color);
177
+ /** The shape it fills: only a shape's has a gradient and a transparency. */
178
+ private readonly shape;
179
+ constructor(read: () => Color | null | undefined, write: (v: Color | null) => void, start?: Color, shape?: ShapeDef);
158
180
  /** A solid fill; its colour is fore_color. */
159
181
  solid(): void;
160
182
  /** No fill (python-pptx's `background()`: transparent). */
161
183
  background(): void;
162
- /** MSO_FILL.SOLID, MSO_FILL.BACKGROUND, or undefined while it is inherited. */
184
+ private _shape;
185
+ /** A gradient fill, of two of the theme's colours until gradient_stops says otherwise. */
186
+ gradient(): void;
187
+ /** A gradient's degrees, clockwise from left to right. python-pptx's run the other way. */
188
+ get gradient_angle(): number;
189
+ set gradient_angle(v: number);
190
+ /** A gradient's stops: `[{ at, color, transparency }]`, `at` and `transparency` shares. */
191
+ get gradient_stops(): GradientDef["stops"];
192
+ set gradient_stops(v: GradientDef["stops"]);
193
+ private _gradient;
194
+ /** How much of the fill shows through, a share (PowerPoint's Transparency). */
195
+ get transparency(): number;
196
+ set transparency(v: number);
197
+ /** MSO_FILL.SOLID, MSO_FILL.BACKGROUND, MSO_FILL.GRADIENT, or undefined while it is inherited. */
163
198
  get type(): FillType | undefined;
164
199
  /** A solid fill's colour; python-pptx refuses it for another fill: call solid() first. */
165
200
  get fore_color(): ColorFormat;
166
201
  }
202
+ /**
203
+ * python-pptx's `ShadowFormat`: a shape's shadow. Its `inherit` is there; what
204
+ * a shadow is made of, python-pptx has no API for.
205
+ */
206
+ export declare class ShadowFormat {
207
+ private readonly def;
208
+ constructor(def: ShapeDef);
209
+ private _shadow;
210
+ /** Whether it has none of its own; false gives it SHADOW_DEFAULTS. */
211
+ get inherit(): boolean;
212
+ set inherit(v: boolean);
213
+ get blur_radius(): Length;
214
+ set blur_radius(v: Length);
215
+ get distance(): Length;
216
+ set distance(v: Length);
217
+ get angle(): number;
218
+ set angle(v: number);
219
+ get transparency(): number;
220
+ set transparency(v: number);
221
+ get color(): ColorFormat;
222
+ }
167
223
  /** python-pptx's `LineFormat`: a shape's outline. */
168
224
  export declare class LineFormat {
169
225
  private readonly def;
@@ -245,6 +301,7 @@ export declare class Shape {
245
301
  set text(v: string);
246
302
  get fill(): FillFormat;
247
303
  get line(): LineFormat;
304
+ get shadow(): ShadowFormat;
248
305
  /** Its geometry's adjustments: `adjustments[0] = 0.1` sets a rounded rectangle's corner. */
249
306
  get adjustments(): Adjustments;
250
307
  }
@@ -406,7 +463,7 @@ export declare class ShapeCollection implements Iterable<Shape> {
406
463
  /** A table of equal columns and rows (python-pptx's add_table), in `.table`; unlike python-pptx's it has no style, so its look is its cells'. */
407
464
  add_table(rows: number, cols: number, left: Length, top: Length, width: Length, height: Length): Shape;
408
465
  /** A chart (python-pptx's add_chart), in `.chart`; PowerPoint opens it as its own, with its numbers in a workbook. */
409
- add_chart(chart_type: ChartType, x: Length, y: Length, cx: Length, cy: Length, chart_data: CategoryChartData): Shape;
466
+ add_chart(chart_type: SheetChartType, x: Length, y: Length, cx: Length, cy: Length, chart_data: CategoryChartData | XyChartData): Shape;
410
467
  /** A group of shapes (python-pptx's add_group_shape): what is added to its `shapes` is in it. */
411
468
  add_group_shape(): GroupShape;
412
469
  /** A freeform's builder (python-pptx's build_freeform): filled and outlined as an autoshape. */