/* * eslint.config.js (ESLint 9 flat config) * * Lints static/js/**\/*.js as plain browser scripts (sourceType:'script'). * All cross-file globals are declared here so no-undef works across the * multi-file global-scope architecture (no ES modules, no bundler). * * Load order and ownership of each global is documented in index.html. */ import js from '@eslint/js'; import globals from 'globals'; // ── Globals that cross file boundaries ────────────────────────────────────── // Declared 'writable' if the variable itself is reassigned across files; // 'readonly' if only the function/value is consumed by other files. const appGlobals = { // state.js — mutable state shared across all modules S: 'writable', _plugins: 'writable', _batchState: 'writable', _batchWs: 'writable', _bnd: 'writable', _photoQueue: 'writable', _aiBlocksVisible: 'writable', _aiLog: 'writable', _aiLogWs: 'writable', // helpers.js esc: 'readonly', toast: 'readonly', isDesktop: 'readonly', // api.js req: 'readonly', // canvas-boundary.js parseBounds: 'readonly', parseBndPluginResults: 'readonly', setupDetailCanvas: 'readonly', drawBnd: 'readonly', // tree-render.js walkTree: 'readonly', removeNode: 'readonly', findNode: 'readonly', pluginsByCategory: 'readonly', pluginsByTarget: 'readonly', isLoading: 'readonly', vPluginBtn: 'readonly', vBatchBtn: 'readonly', vAiIndicator: 'readonly', candidateSugRows: 'readonly', _STATUS_BADGE: 'readonly', getBookStats: 'readonly', vAiProgressBar: 'readonly', vApp: 'readonly', mainTitle: 'readonly', mainHeaderBtns: 'readonly', // detail-render.js vDetailBody: 'readonly', aiBlocksShown: 'readonly', // canvas-crop.js startCropMode: 'readonly', // editing.js attachEditables: 'readonly', initSortables: 'readonly', // photo.js collectQueueBooks: 'readonly', renderPhotoQueue: 'readonly', triggerPhoto: 'readonly', // init.js render: 'readonly', renderDetail: 'readonly', connectBatchWs: 'readonly', connectAiLogWs: 'readonly', loadTree: 'readonly', // CDN (SortableJS loaded via