check-whitespace: normalize javascript files

This commit is contained in:
Andrej730
2026-09-14 11:33:51 +05:00
parent 032a361d16
commit 0c12d2334b
18 changed files with 119 additions and 117 deletions
@@ -268,7 +268,7 @@ function toggleClientList() {
const clientNumbers = $("<div>")
.addClass("client-detail")
.text(
`${allDrawings[client.ifc_file].drawings.length} Drawing(s),
`${allDrawings[client.ifc_file].drawings.length} Drawing(s),
${allDrawings[client.ifc_file].sheets.length} Sheet(s)`
);
clientDetailsDiv.append(clientNumbers);
@@ -334,7 +334,7 @@ function toggleClientList() {
const clientNumbers = $("<div>")
.addClass("client-detail")
.text(
`${allDrawings[client.ifc_file].drawings.length} Drawing(s),
`${allDrawings[client.ifc_file].drawings.length} Drawing(s),
${allDrawings[client.ifc_file].sheets.length} Sheet(s)`
);
clientDetailsDiv.append(clientNumbers);
@@ -75,7 +75,7 @@ function setupPage(workScheduleData){
g.setTotalHeight("");
g.Draw();
var values = document.getElementById("print_page_size").value.split(",")
let css =
let css =
"@media print {\n @page {\n size: " + values[0] + "mm " + values[1] + "mm;\n }\n";
g.printChart(values[0], values[1], css);
g.setTotalHeight(900);
@@ -109,4 +109,4 @@ function setupPage(workScheduleData){
let creation_date_string = document.createTextNode("Created: " + new Date(workScheduleData.CreationDate).toLocaleDateString());
creation_date.appendChild(creation_date_string);
document.getElementById("schedule-header").appendChild(creation_date);
}
}
+15 -15
View File
@@ -99,29 +99,29 @@ const PROVIDERS = {
baseUrlPlaceholder: "https://openrouter.ai/api/v1",
baseUrlDefault: "https://openrouter.ai/api/v1",
models: [
{
{
value: "openai/gpt-oss-20b",
label: "gpt-oss-20b"
label: "gpt-oss-20b"
},
{
{
value: "openai/gpt-oss-120b",
label: "gpt-oss-120b"
label: "gpt-oss-120b"
},
{
{
value: "mistralai/mistral-small-3.2-24b-instruct",
label: "mistral-small-3.2"
label: "mistral-small-3.2"
},
{
value: "openai/gpt-4.1",
label: "gpt-4.1"
{
value: "openai/gpt-4.1",
label: "gpt-4.1"
},
{
value: "anthropic/claude-sonnet-4-5",
label: "claude-sonnet-4-5"
{
value: "anthropic/claude-sonnet-4-5",
label: "claude-sonnet-4-5"
},
{
value: "google/gemini-2.5-pro-preview",
label: "gemini-2.5-pro"
{
value: "google/gemini-2.5-pro-preview",
label: "gemini-2.5-pro"
},
],
},
+3 -3
View File
@@ -25,10 +25,10 @@ async function ensurePyodide() {
await pyodide.loadPackage("numpy");
await pyodide.loadPackage("shapely");
await pyodide.loadPackage("typing-extensions");
const micropip = pyodide.pyimport("micropip");
micropip.install("python-dateutil")
const wheelUrl = "https://ifcopenshell.github.io/wasm-wheels/ifcopenshell-0.8.5-cp313-cp313-pyodide_2025_0_wasm32.whl";
await micropip.install(wheelUrl);
@@ -98,4 +98,4 @@ self.onmessage = async (ev) => {
} catch (e) {
fail(id, e);
}
};
};
@@ -34,4 +34,4 @@ export {
Content as DialogContent,
Description as DialogDescription,
Close as DialogClose,
};
};
@@ -46,4 +46,4 @@ export {
SubContent,
SubTrigger,
Trigger,
};
};
@@ -51,4 +51,4 @@ export {
RadioGroup as MenubarRadioGroup,
Label as MenubarLabel,
GroupHeading as MenubarGroupHeading,
};
};
@@ -1 +1 @@
export { default as Toaster } from "./sonner.svelte";
export { default as Toaster } from "./sonner.svelte";
@@ -18,4 +18,4 @@ export {
Trigger as TooltipTrigger,
Provider as TooltipProvider,
Portal as TooltipPortal,
};
};
@@ -49,7 +49,7 @@ wasm.init().then(async () => {
export async function preloadAutocompletions() {
try {
const schemas = ["IFC2X3", "IFC4"]; // TODO: IFC4X3 is excluded for now because of an error
// Entity classes
const entitySets = await Promise.all(
schemas.map(schema => wasm.getAllEntityClasses(schema))
@@ -60,7 +60,7 @@ export async function preloadAutocompletions() {
allEntities.add(entity.toUpperCase());
}
}
// Data types
const dataTypeSets = await Promise.all(
schemas.map(schema => wasm.getAllDataTypes(schema))
@@ -71,20 +71,20 @@ export async function preloadAutocompletions() {
allDataTypes.add(dataType);
}
}
// Material categories and Classification systems
const [materialCategories, classificationSystems] = await Promise.all([
wasm.getMaterialCategories(),
wasm.getStandardClassificationSystems()
]) as [string[], AutocompletionState["classificationSystems"]];
// Cache autocompletions
Autocompletions.entityClasses = Array.from(allEntities).sort();
Autocompletions.materialCategories = materialCategories;
Autocompletions.classificationSystems = classificationSystems;
Autocompletions.dataTypes = Array.from(allDataTypes).sort();
Autocompletions.isLoaded = true;
console.log('Autocompletions preloaded');
} catch (error) {
console.error('Failed to preload autocompletions:', error);
@@ -122,13 +122,13 @@ export function getDataTypes() {
export async function loadIfc(file: File): Promise<IfcModel> {
try {
IFCModels.isLoading = true;
const arrayBuffer = await file.arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer);
// Load IFC model
const ifcId = await wasm.loadIfc(Array.from(uint8Array)) as string;
// Add to models list
const model: IfcModel = {
id: ifcId,
@@ -137,7 +137,7 @@ export async function loadIfc(file: File): Promise<IfcModel> {
loadedAt: new Date()
};
IFCModels.models = [...IFCModels.models, model];
console.log(`IFC model "${file.name}" loaded with ID: ${ifcId}`);
return model;
} catch (error) {
@@ -152,10 +152,10 @@ export async function unloadIfc(modelId: string) {
try {
// Unload model
await wasm.unloadIfc(modelId);
// Remove from models list
IFCModels.models = IFCModels.models.filter(model => model.id !== modelId);
console.log(`IFC model with ID ${modelId} unloaded`);
} catch (error) {
console.error('Failed to unload IFC model:', error);
@@ -173,10 +173,10 @@ export async function auditIfc(modelId: string, idsData: string | Uint8Array | A
} else {
idsBytes = idsData;
}
// Run audit
const auditResult = await wasm.auditIfc(modelId, idsBytes) as { json: AuditReportData; html: string };
console.log(`Audit completed for model ${modelId}`);
return auditResult;
} catch (error) {
@@ -194,7 +194,7 @@ export async function openIfc() {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.ifc';
fileInput.onchange = async (event) => {
const target = event.target as HTMLInputElement | null;
const file = target?.files?.[0];
@@ -202,13 +202,13 @@ export async function openIfc() {
reject(new Error('No file selected'));
return;
}
// Check if it's an IFC file
if (!file.name.toLowerCase().endsWith('.ifc')) {
reject(new Error('Please select a valid IFC file (.ifc)'));
return;
}
try {
await loadIfc(file);
resolve();
@@ -216,7 +216,7 @@ export async function openIfc() {
reject(error);
}
};
fileInput.onerror = () => reject(new Error('Failed to open file picker'));
fileInput.click();
});
@@ -234,7 +234,7 @@ export function createAuditReport(
): AuditReport | undefined {
const model = getIfcById(modelId);
if (!model) return;
const auditReport: AuditReport = {
id: id(),
modelId: modelId,
@@ -244,7 +244,7 @@ export function createAuditReport(
data: auditData,
htmlReport: htmlReport
};
IFCModels.audits.unshift(auditReport);
return auditReport;
}
@@ -266,7 +266,7 @@ export async function downloadAuditReport(auditId: string) {
if (!audit || !audit.htmlReport) {
throw new Error('HTML report not available for this audit');
}
// Get IDS document title for filename
let filename = 'report.html';
if (audit.document && IDS.Module.documents[audit.document]) {
@@ -274,15 +274,15 @@ export async function downloadAuditReport(auditId: string) {
const title = doc.info?.title || 'untitled';
filename = `report_${title.replace(/[^a-z0-9]/gi, '_').toLowerCase()}.html`;
}
const blob = new Blob([audit.htmlReport], { type: 'text/html' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
@@ -293,47 +293,47 @@ export async function runAudit() {
if (IFCModels.models.length === 0) {
throw new Error('Please load an IFC model first');
}
if (!IDS.Module.activeDocument) {
throw new Error('Please create or open an IDS document first');
}
// Clear previous audit reports
IFCModels.audits = [];
// Get the active IDS document XML
const idsXml = await IDS.exportActiveDocument();
if (!idsXml) {
throw new Error('Failed to export IDS document');
}
// Run audit on all loaded models
let firstAuditReport: AuditReport | undefined;
for (const model of IFCModels.models) {
const result = await auditIfc(model.id, idsXml);
// Extract JSON and HTML reports from the result
const jsonData = result.json || null;
const htmlReport = result.html || null;
if (!jsonData) {
continue;
}
const auditReport = createAuditReport(model.id, IDS.Module.activeDocument as string, jsonData, htmlReport);
// Store the first audit report to open in viewer
if (!firstAuditReport) {
firstAuditReport = auditReport;
}
}
// Switch to viewer mode and set the first audit report as active
if (firstAuditReport && IDS.Module.activeDocument) {
IDS.setDocumentState(IDS.Module.activeDocument, {
IDS.setDocumentState(IDS.Module.activeDocument, {
viewMode: 'viewer',
auditReport: firstAuditReport.id
});
}
return firstAuditReport;
}
@@ -59,33 +59,33 @@ export const connect = () => new Promise<void>((resolve, reject) => {
resolve();
return;
}
try {
Bonsai.socket = io(`ws://127.0.0.1:${Bonsai.port}/ifctester`, {
transports: ['websocket'],
reconnection: false,
timeout: 5000
});
Bonsai.socket.on('connect', () => {
Bonsai.connected = true;
success('Connected to Bonsai');
resolve();
});
Bonsai.socket.on('disconnect', () => {
Bonsai.connected = false;
});
Bonsai.socket.on('connect_error', (err: Error) => {
Bonsai.connected = false;
error(`Failed to connect to Bonsai: ${err.message}`);
reject(err);
});
Bonsai.socket.on('audit_result', handleAuditResult);
Bonsai.socket.on('error', handleAuditError);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
error(`Failed to connect to Bonsai: ${message}`);
@@ -113,35 +113,35 @@ export const runAudit = async () => {
if (!Bonsai.socket || !Bonsai.connected || !IDS.Module.activeDocument) {
return null;
}
try {
Bonsai.auditing = true;
const activeDoc = IDS.Module.documents[IDS.Module.activeDocument];
if (!activeDoc) throw new Error('No active IDS document');
// Convert IDS document to XML string
const idsXml = await IDS.exportActiveDocument();
if (!idsXml) {
throw new Error('Failed to export IDS document');
}
const requestId = id();
const socket = Bonsai.socket;
if (!socket) {
throw new Error('Bonsai socket not connected');
}
return new Promise<string | null>((resolve, reject) => {
// Store request with resolve/reject functions
pendingAudits.set(requestId, { resolve, reject });
socket.emit('audit_ids', {
id: requestId,
ids: idsXml
});
});
} catch (err) {
Bonsai.auditing = false;
const message = err instanceof Error ? err.message : String(err);
@@ -156,19 +156,19 @@ export const runAudit = async () => {
*/
const handleAuditResult = (data: AuditResultPayload) => {
if (!data.id || !data.json_report) return;
const pendingAudit = pendingAudits.get(data.id);
if (!pendingAudit) {
console.warn('[Bonsai] Received response for unknown audit ID:', data.id);
return;
}
pendingAudits.delete(data.id);
const { resolve } = pendingAudit;
try {
const reportData = JSON.parse(data.json_report) as AuditReportData;
const auditReport: AuditReport = {
id: data.id,
modelId: `bonsai:${data.id}`,
@@ -178,16 +178,16 @@ const handleAuditResult = (data: AuditResultPayload) => {
data: reportData,
htmlReport: data.html_report
};
// Store audit report
IFCModels.audits.unshift(auditReport);
Bonsai.auditing = false;
success('Audit completed (Bonsai)');
// Resolve promise with audit ID
resolve(data.id);
} catch (err) {
Bonsai.auditing = false;
const message = err instanceof Error ? err.message : String(err);
@@ -202,16 +202,16 @@ const handleAuditResult = (data: AuditResultPayload) => {
*/
const handleAuditError = (data: AuditErrorPayload) => {
if (!data.id) return;
const pendingAudit = pendingAudits.get(data.id);
if (!pendingAudit) {
console.warn('[Bonsai] Received error for unknown audit ID:', data.id);
return;
}
pendingAudits.delete(data.id);
const { resolve } = pendingAudit;
Bonsai.auditing = false;
error(`Audit failed (Bonsai): ${data.error ?? "Unknown error"}`);
resolve(null);
@@ -55,7 +55,7 @@ export async function createDocument() {
export async function deleteDocument(id: string) {
// Clear any audit reports generated using this IDS document
clearIdsAuditReports(id);
delete Module.documents[id];
delete Module.states[id];
@@ -73,18 +73,18 @@ export async function deleteDocument(id: string) {
// We need this because the backend exports with xs: prefix, yet expects a dict without prefixes.
function normalizeIdsDict(obj: unknown): unknown {
if (typeof obj !== 'object' || obj === null) return obj;
if (Array.isArray(obj)) {
return obj.map(normalizeIdsDict);
}
const result: Record<string, unknown> = {};
for (const [key, value] of Object.entries(obj)) {
if (key === 'xs:restriction' && Array.isArray(value) && value.length > 0) {
// Convert xs:restriction array to restriction object
const restriction = value[0] as Record<string, unknown>;
const newRestriction: Record<string, unknown> = {};
for (const [restrictionKey, restrictionValue] of Object.entries(restriction)) {
if (restrictionKey.startsWith('xs:')) {
// Remove xs: prefix from keys
@@ -94,13 +94,13 @@ function normalizeIdsDict(obj: unknown): unknown {
newRestriction[restrictionKey] = restrictionValue;
}
}
result.restriction = newRestriction;
} else {
result[key] = normalizeIdsDict(value);
}
}
return result;
}
@@ -111,7 +111,7 @@ export async function openDocument() {
};
fileInput.type = 'file';
fileInput.accept = '.ids,.xml';
fileInput.onchange = async (event) => {
const target = event.target as HTMLInputElement | null;
const file = target?.files?.[0];
@@ -119,7 +119,7 @@ export async function openDocument() {
reject(new Error('No file selected'));
return;
}
try {
const reader = new FileReader();
reader.onload = async (e) => {
@@ -130,10 +130,10 @@ export async function openDocument() {
// Add document to list and set as active
Module.documents[docId] = doc;
// Initialize document state and switch to viewer mode
setDocumentState(docId, { viewMode: 'viewer' });
Module.activeDocument = docId;
resolve();
@@ -147,11 +147,11 @@ export async function openDocument() {
reject(error);
}
};
fileInput.oncancel = () => {
reject(new Error('File selection cancelled'));
};
// Trigger the file dialog
fileInput.click();
});
@@ -175,7 +175,7 @@ export async function exportDocument(docId: string) {
}
const xmlString = await wasm.exportIDS(doc as Record<string, unknown>) as string;
// Create and download file
const blob = new Blob([xmlString], { type: 'application/xml' });
const url = URL.createObjectURL(blob);
@@ -290,7 +290,7 @@ export function stringifyFacet(
const usage = getSpecUsage(spec);
const descriptions: string[] = [];
// Entity facet
if (facetType === "entity") {
if (clauseType === "applicability") {
@@ -377,13 +377,13 @@ export function stringifyFacet(
if (clauseType === "requirements" && "@cardinality" in facet && facet["@cardinality"] === "prohibited") {
isProhibited = !isProhibited;
}
if (isProhibited)
combined = combined.replace("Shall", "Shall not").replace("shall", "shall not");
if (clauseType === "requirements" && "@cardinality" in facet && facet["@cardinality"] === "optional")
combined = combined.replace("Shall", "May").replace("shall", "may");
return renderFacetString(combined);
}
@@ -398,27 +398,27 @@ function stringifyValue(value?: FacetValue) {
// Converts restriction objects to human-readable strings
function stringifyRestriction(restriction: Restriction) {
if (!restriction) return "";
// Handle enumeration
if (restriction.enumeration && Array.isArray(restriction.enumeration)) {
const values = restriction.enumeration.map(item => `**${item['@value']}**` || '').filter(v => v);
return values.length > 0 ? `is one of ${values.join(", ")}` : "has enumeration restriction";
}
// Handle pattern
if (restriction.pattern && Array.isArray(restriction.pattern) && restriction.pattern.length > 0) {
const pattern = `\`${restriction.pattern[0]['@value']}\`` || '';
return pattern ? `matches pattern ${pattern}` : "has pattern restriction";
}
// Handle length restrictions
if (restriction.length && Array.isArray(restriction.length) && restriction.length.length > 0) {
const length = `**${restriction.length[0]['@value']}**` || '';
return length ? `has length ${length}` : "has length restriction";
}
// Handle range restrictions
if (restriction.minInclusive || restriction.maxInclusive ||
if (restriction.minInclusive || restriction.maxInclusive ||
restriction.minExclusive || restriction.maxExclusive) {
const parts = [];
if (restriction.minInclusive && restriction.minInclusive.length > 0) {
@@ -435,7 +435,7 @@ function stringifyRestriction(restriction: Restriction) {
}
return parts.length > 0 ? `is in range ${parts.join(", ")}` : "has range restriction";
}
// Handle length range restrictions
if (restriction.minLength || restriction.maxLength) {
const parts = [];
@@ -447,16 +447,16 @@ function stringifyRestriction(restriction: Restriction) {
}
return parts.length > 0 ? `has ${parts.join(", ")}` : "has length range restriction";
}
return "has complex restriction";
}
function renderFacetString(text: string): string {
// Convert **text** to <strong>text</strong>
const withStrong = text.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
// Convert `text` to <code>text</code>
const withCode = withStrong.replace(/`([^`]+)`/g, '<code>$1</code>');
return withCode;
}
@@ -75,7 +75,7 @@ class WASMModule extends EventEmitter {
return new Promise((resolve, reject) => {
this.pendingMessages.set(id, { resolve, reject });
worker.postMessage({
type,
payload,
@@ -86,7 +86,7 @@ class WASMModule extends EventEmitter {
_handleWorkerMessage({ type, payload, id }: WorkerResponse) {
const pendingMessage = this.pendingMessages.get(id);
if (!pendingMessage) {
console.warn('[WASM] Received response for unknown message ID:', id);
return;
@@ -16,7 +16,7 @@ let PartOf: any;
export async function init(pdide: any) {
pyodide = pdide;
await pyodide.loadPackagesFromImports(`
import ifctester.ids
import ifctester.facet
@@ -25,7 +25,7 @@ export async function init(pdide: any) {
// Import the core IDS classes
Ids = pyodide.pyimport("ifctester.ids").Ids;
Specification = pyodide.pyimport("ifctester.ids").Specification;
// Import facet classes
Entity = pyodide.pyimport("ifctester.facet").Entity;
Attribute = pyodide.pyimport("ifctester.facet").Attribute;
@@ -56,13 +56,13 @@ export function validateIDS(idsObj: Record<string, unknown>): boolean {
const ids_raw = _idsToInstance(idsObj)
const tempFilename = `temp_${Date.now()}.xml`;
const isValid = ids_raw.to_xml(tempFilename); // to_xml validates the XML as well, as far as I understand
pyodide.runPython(`
import os
if os.path.exists("${tempFilename}"):
os.remove("${tempFilename}")
`);
return isValid;
}
+1 -1
View File
@@ -3,4 +3,4 @@
*/
export {default as Home} from './Home/index.svelte';
export {default as NotFound} from './NotFound/index.svelte';
export {default as NotFound} from './NotFound/index.svelte';
+1 -1
View File
@@ -5,4 +5,4 @@ const routes = {
'*': NotFound,
};
export default routes;
export default routes;