opentakeoff-mcp 0.9.46 → 0.9.47
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.
- package/dist/server-core.js +35 -16
- package/package.json +1 -1
package/dist/server-core.js
CHANGED
|
@@ -2678,11 +2678,13 @@ function clusterRows(spans) {
|
|
|
2678
2678
|
}
|
|
2679
2679
|
var rowY = (r) => r.reduce((s, t) => s + t.y, 0) / r.length;
|
|
2680
2680
|
var SURFACE_WORDS = /* @__PURE__ */ new Set(["FLOOR", "BASE", "WALL", "WALLS", "CEILING", "NORTH", "SOUTH", "EAST", "WEST", "WAINSCOT"]);
|
|
2681
|
-
var ROOM_HEADERS = ["ROOM", "NO", "NUMBER", "NAME", "MARK", "LOCATION", "FLOOR", "BASE", "WALL", "WALLS", "NORTH", "SOUTH", "EAST", "WEST", "CEILING", "WAINSCOT", "REMARKS", "CLG", "HT", "HEIGHT", "FINISH", "BLDG", "BUILDING"];
|
|
2681
|
+
var ROOM_HEADERS = ["ROOM", "NO", "NUMBER", "NAME", "MARK", "LOCATION", "FLOOR", "BASE", "WALL", "WALLS", "NORTH", "SOUTH", "EAST", "WEST", "CEILING", "WAINSCOT", "REMARKS", "CLG", "HT", "HEIGHT", "FINISH", "CASEWORK", "CABINET", "COUNTER", "COUNTERTOP", "BLDG", "BUILDING"];
|
|
2682
2682
|
var FINISH_HEADERS = ["CODE", "MARK", "SYMBOL", "MATERIAL", "MANUFACTURER", "PRODUCT", "STYLE", "COLOR", "SIZE", "REMARKS", "DESCRIPTION", "PATTERN", "COMMENTS"];
|
|
2683
|
-
var headerLabel = (s, vocab) =>
|
|
2684
|
-
|
|
2685
|
-
|
|
2683
|
+
var headerLabel = (s, vocab) => headerLabels(s, vocab)[0] ?? null;
|
|
2684
|
+
var headerLabels = (s, vocab) => {
|
|
2685
|
+
const out = [];
|
|
2686
|
+
for (const w of norm(s).split(/[^A-Z]+/)) if (w && vocab.includes(w) && !out.includes(w)) out.push(w);
|
|
2687
|
+
return out;
|
|
2686
2688
|
};
|
|
2687
2689
|
function headerHits(row, vocab) {
|
|
2688
2690
|
const out = [];
|
|
@@ -2728,6 +2730,10 @@ function findHeaderRow(rows, vocab, required, minHits) {
|
|
|
2728
2730
|
const parent = parentLabelOver(rows, idx, i, h.span.x, hi, vocab);
|
|
2729
2731
|
if (parent && parent !== h.label) label = `${parent} ${h.label}`;
|
|
2730
2732
|
}
|
|
2733
|
+
if (used.has(label)) {
|
|
2734
|
+
const alt = headerLabels(h.span.str, vocab).find((w) => !used.has(w));
|
|
2735
|
+
if (alt) label = alt;
|
|
2736
|
+
}
|
|
2731
2737
|
if (used.has(label)) continue;
|
|
2732
2738
|
used.add(label);
|
|
2733
2739
|
anchors.push({ label, x: h.span.x + (h.span.w || 0) / 2 });
|
|
@@ -2877,14 +2883,15 @@ function rowKeyOf(raw, kind, buildings) {
|
|
|
2877
2883
|
}
|
|
2878
2884
|
var numOf = (key) => key.match(QUALIFIED_KEY_RE)?.[2] ?? key;
|
|
2879
2885
|
var centerX = (t) => t.x + (t.w || 0) / 2;
|
|
2880
|
-
function
|
|
2886
|
+
function columnMapFor(rows, anchors, cfg, x0, x1, coord) {
|
|
2887
|
+
const at = (t) => coord === "left" ? t.x : t.x + (t.w || 0) / 2;
|
|
2881
2888
|
const xs = [];
|
|
2882
2889
|
const hs = [];
|
|
2883
2890
|
for (let i = Math.max(cfg.fromIdx, 0); i < rows.length; i++) {
|
|
2884
2891
|
if (rowY(rows[i]) <= cfg.belowY) continue;
|
|
2885
2892
|
for (const t of rows[i]) {
|
|
2886
2893
|
if (t.x < x0 || t.x > x1 || revisionOf(t.str) != null) continue;
|
|
2887
|
-
xs.push(t
|
|
2894
|
+
xs.push(at(t));
|
|
2888
2895
|
hs.push(t.h || 8);
|
|
2889
2896
|
}
|
|
2890
2897
|
}
|
|
@@ -2912,23 +2919,35 @@ function columnStarts(rows, anchors, cfg, x0, x1) {
|
|
|
2912
2919
|
if (cur == null || c.start < cur) byLabel.set(own.label, c.start);
|
|
2913
2920
|
}
|
|
2914
2921
|
if (byLabel.size !== anchors.length) return null;
|
|
2915
|
-
const
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2922
|
+
const cols = [...byLabel.entries()].map(([label, start]) => ({ label, start })).sort((a, b) => a.start - b.start);
|
|
2923
|
+
if (cols.map((c) => c.label).join("|") !== anchors.map((a) => a.label).join("|")) return null;
|
|
2924
|
+
const starts = kept.map((c) => c.start);
|
|
2925
|
+
let on = 0;
|
|
2926
|
+
for (const x of xs) if (starts.some((st) => Math.abs(x - st) <= tol)) on++;
|
|
2927
|
+
return { coord, cols, score: on / xs.length };
|
|
2928
|
+
}
|
|
2929
|
+
function columnStarts(rows, anchors, cfg, x0, x1) {
|
|
2930
|
+
const FIT_FLOOR = 0.7;
|
|
2931
|
+
const fits = (m) => m && m.score >= FIT_FLOOR ? m : null;
|
|
2932
|
+
const left = fits(columnMapFor(rows, anchors, cfg, x0, x1, "left"));
|
|
2933
|
+
const center = fits(columnMapFor(rows, anchors, cfg, x0, x1, "center"));
|
|
2934
|
+
if (!left) return center;
|
|
2935
|
+
if (!center) return left;
|
|
2936
|
+
return center.score > left.score + 0.05 ? center : left;
|
|
2919
2937
|
}
|
|
2920
2938
|
function bandDataRows(rows, anchors, kind, sheetKey, buildings, cfg) {
|
|
2921
2939
|
const { x0, x1, medGap } = bandLimits(anchors);
|
|
2922
2940
|
const cols = columnStarts(rows, anchors, cfg, x0, x1);
|
|
2923
|
-
const keyTol = cols && cols.length > 1 ? Math.max(8, (cols[1].start - cols[0].start) * 0.5) : 40;
|
|
2941
|
+
const keyTol = cols && cols.cols.length > 1 ? Math.max(8, (cols.cols[1].start - cols.cols[0].start) * 0.5) : 40;
|
|
2924
2942
|
const out = [];
|
|
2925
2943
|
const outY = [];
|
|
2926
2944
|
let region = null;
|
|
2927
2945
|
const columnOf = (t) => {
|
|
2928
2946
|
if (!cols) return nearestAnchor(centerX(t), anchors);
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2947
|
+
const at = cols.coord === "left" ? t.x : centerX(t);
|
|
2948
|
+
let label = cols.cols[0].label;
|
|
2949
|
+
for (const c of cols.cols) {
|
|
2950
|
+
if (at + 1 >= c.start) label = c.label;
|
|
2932
2951
|
else break;
|
|
2933
2952
|
}
|
|
2934
2953
|
return label;
|
|
@@ -2962,7 +2981,7 @@ function bandDataRows(rows, anchors, kind, sheetKey, buildings, cfg) {
|
|
|
2962
2981
|
orphans.push({ toks: banded, y: rowY(rows[i]) });
|
|
2963
2982
|
continue;
|
|
2964
2983
|
}
|
|
2965
|
-
if (cols && Math.abs(banded[0].x - cols[0].start) > keyTol) continue;
|
|
2984
|
+
if (cols && Math.abs((cols.coord === "left" ? banded[0].x : centerX(banded[0])) - cols.cols[0].start) > keyTol) continue;
|
|
2966
2985
|
if (cfg.keyAlign && Math.abs(centerX(banded[0]) - cfg.keyAlign.x) > cfg.keyAlign.tol) continue;
|
|
2967
2986
|
const row = { key: keyed.key, sheet: sheetKey, cells: {} };
|
|
2968
2987
|
if (keyed.building) row.building = keyed.building;
|
|
@@ -11100,7 +11119,7 @@ function applyStagedTools(server, registered) {
|
|
|
11100
11119
|
// package.json
|
|
11101
11120
|
var package_default = {
|
|
11102
11121
|
name: "opentakeoff-mcp",
|
|
11103
|
-
version: "0.9.
|
|
11122
|
+
version: "0.9.47",
|
|
11104
11123
|
mcpName: "io.github.Kentucky-ai/opentakeoff",
|
|
11105
11124
|
type: "module",
|
|
11106
11125
|
description: "OpenTakeoff MCP server \u2014 drive the takeoff engine from your MCP client over stdio.",
|
package/package.json
CHANGED