locio 1.0.1 β 1.0.2
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/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +14 -5
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var e=require("process"),n=require("readline"),t=require("commander"),o=require("fs"),s=require("path"),i=require("url"),l=require("chalk"),r=require("fast-glob"),c=require("ignore"),a="undefined"!=typeof document?document.currentScript:null;function d(e){return e&&e.__esModule?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var o=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,o.get?o:{enumerable:!0,get:function(){return e[t]}})}}),n.default=e,Object.freeze(n)}var m=u(e),f=u(n),p=u(o),_=u(s),y=d(l),h=d(r),g=d(c),x=Object.defineProperty,b=(e,n,t)=>((e,n,t)=>n in e?x(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t)(e,"symbol"!=typeof n?n+"":n,t),$=i.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:a&&"SCRIPT"===a.tagName.toUpperCase()&&a.src||new URL("index.cjs",document.baseURI).href),v=s.dirname($);function k(){try{const e=[s.join(v,"../package.json"),s.join(v,"../../package.json"),s.join(process.cwd(),"package.json")];for(const n of e)try{const e=JSON.parse(o.readFileSync(n,"utf-8"));if(e.version)return e.version}catch{continue}return"0.0.0"}catch(e){return"0.0.0"}}var L=class e extends Error{constructor(e,n,t){super(e),this.cause=n,b(this,"suggestion"),this.name="LineCounterError",this.suggestion=t}static io(n,t){return new e(`IO error: ${n}`,t,"Check if the file/directory exists, you have read permissions, and there's sufficient disk space.")}static invalidSizeFormat(n){return new e(`Invalid size format: ${n}`,void 0,"Size format should be a number followed by a unit (e.g., '5MB', '1KB', '500B').\nValid units: B, KB, MB, GB, TB (case-insensitive).")}static invalidRegex(n,t){return new e(`Invalid regex pattern: ${n}${t?`: ${t.message}`:""}`,t,"Check your regex pattern syntax. Common issues:\n - Escape special characters with backslash (\\* for literal *)\n - Use proper grouping syntax (parentheses, brackets)\n - Verify quantifiers are properly placed\n - Test your pattern at https://regex101.com")}static directoryNotFound(n){let t;try{t=_.resolve(n)}catch{t=n}return new e(`Directory not found: ${n}`,void 0,`The path "${n}" does not exist.\n - Check if the path is correct (resolved: ${t})\n - Use relative paths like '.' for current directory\n - Verify you have read permissions\n - Check if it's a file instead of a directory (use the file path directly)`)}static notADirectory(n){return new e(`Not a directory: ${n}`,void 0,`"${n}" exists but is not a directory.\n - If it's a file, you can scan it directly: locio <file-path>\n - If you meant a directory, check the path spelling\n - Use 'locio .' to scan the current directory`)}static fileNotFound(n){return new e(`File not found: ${n}`,void 0,`The file "${n}" does not exist.\n - Check if the file path is correct\n - Verify the file extension\n - Ensure you have read permissions`)}static exportPathError(n,t){return new e(`Export path error: ${n}`,void 0,`Cannot write to export path "${n}": ${t}\n - Ensure the directory exists or can be created\n - Check write permissions\n - Verify there's sufficient disk space\n - Use an absolute path if relative paths aren't working`)}};function w(e){return e instanceof L}function C(e,n){return n&&Array.isArray(n)?[...n,e]:[e]}function j(e){return e.split(",").map(e=>e.trim()).filter(Boolean)}function S(e){if(void 0===e)return;if(!0===e)return"human";const n={json:"json",csv:"csv",tsv:"tsv",markdown:"markdown",md:"markdown",html:"html",human:"human",txt:"human"},t=j(e).map(e=>n[e.toLowerCase()]).filter(e=>void 0!==e);return t.length>0?1===t.length?t[0]:t:void 0}function z(e){const n=_.resolve(e);if(!p.existsSync(n))return{path:null,error:L.directoryNotFound(e)};const t=p.statSync(n);return t.isDirectory()||t.isFile()?{path:n,error:null}:{path:null,error:L.notADirectory(e)}}function E(e,n){const t=e.length>n.length?e:n;if(0===t.length)return 1;const o=function(e,n){const t=[];for(let e=0;e<=n.length;e++)t[e]=[e];for(let n=0;n<=e.length;n++)t[0][n]=n;for(let o=1;o<=n.length;o++)for(let s=1;s<=e.length;s++)n.charAt(o-1)===e.charAt(s-1)?t[o][s]=t[o-1][s-1]:t[o][s]=Math.min(t[o-1][s-1]+1,t[o][s-1]+1,t[o-1][s]+1);return t[n.length][e.length]}(e,n);return(t.length-o)/t.length}function F(){const e=new t.Command,n=["files-only","lines-only","exclude","exclude-ext","include-ext","exclude-dir","include-dir","exclude-name","include-name","max-size","min-size","no-hidden","no-empty","follow-links","max-depth","stats","no-progress","no-binary","ignore-case","quiet","export","export-path","watch","no-comments","code-vs-comments","rm-comments","top-files","top-dirs","version"];return e.configureOutput({writeErr:e=>{if(e.includes("unknown option")){const t=e.match(/unknown option ['"]--?([^'"]+)['"]/);if(t){const e=t[1],o=function(e,n,t=3){return n.map(n=>({option:n,score:E(e,n)})).sort((e,n)=>n.score-e.score).filter(e=>e.score>.3).slice(0,t).map(e=>e.option)}(e,n);if(o.length>0){const n=1===o.length?"Did you mean this?":"Did you mean one of these?";process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ ${n}\n`+o.map(e=>` β’ --${e}`).join("\n")+"\n\nRun 'locio --help' to see all available options.\n\n"),process.exit(1)}process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ This option doesn't exist. Run 'locio --help' to see all available options.\n\n`),process.exit(1)}}process.stderr.write(e)}}),e.name("LocIO").description("A powerful CLI tool to count lines and files in directories").version(k(),"-v, --version","Show version number").argument("[directory]","Directory to scan",".").option("-f, --files-only","Count only files").option("-l, --lines-only","Count only lines").option("-e, --exclude <pattern>","Exclude files matching pattern",C).option("--exclude-ext <extensions>","Exclude file extensions (comma-separated)").option("--include-ext <extensions>","Include only file extensions (comma-separated)").option("--exclude-dir <pattern>","Exclude directories matching pattern",C).option("--include-dir <pattern>","Include only directories matching pattern",C).option("--exclude-name <pattern>","Exclude files by name pattern",C).option("--include-name <pattern>","Include only files by name pattern",C).option("--max-size <size>","Maximum file size (e.g., 5MB)").option("--min-size <size>","Minimum file size (e.g., 1KB)").option("--no-hidden","Exclude hidden files").option("--no-empty","Exclude empty files").option("--follow-links","Follow symbolic links").option("--max-depth <depth>","Maximum directory depth",parseInt).option("--stats","Show detailed statistics").option("--no-progress","Disable progress indicator (enabled by default)").option("--no-binary","Exclude binary files").option("-i, --ignore-case","Case-insensitive pattern matching").option("-q, --quiet","Quiet mode (minimal output)").option("--export [format]","Write report to LocIO-report.{ext} in the given format (human, json, csv, tsv, markdown, html). Multiple formats can be specified comma-separated (e.g., json,html,markdown)").option("--export-path <dir>","Specify output directory for exported reports. Files will use default naming (LocIO-report.{ext}). Directories will be created automatically if they don't exist").option("-w, --watch","Watch directory for changes and auto-rescan").option("--no-comments","Disable comment counting (enabled by default)").option("--code-vs-comments","Show code vs comments ratio (automatically enables --comments)").option("--rm-comments [extensions]","Remove comments from files (modifies files in place). Optionally specify file extensions (comma-separated, e.g., js,ts,py). If no extensions specified, all files are processed.").option("--top-files <n>","Show top N largest files by size",parseInt).option("--top-dirs <n>","Show top N directories with most files",parseInt),e}var D=[{type:"nextjs",files:["next.config.js","next.config.ts","next.config.mjs","next.config.cjs"],packageJsonDeps:["next"],packageJsonDevDeps:["next"],priority:100},{type:"angular",files:["angular.json","angular-cli.json"],packageJsonDeps:["@angular/core"],packageJsonDevDeps:["@angular/cli","@angular/core"],priority:90},{type:"vue",files:["vue.config.js","vue.config.ts","vite.config.js","vite.config.ts"],packageJsonDeps:["vue"],packageJsonDevDeps:["vue","@vitejs/plugin-vue","vite"],dirs:[".nuxt"],priority:85},{type:"react",files:["react-scripts"],packageJsonDeps:["react"],packageJsonDevDeps:["react","react-scripts","@vitejs/plugin-react","vite"],dirs:["node_modules/react"],priority:80},{type:"typescript",files:["tsconfig.json","tsconfig.app.json","tsconfig.base.json"],priority:70},{type:"nodejs",files:["package.json"],priority:75},{type:"rust",files:["Cargo.toml","Cargo.lock"],priority:100},{type:"python",files:["requirements.txt","setup.py","pyproject.toml","Pipfile","poetry.lock","manage.py","setup.cfg","Pipfile.lock"],dirs:["__pycache__"],priority:100},{type:"go",files:["go.mod","go.sum","Gopkg.toml","Gopkg.lock"],priority:100},{type:"java",files:["pom.xml","build.gradle","build.gradle.kts","settings.gradle"],dirs:[".gradle"],priority:100},{type:"csharp",files:["*.csproj","*.sln","project.json","*.fsproj","*.vbproj"],dirs:[".vs"],priority:100},{type:"ruby",files:["Gemfile","Rakefile","Gemfile.lock"],dirs:[".bundle"],priority:100},{type:"php",files:["composer.json","composer.lock","artisan"],dirs:["vendor"],priority:100},{type:"swift",files:["Package.swift","*.xcodeproj","*.xcworkspace"],dirs:[".build"],priority:100},{type:"kotlin",files:["build.gradle.kts","settings.gradle.kts"],dirs:[".gradle"],priority:100},{type:"dart",files:["pubspec.yaml","pubspec.yml","pubspec.lock"],dirs:[".dart_tool"],priority:100}],T={nodejs:{exclude_dirs:["node_modules",".next",".nuxt",".cache","dist","build",".turbo",".vercel",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},nextjs:{exclude_dirs:["node_modules",".next",".vercel","out","dist","build",".turbo"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},react:{exclude_dirs:["node_modules","build","dist",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},vue:{exclude_dirs:["node_modules","dist",".nuxt",".cache","coverage",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},angular:{exclude_dirs:["node_modules","dist",".angular","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},typescript:{exclude_dirs:["node_modules","dist","build",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},rust:{exclude_dirs:["target",".cargo"],exclude_extensions:[],exclude_names:["Cargo.lock"]},python:{exclude_dirs:["__pycache__",".pytest_cache",".mypy_cache",".ruff_cache",".venv","venv","env",".env","build","dist",".*\\.egg-info",".tox",".coverage","htmlcov",".hypothesis"],exclude_extensions:["pyc","pyo","pyd","so"],exclude_names:[".python-version","pip-log.txt","pip-delete-this-directory.txt"]},go:{exclude_dirs:["vendor",".cache"],exclude_extensions:[],exclude_names:["go.sum"]},java:{exclude_dirs:["target","build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar","war","ear"],exclude_names:[".project",".*\\.iml"]},csharp:{exclude_dirs:["bin","obj",".vs","packages","TestResults","[Bb]in","[Oo]bj"],exclude_extensions:["dll","exe","pdb"],exclude_names:[]},ruby:{exclude_dirs:["vendor",".bundle","tmp","log"],exclude_extensions:[],exclude_names:["Gemfile.lock"]},php:{exclude_dirs:["vendor","node_modules"],exclude_extensions:[],exclude_names:["composer.lock"]},swift:{exclude_dirs:[".build",".swiftpm","DerivedData"],exclude_extensions:[],exclude_names:["Package.resolved"]},kotlin:{exclude_dirs:["build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar"],exclude_names:[".project",".*\\.iml"]},dart:{exclude_dirs:[".dart_tool","build"],exclude_extensions:[],exclude_names:["pubspec.lock"]},unknown:{exclude_dirs:[],exclude_extensions:[],exclude_names:[]}};function O(e,n,t){if(!e||!n&&!t)return!1;const o={...e.dependencies||{},...e.devDependencies||{}};if(n)for(const e of n)if(o[e])return!0;if(t)for(const e of t)if(o[e])return!0;return!1}function M(e,n){if(!e||!n||!e.scripts)return!1;for(const t of n)if(e.scripts[t])return!0;return!1}function q(e,n){if(n.includes("*"))try{const t=p.readdirSync(e),o=n.replace(/\*/g,".*"),s=new RegExp(`^${o}$`);return t.some(n=>{const t=_.join(e,n);try{const e=p.statSync(t);return(e.isFile()||e.isDirectory())&&s.test(n)}catch{return!1}})}catch{return!1}else{const t=_.join(e,n);try{if(p.existsSync(t)){return p.statSync(t).isFile()}}catch{}}return!1}function R(e,n){const t=_.join(e,n);try{if(p.existsSync(t)){return p.statSync(t).isDirectory()}}catch{}return!1}function I(e,n=2){try{const t=p.readdirSync(e);for(const o of t){const t=_.join(e,o);try{const e=p.statSync(t);if(e.isFile()&&(o.endsWith(".ts")||o.endsWith(".tsx")))return!0;if(e.isDirectory()&&n>0&&!o.startsWith(".")&&"node_modules"!==o&&I(t,n-1))return!0}catch{}}}catch{}return!1}function B(e){const n=_.resolve(e);let t=n;try{p.statSync(n).isFile()&&(t=_.dirname(n))}catch{}const o=new Map,s=function(e){const n=_.join(e,"package.json");try{if(p.existsSync(n)){const e=p.readFileSync(n,"utf-8");return JSON.parse(e)}}catch{}return null}(t);for(const e of D){let n=0;const i=[];for(const o of e.files)q(t,o)&&(n+=30,i.push(`file:${o}`));if(e.dirs)for(const o of e.dirs)R(t,o)&&(n+=20,i.push(`dir:${o}`));if((e.packageJsonDeps||e.packageJsonDevDeps)&&O(s,e.packageJsonDeps,e.packageJsonDevDeps)){n+=50;const t=[...e.packageJsonDeps||[],...e.packageJsonDevDeps||[]];i.push(`dep:${t.join(",")}`)}if(e.packageJsonScripts&&M(s,e.packageJsonScripts)&&(n+=15,i.push(`script:${e.packageJsonScripts.join(",")}`)),"typescript"===e.type&&(q(t,"tsconfig.json")&&(n+=30,i.push("file:tsconfig.json")),I(t)&&(n+=20,i.push("typescript-files")),s&&q(t,"package.json"))){O(s,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(n=Math.floor(.5*n),i.push("nodejs-backend-penalty"))}if("nodejs"===e.type&&q(t,"package.json")&&(q(t,"tsconfig.json")||I(t))&&(n+=40,i.push("nodejs-with-typescript")),"react"===e.type)try{const e=p.readdirSync(t);e.some(e=>{const n=_.join(t,e);try{return p.statSync(n).isFile()&&(e.endsWith(".jsx")||e.endsWith(".tsx"))}catch{return!1}})&&(n+=15,i.push("jsx-files"))}catch{}n=Math.floor(n*(1+e.priority/100)),n>0&&o.set(e.type,{type:e.type,score:n,indicators:i})}if(s){if(!Array.from(o.keys()).some(e=>"react"===e||"vue"===e||"angular"===e||"nextjs"===e)){const e=q(t,"tsconfig.json")||I(t);if(e&&q(t,"package.json")){O(s,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(o.has("nodejs")||o.set("nodejs",{type:"nodejs",score:55,indicators:["package.json","nodejs-backend-with-typescript"]})),o.has("typescript")||o.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]})}else e?o.has("typescript")||o.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]}):o.has("nodejs")||o.set("nodejs",{type:"nodejs",score:30,indicators:["package.json"]})}}return Array.from(o.values()).sort((e,n)=>n.score-e.score)}function W(e){const n=B(e);return 0===n.length?"unknown":n[0].type}function A(e){const n=[];let t="",o="",s=!1;switch(e.toLowerCase().replace(/^\./,"")){case"js":case"jsx":case"ts":case"tsx":case"c":case"cpp":case"cc":case"cxx":case"h":case"hpp":case"java":case"cs":case"php":case"swift":case"go":case"rust":case"rs":case"dart":case"kt":case"scala":case"sc":n.push("//"),t="/*",o="*/",s=!0;break;case"sh":case"bash":case"zsh":case"fish":case"py":case"python":case"rb":case"ruby":case"r":case"pl":case"perl":case"yaml":case"yml":case"toml":case"conf":case"ini":case"cfg":case"dockerfile":case"makefile":case"make":case"cmake":case"ps1":case"psm1":case"ex":case"exs":n.push("#");break;case"html":case"htm":case"xml":case"xhtml":case"svg":n.push("\x3c!--"),t="\x3c!--",o="--\x3e",s=!0;break;case"css":case"scss":case"sass":case"less":case"styl":t="/*",o="*/",s=!0;break;case"sql":n.push("--"),t="/*",o="*/",s=!0;break;case"lua":n.push("--"),t="--[[",o="]]",s=!0;break;case"pas":case"p":case"pp":case"fs":case"fsi":case"fsx":n.push("//"),t="(*",o="*)",s=!0;break;case"hs":case"lhs":n.push("--"),t="{-",o="-}",s=!0;break;case"erl":case"hrl":case"m":case"matlab":n.push("%");break;case"vhd":case"vhdl":n.push("--");break;case"bat":case"cmd":n.push("::");break;case"vbs":n.push("'");break;case"clj":case"cljs":case"cljc":case"lisp":case"lsp":case"el":case"rkt":case"rktl":n.push(";");break;case"ml":case"mli":t="(*",o="*)",s=!0;break;default:n.push("//","#","--")}return{singleLine:n,multiLineStart:t,multiLineEnd:o,supportsMultiLine:s}}function P(e,n,t){let o=0,s=!1,i=0,l=-1;const r=[];let c=-1,a=-1;for(;i<e.length;){const d=e[i];if(s)s=!1,i++;else if("\\"!==d||0===o){if(3===o&&"$"===d&&i+1<e.length&&"{"===e[i+1]){let n=1;for(i+=2;i<e.length&&n>0;)"{"===e[i]?n++:"}"===e[i]&&n--,i++;continue}if(0===o){if('"'===d)o=2;else if("'"===d)o=1;else if("`"===d)o=3;else if("/"===d&&i+1<e.length){const t=e[i+1];if("/"===t||"*"===t){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){r.push({pos:i,marker:t});break}n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i),i++;continue}{const n=i>0?e[i-1]:" ";/[\s,;=([{!&|?:]/.test(n)&&(o=4,l=i)}}}else if(2===o&&'"'===d)o=0;else if(1===o&&"'"===d)o=0;else if(3===o&&"`"===d)o=0;else if(4===o){if("\\"===d){i+1<e.length?i+=2:i++;continue}if("/"===d)if(i+1<e.length){const n=e[i+1];if(/[gimsuvy]/.test(n)){let n=i+1;for(;n<e.length&&/[gimsuvy]/.test(e[n]);)n++;(n>=e.length||!/[a-zA-Z0-9_]/.test(e[n]))&&(o=0,l=-1,i=n-1)}else/[a-zA-Z0-9_]/.test(n)||(o=0,l=-1)}else o=0,l=-1;else if(" "===d||"\t"===d){const n=i-l-1;let t=!0;for(let n=l+1;n<i;n++)if(" "!==e[n]&&"\t"!==e[n]){t=!1;break}if(t&&n<=2){let n=i+1;for(;n<e.length&&(" "===e[n]||"\t"===e[n]);)n++;n<e.length&&/[0-9;,)}\]\]]/.test(e[n])&&(o=0,l=-1)}}else/[;,)}\]\]]/.test(d)&&(o=0,l=-1)}if(0===o){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){r.push({pos:i,marker:t});break}if(n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i),n.supportsMultiLine&&t&&e.substring(i).startsWith(n.multiLineEnd)){a=i;break}}i++}else s=!0,i++}if(t){if(-1!==a){const t=e.substring(0,a).trim(),o=e.substring(a+n.multiLineEnd.length).trim();return{commentStart:0,commentEnd:a+n.multiLineEnd.length,isMultiLine:!0,endsMultiLine:!0,commentMarker:n.multiLineEnd,hasCodeBefore:t.length>0,hasCodeAfter:o.length>0}}return{commentStart:0,commentEnd:e.length,isMultiLine:!0,endsMultiLine:!1,commentMarker:n.multiLineEnd,hasCodeBefore:!1,hasCodeAfter:!1}}if(n.supportsMultiLine&&-1!==c){const t=e.substring(0,c).trim(),o=e.indexOf(n.multiLineEnd,c),s=-1!==o,i=s?e.substring(o+n.multiLineEnd.length).trim():"";return{commentStart:c,commentEnd:s?o+n.multiLineEnd.length:e.length,isMultiLine:!0,endsMultiLine:s,commentMarker:n.multiLineStart,hasCodeBefore:t.length>0,hasCodeAfter:i.length>0}}if(r.length>0){const n=r[0],t=e.substring(0,n.pos).trim();return{commentStart:n.pos,commentEnd:e.length,isMultiLine:!1,endsMultiLine:!1,commentMarker:n.marker,hasCodeBefore:t.length>0,hasCodeAfter:!1}}return null}function N(e){try{const n=p.readFileSync(e,"utf-8"),t=n.split(/\r?\n/),o=A(_.extname(e));let s=!1;const i=[];let l=!1;for(const e of t){const n=e,t=U(e,o,s);t.line!==n&&(l=!0),!t.line.trim()&&t.isEmpty||i.push(t.line),s=t.inMultiLineComment}const r=i.join("\n");return l||r!==n?(p.writeFileSync(e,r,"utf-8"),{success:!0,commentsFound:!0}):{success:!0,commentsFound:!1}}catch{return{success:!1,commentsFound:!1}}}function J(e){const n=e.replace(/^\/\//,"").replace(/^\/\*/,"").replace(/\*\/$/,"").trim().toLowerCase();return n.startsWith("eslint")||n.startsWith("@eslint")||n.includes("eslint-disable")||n.includes("eslint-enable")}function U(e,n,t){if(t){const t=e.indexOf(n.multiLineEnd);if(-1!==t){const o=e.substring(0,t+n.multiLineEnd.length),s=e.substring(t+n.multiLineEnd.length);return J(o)?{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length}:{line:s.trimEnd(),inMultiLineComment:!1,isEmpty:0===s.trim().length}}return J(e)?{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length}:{line:"",inMultiLineComment:!0,isEmpty:!0}}let o=0,s=!1,i=0,l=-1;const r=[];let c=-1;for(;i<e.length;){const t=e[i];if(s)s=!1,i++;else if("\\"!==t||0===o){if(3===o&&"$"===t&&i+1<e.length&&"{"===e[i+1]){let n=1;for(i+=2;i<e.length&&n>0;)"{"===e[i]?n++:"}"===e[i]&&n--,i++;continue}if(0===o){if('"'===t)o=2;else if("'"===t)o=1;else if("`"===t)o=3;else if("/"===t&&i+1<e.length){const t=e[i+1];if("/"===t||"*"===t){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){r.push(i);break}n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i),i++;continue}{const n=i>0?e[i-1]:" ";/[\s,;=([{!&|?:]/.test(n)&&(o=4,l=i)}}}else if(2===o&&'"'===t)o=0;else if(1===o&&"'"===t)o=0;else if(3===o&&"`"===t)o=0;else if(4===o){if("\\"===t){i+1<e.length?i+=2:i++;continue}if("/"===t)if(i+1<e.length){const n=e[i+1];if(/[gimsuvy]/.test(n)){let n=i+1;for(;n<e.length&&/[gimsuvy]/.test(e[n]);)n++;(n>=e.length||!/[a-zA-Z0-9_]/.test(e[n]))&&(o=0,l=-1,i=n-1)}else/[a-zA-Z0-9_]/.test(n)||(o=0,l=-1)}else o=0,l=-1;else if(" "===t||"\t"===t){const n=i-l-1;let t=!0;for(let n=l+1;n<i;n++)if(" "!==e[n]&&"\t"!==e[n]){t=!1;break}if(t&&n<=2){let n=i+1;for(;n<e.length&&(" "===e[n]||"\t"===e[n]);)n++;n<e.length&&/[0-9;,)}\]\]]/.test(e[n])&&(o=0,l=-1)}}else/[;,)}\]\]]/.test(t)&&(o=0,l=-1)}if(0===o){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){r.push(i);break}n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i)}i++}else s=!0,i++}if(-1!==c){const t=e.substring(0,c),o=e.indexOf(n.multiLineEnd,c+n.multiLineStart.length);if(-1!==o){const s=e.substring(c,o+n.multiLineEnd.length),i=e.substring(o+n.multiLineEnd.length);if(J(s))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};const l=(t+i).trimEnd();return{line:l,inMultiLineComment:!1,isEmpty:0===l.length}}{if(J(e.substring(c)))return{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length};const n=t.trimEnd();return{line:n,inMultiLineComment:!0,isEmpty:0===n.length}}}if(r.length>0){const t=r[0];for(const o of n.singleLine)if(e.substring(t).startsWith(o)){if(J(e.substring(t+o.length)))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};break}const o=e.substring(0,t).trimEnd();return{line:o,inMultiLineComment:!1,isEmpty:0===o.length}}return{line:e,inMultiLineComment:!1,isEmpty:!1}}function G(e){const n=["B","KB","MB","GB","TB"];let t=e,o=0;for(;t>=1024&&o<n.length-1;)t/=1024,o+=1;return 0===o?`${Math.floor(t)} ${n[o]}`:`${t.toFixed(2)} ${n[o]}`}function V(e){return{codeLines:e.code_lines||0,commentLines:e.comment_lines||0,fullLineComments:e.full_line_comments||0,inlineComments:e.inline_comments||0}}function K(e,n,t,o,s){let i=` (${e} code, ${n} comments`;return void 0!==s&&s>0&&(i+=`, ${s} blank`),(t>0||o>0)&&(i+=`: ${t} full-line, ${o} inline`),i+=")",i}function H(e,n,t,o,s){let i=` ${y.default.gray(`(${y.default.blue(e)} code, ${y.default.cyan(n)} comments`)}`;return void 0!==s&&s>0&&(i+=y.default.gray(`, ${y.default.gray(s)} blank`)),(t>0||o>0)&&(i+=y.default.gray(`: ${y.default.yellow(t)} full-line, ${y.default.magenta(o)} inline`)),i+=y.default.gray(")"),i}function Q(e,n){return(e.comments||e.show_stats)&&!e.files_only&&n}function Y(e,n,t){return{sizeStr:G(e),linesStr:null===n||t.files_only?"":` | ${n} lines`}}function Z(e){const n={};for(const t of e)n[t.directory]||(n[t.directory]=[]),n[t.directory].push(t);return n}function X(e){try{return p.statSync(e.directory).isFile()}catch{return!1}}function ee(e){const n=e.directory;try{if(p.statSync(n).isFile())return _.basename(n)}catch{}return"."===n?"current":n}function ne(e){return{nodejs:"Node.js",rust:"Rust",python:"Python",go:"Go",java:"Java",csharp:"C#",ruby:"Ruby",php:"PHP",swift:"Swift",kotlin:"Kotlin",dart:"Dart",typescript:"TypeScript",vue:"Vue.js",react:"React",angular:"Angular",nextjs:"Next.js",unknown:"Unknown"}[e]||e}function te(e,n){return[...e.details].sort((e,n)=>n.size-e.size).slice(0,n)}function oe(e,n){const t={};for(const n of e.details)t[n.directory]||(t[n.directory]={fileCount:0,totalSize:0,totalLines:0}),t[n.directory].fileCount+=1,t[n.directory].totalSize+=n.size,null!==n.lines&&(t[n.directory].totalLines+=n.lines);return Object.entries(t).map(([e,n])=>({directory:e,...n})).sort((e,n)=>n.fileCount-e.fileCount).slice(0,n)}function se(e,n,t){switch(e){case"human":return function(e,n){let t="";if(n.quiet)return t+=`${e.total_files} ${e.total_lines}\n`,t;t+="=".repeat(60)+"\n",t+="LocIO RESULTS".padStart(37).padEnd(60)+"\n",t+="=".repeat(60)+"\n\n",t+=`Directory: ${ee(n)}\n`,n.lines_only||(X(n)?t+=`\nSize: ${G(e.total_size)}\n`:(t+=`\nTotal Files: ${e.total_files}\n`,t+=`\nTotal Files Size: ${G(e.total_size)}\n`)),!n.files_only&&(t+=`\nTotal Lines: ${e.total_lines}\n`,(n.comments||n.show_stats)&&void 0!==e.total_comment_lines&&(t+=`Total Comment Lines: ${e.total_comment_lines}\n`,void 0!==e.total_full_line_comments&&(t+=` - Full Line Comments: ${e.total_full_line_comments}\n`),void 0!==e.total_inline_comments&&(t+=` - Inline Comments: ${e.total_inline_comments}\n`),void 0!==e.total_code_lines&&(t+=`Total Code Lines: ${e.total_code_lines}\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(t+=`Total Blank Lines: ${e.total_blank_lines}\n`),n.code_vs_comments&&void 0!==e.total_code_lines))&&(t+=`Code vs Comments Ratio: ${e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00"}:1 (${e.total_comment_lines} comments per ${e.total_code_lines} code lines)\n`);Object.keys(e.files_by_extension).length>0&&(t+=`\nExtensions: ${Object.keys(e.files_by_extension).sort().join(", ")}\n`);if(n.show_stats&&Object.keys(e.files_by_extension).length>0){const o=Object.keys(e.files_by_extension).sort();t+="\nStatistics by Extension:\n",t+="-".repeat(60)+"\n";for(const s of o){const o=e.files_by_extension[s],i=e.size_by_extension[s]||0,l=e.lines_by_extension[s]||0;if(t+=` ${s}: ${o} files`,n.lines_only||(t+=`, ${G(i)}`),!n.files_only&&(t+=`, ${l} lines`,Q(n,void 0!==e.comment_lines_by_extension?.[s]))){const o=V({comment_lines:e.comment_lines_by_extension?.[s]||0,code_lines:e.code_lines_by_extension?.[s]||0,full_line_comments:e.full_line_comments_by_extension?.[s]||0,inline_comments:e.inline_comments_by_extension?.[s]||0}),i=e.blank_lines_by_extension?.[s]||0;t+=K(o.codeLines,o.commentLines,o.fullLineComments,o.inlineComments,i),n.code_vs_comments&&o.codeLines>0&&(t+=` [${(o.commentLines/o.codeLines).toFixed(2)}:1]`)}t+="\n"}}if(n.show_stats&&e.details.length>0){t+="\nFiles by Directory:\n",t+="-".repeat(60)+"\n";const o=Z(e.details),s=Object.keys(o).sort();for(const e of s){const s=o[e];t+=`Directory: ${e}\n`;for(const e of s){const o=G(e.size),s=null===e.lines||n.files_only?"":` | ${e.lines} lines`;let i="";if(Q(n,void 0!==e.comment_lines&&null!==e.comment_lines)){const n=V(e);i=K(n.codeLines,n.commentLines,n.fullLineComments,n.inlineComments,e.blank_lines||void 0)}t+=` - ${e.name} (${e.extension}, ${o}${s}${i})\n`}t+="\n"}}if(n.top_files&&n.top_files>0){const o=te(e,n.top_files);t+=`\nTop ${n.top_files} Largest Files:\n`,t+="-".repeat(60)+"\n";for(const e of o){const{sizeStr:o,linesStr:s}=Y(e.size,e.lines,n);t+=` ${o.padEnd(10)} ${e.name} (${e.extension})${s}\n`}}if(n.top_dirs&&n.top_dirs>0){const o=oe(e,n.top_dirs);t+=`\nTop ${n.top_dirs} Directories (by file count):\n`,t+="-".repeat(60)+"\n";for(const e of o){const o=G(e.totalSize),s=n.files_only?"":` | ${e.totalLines} lines`;t+=` ${e.fileCount.toString().padEnd(5)} files ${e.directory} (${o}${s})\n`}}return t+="\n",t}(n,t);case"json":return function(e,n){const t=W(n.directory),o={directory:ee(n)};if("unknown"!==t&&(o.project_type=t,o.project_type_display=ne(t)),X(n)||(o.files=e.total_files,o.size=e.total_size,o.size_formatted=G(e.total_size)),n.files_only||(o.lines=e.total_lines,n.comments&&(o.comment_lines=e.total_comment_lines||0,o.code_lines=e.total_code_lines||0,o.blank_lines=e.total_blank_lines||0,o.full_line_comments=e.total_full_line_comments||0,o.inline_comments=e.total_inline_comments||0,n.code_vs_comments&&void 0!==e.total_code_lines&&(o.code_vs_comments_ratio=e.total_code_lines>0?parseFloat((e.total_comment_lines/e.total_code_lines).toFixed(2)):0))),n.show_stats){const t={};for(const o of Object.keys(e.files_by_extension))t[o]={files:e.files_by_extension[o],lines:e.lines_by_extension[o]||0,size:e.size_by_extension[o]||0},n.comments&&(t[o].comment_lines=e.comment_lines_by_extension?.[o]||0,t[o].code_lines=e.code_lines_by_extension?.[o]||0,t[o].blank_lines=e.blank_lines_by_extension?.[o]||0,t[o].full_line_comments=e.full_line_comments_by_extension?.[o]||0,t[o].inline_comments=e.inline_comments_by_extension?.[o]||0,n.code_vs_comments&&e.code_lines_by_extension?.[o]&&e.code_lines_by_extension[o]>0&&(t[o].code_vs_comments_ratio=parseFloat(((e.comment_lines_by_extension[o]||0)/e.code_lines_by_extension[o]).toFixed(2))));o.by_extension=t}if(n.top_files&&n.top_files>0){const t=te(e,n.top_files);o.top_files=t.map(e=>({name:e.name,directory:e.directory,extension:e.extension,size:e.size,size_formatted:G(e.size),lines:e.lines}))}if(n.top_dirs&&n.top_dirs>0){const t=oe(e,n.top_dirs);o.top_directories=t.map(e=>({directory:e.directory,file_count:e.fileCount,total_size:e.totalSize,total_size_formatted:G(e.totalSize),total_lines:e.totalLines}))}return JSON.stringify(o,null,2)}(n,t);case"csv":return function(e,n){const t=W(n.directory);let o=`# Directory,${ee(n)}\n`;if("unknown"!==t&&(o+=`# Project Type,${ne(t)}\n`),n.comments){o+="Extension,Files,Lines,Code Lines,Comment Lines,Blank Lines,Size",n.code_vs_comments&&(o+=",Code vs Comments Ratio"),o+="\n";for(const t of Object.keys(e.files_by_extension)){const s=e.files_by_extension[t],i=e.lines_by_extension[t]||0,l=e.code_lines_by_extension?.[t]||0,r=e.comment_lines_by_extension?.[t]||0;o+=`${t},${s},${i},${l},${r},${e.blank_lines_by_extension?.[t]||0},${e.size_by_extension[t]||0}`,n.code_vs_comments&&l>0&&(o+=`,${((r||0)/l).toFixed(2)}`),o+="\n"}}else{o+="Extension,Files,Lines,Size\n";for(const n of Object.keys(e.files_by_extension))o+=`${n},${e.files_by_extension[n]},${e.lines_by_extension[n]||0},${e.size_by_extension[n]||0}\n`}return o}(n,t);case"tsv":return function(e,n){const t=W(n.directory);let o=`# Directory\t${ee(n)}\n`;if("unknown"!==t&&(o+=`# Project Type\t${ne(t)}\n`),n.comments){o+="Extension\tFiles\tLines\tCode Lines\tComment Lines\tBlank Lines\tSize",n.code_vs_comments&&(o+="\tCode vs Comments Ratio"),o+="\n";for(const t of Object.keys(e.files_by_extension)){const s=e.files_by_extension[t],i=e.lines_by_extension[t]||0,l=e.code_lines_by_extension?.[t]||0,r=e.comment_lines_by_extension?.[t]||0;o+=`${t}\t${s}\t${i}\t${l}\t${r}\t${e.blank_lines_by_extension?.[t]||0}\t${e.size_by_extension[t]||0}`,n.code_vs_comments&&l>0&&(o+=`\t${((r||0)/l).toFixed(2)}`),o+="\n"}}else{o+="Extension\tFiles\tLines\tSize\n";for(const n of Object.keys(e.files_by_extension))o+=`${n}\t${e.files_by_extension[n]}\t${e.lines_by_extension[n]||0}\t${e.size_by_extension[n]||0}\n`}return o}(n,t);case"markdown":return function(e,n){const t=W(n.directory);let o="# LocIO Report\n\n";o+=`**Directory:** ${ee(n)}\n`,"unknown"!==t&&(o+=`**Project Type:** ${ne(t)}\n`),o+="\n",o+="## Summary\n\n",o+="| Metric | Value |\n",o+="|--------|-------|\n",o+=`| Total Files | ${e.total_files} |\n`,o+=`| Total Size | ${G(e.total_size)} |\n`,!n.files_only&&(o+=`| Total Lines | ${e.total_lines} |\n`,n.comments&&void 0!==e.total_comment_lines&&(o+=`| Comment Lines | ${e.total_comment_lines} |\n`,void 0!==e.total_code_lines&&(o+=`| Code Lines | ${e.total_code_lines} |\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(o+=`| Blank Lines | ${e.total_blank_lines} |\n`),n.code_vs_comments&&void 0!==e.total_code_lines&&e.total_code_lines>0))&&(o+=`| Code vs Comments Ratio | ${(e.total_comment_lines/e.total_code_lines).toFixed(2)}:1 |\n`);if(Object.keys(e.files_by_extension).length>0){o+="\n## Statistics by Extension\n\n",o+="| Extension | Files |",n.lines_only||(o+=" Size |"),n.files_only||(o+=" Lines |",n.comments&&(o+=" Code | Comments |",n.code_vs_comments&&(o+=" Ratio |"))),o+="\n",o+="|----------|-------|",n.lines_only||(o+="------|"),n.files_only||(o+="-------|",n.comments&&(o+="------|-----------|",n.code_vs_comments&&(o+="-------|"))),o+="\n";const t=Object.keys(e.files_by_extension).sort();for(const s of t){const t=e.files_by_extension[s],i=e.size_by_extension[s]||0,l=e.lines_by_extension[s]||0,r=e.code_lines_by_extension?.[s]||0,c=e.comment_lines_by_extension?.[s]||0;o+=`| \`${s}\` | ${t} |`,n.lines_only||(o+=` ${G(i)} |`),!n.files_only&&(o+=` ${l} |`,n.comments)&&(o+=` ${r} | ${c} |`,n.code_vs_comments&&r>0?o+=` ${((c||0)/r).toFixed(2)}:1 |`:n.code_vs_comments&&(o+=" - |")),o+="\n"}}if(n.show_stats&&e.details.length>0){o+="\n## Files by Directory\n\n";const t=Z(e.details),s=Object.keys(t).sort();for(const e of s){const s=t[e];o+=`### ${e}\n\n`,o+="| File | Extension | Size |",n.files_only||(o+=" Lines |",(n.comments||n.show_stats)&&(o+=" Code | Comments | Blank | Full-Line | Inline |")),o+="\n",o+="|------|-----------|------|",n.files_only||(o+="-------|",(n.comments||n.show_stats)&&(o+="------|----------|-------|----------|--------|")),o+="\n";for(const e of s)o+=`| ${e.name} | \`${e.extension}\` | ${G(e.size)} |`,!n.files_only&&null!==e.lines&&(o+=` ${e.lines} |`,n.comments||n.show_stats)&&(o+=` ${e.code_lines||0} | ${e.comment_lines||0} | ${e.blank_lines||0} | ${e.full_line_comments||0} | ${e.inline_comments||0} |`),o+="\n";o+="\n"}}if(n.top_files&&n.top_files>0){const t=te(e,n.top_files);o+=`\n## Top ${n.top_files} Largest Files\n\n`,o+="| Size | File | Extension |",n.files_only||(o+=" Lines |"),o+="\n",o+="|------|------|-----------|",n.files_only||(o+="-------|"),o+="\n";for(const e of t)o+=`| ${G(e.size)} | ${e.name} | \`${e.extension}\` |`,n.files_only||null===e.lines||(o+=` ${e.lines} |`),o+="\n";o+="\n"}if(n.top_dirs&&n.top_dirs>0){const t=oe(e,n.top_dirs);o+=`\n## Top ${n.top_dirs} Directories (by file count)\n\n`,o+="| Files | Directory | Size |",n.files_only||(o+=" Lines |"),o+="\n",o+="|-------|-----------|------|",n.files_only||(o+="-------|"),o+="\n";for(const e of t)o+=`| ${e.fileCount} | ${e.directory} | ${G(e.totalSize)} |`,n.files_only||(o+=` ${e.totalLines} |`),o+="\n";o+="\n"}return o+="\n---\n\n",o+="*Generated by [LocIO](https://locio.js.org)*\n",o}(n,t);case"html":return function(e,n){const t=W(n.directory),o=Object.keys(e.files_by_extension).sort(),s=o.map(n=>({ext:n,files:e.files_by_extension[n],lines:e.lines_by_extension[n]||0,size:e.size_by_extension[n]||0,codeLines:e.code_lines_by_extension?.[n]||0,commentLines:e.comment_lines_by_extension?.[n]||0,blankLines:e.blank_lines_by_extension?.[n]||0}));return`<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>LocIO Report - ${ee(n)}</title>\n <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"><\/script>\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh;\n padding: 20px;\n }\n .container {\n max-width: 1200px;\n margin: 0 auto;\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n overflow: hidden;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 40px;\n text-align: center;\n }\n .header h1 {\n font-size: 2.5em;\n margin-bottom: 10px;\n }\n .header p {\n opacity: 0.9;\n font-size: 1.1em;\n }\n .content {\n padding: 40px;\n }\n .summary-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 20px;\n margin-bottom: 40px;\n }\n .card {\n background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n padding: 25px;\n border-radius: 10px;\n text-align: center;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n }\n .card h3 {\n color: #667eea;\n font-size: 0.9em;\n text-transform: uppercase;\n letter-spacing: 1px;\n margin-bottom: 10px;\n }\n .card .value {\n font-size: 2.5em;\n font-weight: bold;\n color: #2d3748;\n }\n .section {\n margin-bottom: 40px;\n }\n .section h2 {\n color: #2d3748;\n margin-bottom: 20px;\n padding-bottom: 10px;\n border-bottom: 3px solid #667eea;\n }\n .chart-container {\n position: relative;\n height: 400px;\n margin: 20px 0;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n margin-top: 20px;\n background: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n th {\n background: #667eea;\n color: white;\n padding: 15px;\n text-align: left;\n font-weight: 600;\n }\n td {\n padding: 12px 15px;\n border-bottom: 1px solid #e2e8f0;\n }\n tr:hover {\n background: #f7fafc;\n }\n .footer {\n text-align: center;\n padding: 20px;\n color: #718096;\n border-top: 1px solid #e2e8f0;\n }\n .footer a {\n color: #667eea;\n text-decoration: none;\n }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="header">\n <h1>LocIO Report</h1>\n <p>Directory: ${ee(n)}</p>\n ${"unknown"!==t?`<p>Project Type: <strong>${ne(t)}</strong></p>`:""}\n </div>\n <div class="content">\n <div class="summary-cards">\n <div class="card">\n <h3>Total Files</h3>\n <div class="value">${e.total_files}</div>\n </div>\n <div class="card">\n <h3>Total Size</h3>\n <div class="value">${G(e.total_size)}</div>\n </div>\n ${n.files_only?"":`<div class="card">\n <h3>Total Lines</h3>\n <div class="value">${e.total_lines}</div>\n </div>`}\n ${n.comments&&void 0!==e.total_comment_lines?`<div class="card">\n <h3>Comment Lines</h3>\n <div class="value">${e.total_comment_lines}</div>\n </div>\n <div class="card">\n <h3>Code Lines</h3>\n <div class="value">${e.total_code_lines||0}</div>\n </div>\n ${void 0!==e.total_blank_lines&&e.total_blank_lines>0?`<div class="card">\n <h3>Blank Lines</h3>\n <div class="value">${e.total_blank_lines}</div>\n </div>`:""}`:""}\n </div>\n\n ${o.length>0?`<div class="section">\n <h2>π Statistics by Extension</h2>\n <div class="chart-container">\n <canvas id="extensionChart"></canvas>\n </div>\n <table>\n <thead>\n <tr>\n <th>Extension</th>\n <th>Files</th>\n ${n.lines_only?"":"<th>Size</th>"}\n ${n.files_only?"":"<th>Lines</th>"}\n ${n.comments?"<th>Code</th><th>Comments</th><th>Blank</th>":""}\n </tr>\n </thead>\n <tbody>\n ${s.map(e=>`<tr>\n <td><strong>${e.ext}</strong></td>\n <td>${e.files}</td>\n ${n.lines_only?"":`<td>${G(e.size)}</td>`}\n ${n.files_only?"":`<td>${e.lines}</td>`}\n ${n.comments?`<td>${e.codeLines}</td><td>${e.commentLines}</td><td>${e.blankLines}</td>`:""}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`:""}\n\n ${n.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?'<div class="section">\n <h2>π¬ Code vs Comments</h2>\n <div class="chart-container">\n <canvas id="commentChart"></canvas>\n </div>\n </div>':""}\n\n ${n.top_files&&n.top_files>0?(()=>{const t=te(e,n.top_files);return`<div class="section">\n <h2>π Top ${n.top_files} Largest Files</h2>\n <table>\n <thead>\n <tr>\n <th>Size</th>\n <th>File</th>\n <th>Extension</th>\n ${n.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${t.map(e=>`<tr>\n <td><strong>${G(e.size)}</strong></td>\n <td>${e.name}</td>\n <td><code>${e.extension}</code></td>\n ${n.files_only||null===e.lines?"":`<td>${e.lines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${n.top_dirs&&n.top_dirs>0?(()=>{const t=oe(e,n.top_dirs);return`<div class="section">\n <h2>π Top ${n.top_dirs} Directories (by file count)</h2>\n <table>\n <thead>\n <tr>\n <th>Files</th>\n <th>Directory</th>\n <th>Size</th>\n ${n.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${t.map(e=>`<tr>\n <td><strong>${e.fileCount}</strong></td>\n <td>${e.directory}</td>\n <td>${G(e.totalSize)}</td>\n ${n.files_only?"":`<td>${e.totalLines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${"html"===n.export?(()=>{const t={};for(const n of e.details)t[n.directory]||(t[n.directory]={fileCount:0,totalSize:0,totalLines:0}),t[n.directory].fileCount+=1,t[n.directory].totalSize+=n.size,null!==n.lines&&(t[n.directory].totalLines+=n.lines);const o=Object.entries(t),s=Math.max(...o.map(([,e])=>e.fileCount)),i=Math.max(...o.map(([,e])=>e.totalSize));return`<div class="section">\n <h2>πΊοΈ Directory Heatmap</h2>\n <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; margin-top: 20px;">\n ${o.map(([e,t])=>{const o=(t.fileCount/s*100+t.totalSize/i*100)/2,l=240-1.2*o;return`<div style="\n background: linear-gradient(135deg, hsl(${l}, 70%, ${85-.3*o}%), hsl(${l}, 70%, ${75-.3*o}%));\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n color: ${o>50?"white":"#2d3748"};\n ">\n <div style="font-weight: bold; margin-bottom: 8px; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="${e}">${e.split("/").pop()||e}</div>\n <div style="font-size: 0.8em; opacity: 0.9;">\n <div>π ${t.fileCount} files</div>\n <div>πΎ ${G(t.totalSize)}</div>\n ${n.files_only?"":`<div>π ${t.totalLines} lines</div>`}\n </div>\n </div>`}).join("")}\n </div>\n </div>`})():""}\n </div>\n <div class="footer">\n Generated by <a href="https://locio.js.org">LocIO</a>\n </div>\n </div>\n\n <script>\n ${o.length>0?`const extensionCtx = document.getElementById('extensionChart');\n new Chart(extensionCtx, {\n type: 'bar',\n data: {\n labels: ${JSON.stringify(o)},\n datasets: [\n ${n.files_only?"":`{\n label: 'Lines',\n data: ${JSON.stringify(o.map(n=>e.lines_by_extension[n]||0))},\n backgroundColor: 'rgba(102, 126, 234, 0.8)',\n borderColor: 'rgba(102, 126, 234, 1)',\n borderWidth: 2\n },`}\n {\n label: 'Files',\n data: ${JSON.stringify(o.map(n=>e.files_by_extension[n]))},\n backgroundColor: 'rgba(118, 75, 162, 0.8)',\n borderColor: 'rgba(118, 75, 162, 1)',\n borderWidth: 2\n }\n ]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'top',\n },\n title: {\n display: true,\n text: 'Files and Lines by Extension'\n }\n }\n }\n });`:""}\n\n ${n.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?`const commentCtx = document.getElementById('commentChart');\n new Chart(commentCtx, {\n type: 'doughnut',\n data: {\n labels: ['Code Lines', 'Comment Lines'],\n datasets: [{\n data: [${e.total_code_lines}, ${e.total_comment_lines||0}],\n backgroundColor: [\n 'rgba(102, 126, 234, 0.8)',\n 'rgba(118, 75, 162, 0.8)'\n ],\n borderColor: [\n 'rgba(102, 126, 234, 1)',\n 'rgba(118, 75, 162, 1)'\n ],\n borderWidth: 2\n }]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'bottom',\n },\n title: {\n display: true,\n text: 'Code vs Comments Distribution'\n }\n }\n }\n });`:""}\n <\/script>\n</body>\n</html>`}(n,t)}}function ie(e,n,t){const o=function(e){switch(e){case"human":return"txt";case"json":return"json";case"csv":return"csv";case"tsv":return"tsv";case"markdown":return"md";case"html":return"html"}}(e);let s;return s=Array.isArray(n.export)&&n.export.length>1&&void 0!==t?`LocIO-report-${t+1}.${o}`:`LocIO-report.${o}`,n.export_path?_.join(n.export_path,s):s}function le(e,n){void 0===n.export?function(e,n){if(n.quiet)console.log(`${e.total_files} ${e.total_lines}`);else{if(console.log("\n"+y.default.cyan("=".repeat(60))),console.log(y.default.cyan.bold("LocIO RESULTS".padStart(37).padEnd(60))),console.log(y.default.cyan("=".repeat(60))),console.log(`\n${y.default.green.bold("Directory:")} ${ee(n)}`),n.lines_only||(X(n)?console.log(`\n${y.default.green.bold("Size:")} ${y.default.white(G(e.total_size))}`):(console.log(`\n${y.default.green.bold("Total Files:")} ${y.default.yellow(e.total_files)}`),console.log(`\n${y.default.green.bold("Total Files Size:")} ${y.default.white(G(e.total_size))}`))),!n.files_only&&(console.log(`\n${y.default.green.bold("Total Lines:")} ${y.default.yellow(e.total_lines)}`),(n.comments||n.show_stats)&&void 0!==e.total_comment_lines&&(console.log(`\n${y.default.green.bold("Total Comment Lines:")} ${y.default.cyan(e.total_comment_lines)}`),void 0!==e.total_full_line_comments&&console.log(` ${y.default.gray("β")} ${y.default.green("Full Line Comments:")} ${y.default.cyan(e.total_full_line_comments)}`),void 0!==e.total_inline_comments&&console.log(` ${y.default.gray("β")} ${y.default.green("Inline Comments:")} ${y.default.cyan(e.total_inline_comments)}`),void 0!==e.total_code_lines&&console.log(`\n${y.default.green.bold("Total Code Lines:")} ${y.default.blue(e.total_code_lines)}`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&console.log(`\n${y.default.green.bold("Total Blank Lines:")} ${y.default.gray(e.total_blank_lines)}`),n.code_vs_comments&&void 0!==e.total_code_lines))){const n=e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00";console.log(`\n${y.default.green.bold("Code vs Comments Ratio:")} ${y.default.magenta(n)}:1 ${y.default.gray(`(${e.total_comment_lines} comments per ${e.total_code_lines} code lines)`)}`)}if(Object.keys(e.files_by_extension).length>0){const n=Object.keys(e.files_by_extension).sort();console.log(`\n${y.default.green.bold("Extensions:")} ${y.default.white(n.join(", "))}`)}if(n.show_stats&&Object.keys(e.files_by_extension).length>0){console.log(`\n${y.default.cyan.bold("Statistics by Extension:")}`),console.log(y.default.gray("-".repeat(60)));const t=Object.keys(e.files_by_extension).sort();for(const o of t){const t=e.files_by_extension[o],s=e.size_by_extension[o]||0,i=e.lines_by_extension[o]||0;let l=` ${y.default.white(o)}: ${y.default.yellow(t)} files`;if(n.lines_only||(l+=`, ${y.default.white(G(s))}`),!n.files_only&&(l+=`, ${y.default.yellow(i)} lines`,Q(n,void 0!==e.comment_lines_by_extension?.[o]))){const t=V({comment_lines:e.comment_lines_by_extension?.[o]||0,code_lines:e.code_lines_by_extension?.[o]||0,full_line_comments:e.full_line_comments_by_extension?.[o]||0,inline_comments:e.inline_comments_by_extension?.[o]||0}),s=e.blank_lines_by_extension?.[o]||0;if(l+=H(t.codeLines,t.commentLines,t.fullLineComments,t.inlineComments,s),n.code_vs_comments&&t.codeLines>0){const e=(t.commentLines/t.codeLines).toFixed(2);l+=` ${y.default.magenta(`[${e}:1]`)}`}}console.log(l)}}if(n.show_stats&&e.details.length>0){console.log(`\n${y.default.cyan.bold("Files by Directory:")}`),console.log(y.default.gray("-".repeat(60)));const t=Z(e.details),o=Object.keys(t).sort();for(const e of o){const o=t[e];console.log(y.default.green.bold(`Directory: ${e}`));for(const e of o){const t=G(e.size),o=null===e.lines||n.files_only?"":` | ${e.lines} lines`;let s="";if(Q(n,void 0!==e.comment_lines&&null!==e.comment_lines)){const n=V(e);s=H(n.codeLines,n.commentLines,n.fullLineComments,n.inlineComments,e.blank_lines||void 0)}console.log(` - ${y.default.white(e.name)} (${y.default.blue(e.extension)}, ${y.default.white(t)}${o}${s})`)}console.log()}}if(n.top_files&&n.top_files>0){const t=te(e,n.top_files);console.log(`\n${y.default.cyan.bold(`Top ${n.top_files} Largest Files:`)}`),console.log(y.default.gray("-".repeat(60)));for(const e of t){const{sizeStr:t,linesStr:o}=Y(e.size,e.lines,n);console.log(` ${y.default.yellow(t.padEnd(10))} ${y.default.white(e.name)} ${y.default.blue(`(${e.extension})`)}${o}`)}}if(n.top_dirs&&n.top_dirs>0){const t=oe(e,n.top_dirs);console.log(`\n${y.default.cyan.bold(`Top ${n.top_dirs} Directories (by file count):`)}`),console.log(y.default.gray("-".repeat(60)));for(const e of t){const t=G(e.totalSize),o=n.files_only?"":` | ${e.totalLines} lines`;console.log(` ${y.default.yellow(e.fileCount.toString().padEnd(5))} files ${y.default.white(e.directory)} ${y.default.gray(`(${t}${o})`)}`)}}console.log()}}(e,n):function(e,n){const t=Array.isArray(n.export)?n.export:[n.export||"human"];for(let o=0;o<t.length;o++){const s=t[o],i=se(s,e,n),l=ie(s,n,o);try{let e;e=n.export_path?n.export_path:_.dirname(l),"."!==e&&e!==l&&p.mkdirSync(e,{recursive:!0}),p.writeFileSync(l,i,"utf-8"),n.quiet||console.log(`Report written to ${l}`)}catch(e){const n=(e instanceof Error?e:new Error(String(e))).message||String(e);let t="";t=n.includes("ENOENT")?`The directory for "${l}" does not exist.\n - Ensure the parent directory exists\n - Check if the path is correct`:n.includes("EACCES")||n.includes("permission")?`Permission denied when writing to "${l}".\n - Check write permissions for the directory\n - Try running with appropriate permissions\n - Use a different output directory`:n.includes("ENOSPC")?"Insufficient disk space.\n - Free up disk space\n - Choose a different location":"Check if the path is valid and you have write permissions.",console.error(`\nβ Failed to create report file ${l}`),console.error(`π Error: ${n}`),t&&console.error(`\nπ‘ Suggestion:\n${t}`)}}}(e,n)}function re(e){const n=e.trim().toUpperCase();let t,o;n.endsWith("KB")?(t=n.slice(0,-2),o=1024):n.endsWith("MB")?(t=n.slice(0,-2),o=1048576):n.endsWith("GB")?(t=n.slice(0,-2),o=1073741824):n.endsWith("B")&&n.length>1?(t=n.slice(0,-1),o=1):(t=n,o=1);const s=parseFloat(t);return isNaN(s)?L.invalidSizeFormat(e):Math.floor(s*o)}var ce=["jpg","jpeg","png","gif","bmp","svg","ico","webp","tiff","tif","psd","raw","heic","heif","avif","mp3","wav","flac","aac","ogg","wma","m4a","opus","aiff","au","mp4","avi","mkv","mov","wmv","flv","webm","m4v","mpg","mpeg","3gp","ogv","zip","rar","7z","tar","gz","bz2","xz","z","cab","iso","dmg","pkg","deb","rpm","pdf","doc","docx","xls","xlsx","ppt","pptx","odt","ods","odp","exe","dll","so","dylib","app","msi","bin","run","ttf","otf","woff","woff2","eot","db","sqlite","sqlite3","mdb","accdb","ps","eps","ai","sketch","fig","xd"],ae=["md","markdown","txt","rst","adoc","asciidoc","org","wiki","json","yaml","yml","toml","ini","cfg","conf","config","properties","env","dotenv","csv","tsv","xml","html","htm","xhtml","log","lock","lockfile"];function de(e){try{if(e.max_size){const n=re(e.max_size);if(n instanceof L)return n}if(e.min_size){const n=re(e.min_size);if(n instanceof L)return n}const n=W(e.directory),t=T[n]||T.unknown,o=e.exclude_patterns.map(n=>{try{return new RegExp(n,e.ignore_case?"i":void 0)}catch(e){throw L.invalidRegex(n,e instanceof Error?e:void 0)}}),s=[...e.exclude_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),...t.exclude_extensions.map(e=>e.toLowerCase()),...ce.map(e=>e.toLowerCase())],i=Array.from(new Set(s)).sort(),l=e.include_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),r=[...e.exclude_dirs,...t.exclude_dirs].map(n=>new RegExp(n,e.ignore_case?"i":void 0)),c=e.include_dirs.map(n=>new RegExp(n,e.ignore_case?"i":void 0)),a=[...e.exclude_names,...t.exclude_names].map(n=>new RegExp(n,e.ignore_case?"i":void 0));return{exclude_patterns:o,exclude_extensions:i,include_extensions:l,exclude_dirs:r,include_dirs:c,exclude_names:a,include_names:e.include_names.map(n=>new RegExp(n,e.ignore_case?"i":void 0)),detected_project_type:n}}catch(e){return e instanceof L?e:L.io(`Failed to create filter patterns: ${e instanceof Error?e.message:String(e)}`)}}function ue(e,n,t){const o=e,s=_.basename(e);for(const e of t.exclude_patterns)if(e.test(o))return!0;const i=_.extname(e).replace(/^\./,"").toLowerCase();if(i){for(const e of t.exclude_extensions)if(i===e.toLowerCase())return!0;if(t.include_extensions.length>0){let e=!1;for(const n of t.include_extensions)if(i===n.toLowerCase()){e=!0;break}if(!e)return!0}}else if(t.include_extensions.length>0)return!0;const l=_.dirname(e);for(const e of t.exclude_dirs)if(e.test(l))return!0;if(t.include_dirs.length>0){let e=!1;for(const n of t.include_dirs)if(n.test(l)){e=!0;break}if(!e)return!0}for(const e of t.exclude_names)if(e.test(s))return!0;if(t.include_names.length>0){let e=!1;for(const n of t.include_names)if(n.test(s)){e=!0;break}if(!e)return!0}if(n.no_hidden&&s.startsWith("."))return!0;try{const t=p.statSync(e).size;if(n.max_size){const e=re(n.max_size);if(!(e instanceof L)&&t>e)return!0}if(n.min_size){const e=re(n.min_size);if(!(e instanceof L)&&t<e)return!0}if(n.no_empty&&0===t)return!0}catch{}return!(!n.no_binary||!function(e){try{const n=Buffer.alloc(8192),t=p.openSync(e,"r"),o=p.readSync(t,n,0,8192,0);if(p.closeSync(t),0===o)return!1;for(let e=0;e<o;e++)if(0===n[e])return!0;return!1}catch{return!1}}(e))}function me(e){return _.extname(e).replace(/^\./,"").toLowerCase()||"no-ext"}function fe(e){const n=null!==e.commentLines,t=null!==e.codeLines&&null!==e.blankLines;return n||t?{totalLines:e.lines||0,commentLines:e.commentLines||0,codeLines:e.codeLines||0,fullLineComments:e.fullLineComments||0,inlineComments:e.inlineComments||0,blankLines:e.blankLines||0}:null}function pe(e,n,t,o,s){if(e.total_files+=1,e.total_size+=t,e.files_by_extension[n]=(e.files_by_extension[n]||0)+1,e.size_by_extension[n]=(e.size_by_extension[n]||0)+t,null!==o&&(e.total_lines+=o,e.lines_by_extension[n]=(e.lines_by_extension[n]||0)+o),s){const t=s.codeLines+s.commentLines+s.blankLines;s.totalLines!==t&&(s.totalLines=t),e.total_comment_lines=(e.total_comment_lines||0)+s.commentLines,e.total_code_lines=(e.total_code_lines||0)+s.codeLines,e.total_blank_lines=(e.total_blank_lines||0)+s.blankLines,e.total_full_line_comments=(e.total_full_line_comments||0)+s.fullLineComments,e.total_inline_comments=(e.total_inline_comments||0)+s.inlineComments,e.comment_lines_by_extension[n]=(e.comment_lines_by_extension[n]||0)+s.commentLines,e.code_lines_by_extension[n]=(e.code_lines_by_extension[n]||0)+s.codeLines,e.blank_lines_by_extension||(e.blank_lines_by_extension={}),e.blank_lines_by_extension[n]=(e.blank_lines_by_extension[n]||0)+s.blankLines,e.full_line_comments_by_extension[n]=(e.full_line_comments_by_extension[n]||0)+s.fullLineComments,e.inline_comments_by_extension[n]=(e.inline_comments_by_extension[n]||0)+s.inlineComments}}function _e(e,n){const t=_.extname(e).replace(/^\./,"").toLowerCase(),o=ae.map(e=>e.toLowerCase()).includes(t);if(n.comments){if(!o){const n=function(e){try{const n=p.readFileSync(e,"utf-8").split(/\r?\n/),t=A(_.extname(e));let o=n.length,s=0,i=0,l=0,r=0,c=0,a=!1;for(const e of n){if(0===e.trim().length){a?(i++,l++):c++;continue}const n=P(e,t,a);n?(n.isMultiLine&&(a=!n.endsMultiLine),n.hasCodeBefore?(r++,s++,n.hasCodeAfter):(l++,n.hasCodeAfter&&s++),i++):a?(i++,l++):s++}return{totalLines:o,codeLines:s,commentLines:i,fullLineComments:l,inlineComments:r,blankLines:c}}catch{return null}}(e);if(n)return{lines:n.totalLines,commentLines:n.commentLines,codeLines:n.codeLines,fullLineComments:n.fullLineComments,inlineComments:n.inlineComments,blankLines:n.blankLines,error:null}}const n=function(e){try{const n=p.readFileSync(e,"utf-8").split(/\r?\n/);let t=0,o=0;for(const e of n)0===e.trim().length?t++:o++;return{total:n.length,blank:t,code:o}}catch(n){return L.io(`Failed to read file: ${e}`,n instanceof Error?n:void 0)}}(e);return w(n)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:n}:{lines:n.total,commentLines:0,codeLines:n.code,fullLineComments:0,inlineComments:0,blankLines:n.blank,error:null}}const s=function(e){try{return p.readFileSync(e,"utf-8").split(/\r?\n/).length}catch(n){return L.io(`Failed to read file: ${e}`,n instanceof Error?n:void 0)}}(e);return w(s)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:s}:{lines:s,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}function ye(e,n,t,o,s,i,l,r,c){return{directory:_.dirname(e),name:_.basename(e),extension:t,size:n,lines:o,comment_lines:s,code_lines:i,blank_lines:c,full_line_comments:l,inline_comments:r}}function he(e){try{return{metadata:p.statSync(e),error:null}}catch(e){return{metadata:null,error:e instanceof Error?e:new Error(String(e))}}}function ge(e,n,t){return _.relative(n,e).split(_.sep).length-1>t}var xe=class{constructor(e){b(this,"total"),b(this,"current",0),b(this,"startTime"),b(this,"width",40),b(this,"errors",0),this.total=e,this.startTime=Date.now()}update(e,n=0){this.current=e,this.errors=n,this.render()}increment(e=0){this.current++,e>0&&(this.errors=e),this.render()}formatTime(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;return`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3)}s`}calculateETA(){if(0===this.current)return"calculating...";const e=Date.now()-this.startTime,n=this.current/e,t=(this.total-this.current)/n;return t<0||!isFinite(t)?"calculating...":this.formatTime(t)}render(){const e=this.total>0?this.current/this.total*100:0,n=e.toFixed(1).padStart(5),t=String(this.current).padStart(String(this.total).length),o=this.errors>0?y.default.red(` (${this.errors} errors)`):"",s=Date.now()-this.startTime,i=this.formatTime(s),l=this.calculateETA();if(!process.stderr.isTTY)return void(this.current%100!=0&&this.current!==this.total||process.stderr.write(`\rProcessed: ${t}/${this.total} (${n}%) | ${i} elapsed | ETA: ${l}${o}`));const r=Math.round(e/100*this.width),c=this.width-r,a=`\r${y.default.green("β".repeat(r))+y.default.gray("β".repeat(c))} ${n}% | ${t}/${this.total} files | ${i} elapsed | ETA: ${l}${o}`;process.stderr.write("[K"+a)}finish(){const e=Date.now()-this.startTime,n=this.formatTime(e),t=this.errors>0?y.default.red(` (${this.errors} errors)`):"";if(process.stderr.isTTY){const e=100,o=y.default.green("β".repeat(this.width)),s=String(this.current).padStart(String(this.total).length);process.stderr.write(`\r${o} ${e.toFixed(1).padStart(5)}% | ${s}/${this.total} files | ${n}${t}\n`)}else process.stderr.write(`\rProcessed: ${this.current}/${this.total} files in ${n}${t}\n`)}};function be(e){const n=Date.now(),t={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},o=de(e);if(w(o))return o;const s=_.resolve(e.directory),i=_.dirname(s),{processed:l,errors:r}=function(e,n,t,o,s){let i=0,l=0;if(void 0!==n.max_depth&&ge(e,s,n.max_depth))return{processed:i,errors:l};try{if(!p.statSync(e).isFile())return{processed:i,errors:l}}catch{return{processed:i,errors:l}}if(ue(e,n,o))return{processed:i,errors:l};const r=he(e);if(r.error)return n.quiet||console.error(`Warning: Could not read metadata for ${e}: ${r.error}`),l+=1,{processed:i,errors:l};const c=r.metadata.size,a=me(e);if(n.rm_comments){const t=a.toLowerCase().replace(/^\./,"");if(ae.map(e=>e.toLowerCase()).includes(t))return{processed:i,errors:l};if((()=>{if(!0===n.rm_comments)return!0;if("string"==typeof n.rm_comments){const e=j(n.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return e.includes(t)||e.includes(`.${t}`)}return!1})()){const t=N(e);if(t.success){if(t.commentsFound){if(!n.quiet){const n=_.relative(s,e);console.log(`β Removed comments from ${n}`)}i+=1}}else{if(!n.quiet){const n=_.relative(s,e);console.error(`β Failed to remove comments from ${n}`)}l+=1}}return{processed:i,errors:l}}i+=1;let d=null,u=null,m=null,f=null,y=null,h=null,g=null;if(!n.files_only){const t=_e(e,n);t.error?(n.quiet||console.error(`Warning: Could not count lines in ${e}: ${t.error.message}`),l+=1):(d=t.lines,u=t.commentLines,m=t.codeLines,f=t.fullLineComments,y=t.inlineComments,h=t.blankLines,g=fe(t))}return pe(t,a,c,d,g),t.details.push(ye(e,c,a,d,u,m,f,y,h)),{processed:i,errors:l}}(s,e,t,o,i);return $e(e,n,l,r),e.rm_comments?{...t,_commentsRemoved:l}:t}function $e(e,n,t,o){if(e.show_progress&&!e.quiet){const e=`${Date.now()-n}ms`;process.stderr.write(`\rProcessed: ${t} files (${o} errors) in ${e}\n`)}}function ve(e){const n=Date.now(),t={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},o=de(e);if(w(o))return o;const s=function(e){const n=g.default();return n.add(".git"),n.add(".gitignore"),n.add(".lcignore"),function e(t,o){const s=_.join(t,".gitignore");try{if(p.existsSync(s)&&p.statSync(s).isFile()){const e=p.readFileSync(s,"utf-8"),i=_.relative(o,t)||".",l=e.split("\n").map(e=>e.trim()).filter(e=>e&&!e.startsWith("#"));for(const e of l)"."===i?n.add(e):n.add(_.join(i,e))}}catch{}try{const n=p.readdirSync(t);for(const s of n){const n=_.join(t,s);try{p.statSync(n).isDirectory()&&".git"!==s&&e(n,o)}catch{}}}catch{}}(e,e),n}(e.directory),i={cwd:e.directory,absolute:!0,onlyFiles:!0,ignore:[],dot:!e.no_hidden,followSymbolicLinks:e.follow_links};let l=0,r=0,c=null,a=0;try{const n=h.default.sync("**/*",i).map(e=>"string"==typeof e?e:e.path||String(e));e.show_progress&&!e.quiet&&(c=new xe(n.length));for(const i of n){if(a+=1,c&&c.update(a,r),void 0!==e.max_depth&&ge(i,e.directory,e.max_depth))continue;const n=_.relative(e.directory,i);if(s.ignores(n))continue;try{if(!p.statSync(i).isFile())continue}catch{continue}if(ue(i,e,o))continue;const d=he(i);if(d.error){e.quiet||console.error(`Warning: Could not read metadata for ${i}: ${d.error}`),r+=1;continue}const u=d.metadata.size,m=me(i);if(e.rm_comments){const n=m.toLowerCase().replace(/^\./,"");if(ae.map(e=>e.toLowerCase()).includes(n))continue;if((()=>{if(!0===e.rm_comments)return!0;if("string"==typeof e.rm_comments){const t=j(e.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return t.includes(n)||t.includes(`.${n}`)}return!1})()){const n=N(i);if(n.success){if(n.commentsFound){if(!e.quiet){const n=_.relative(e.directory,i);console.log(`β Removed comments from ${n}`)}l+=1}}else{if(!e.quiet){const n=_.relative(e.directory,i);console.error(`β Failed to remove comments from ${n}`)}r+=1}}continue}l+=1;let f=null,y=null,h=null,g=null,x=null,b=null,$=null;if(!e.files_only){const n=_e(i,e);n.error?(e.quiet||console.error(`Warning: Could not count lines in ${i}: ${n.error.message}`),r+=1):(f=n.lines,y=n.commentLines,h=n.codeLines,g=n.fullLineComments,x=n.inlineComments,b=n.blankLines,$=fe(n))}pe(t,m,u,f,$),t.details.push(ye(i,u,m,f,y,h,g,x,b))}}catch(e){return L.io(`Failed to scan directory: ${e instanceof Error?e.message:String(e)}`,e instanceof Error?e:void 0)}return $e(e,n,l,r),e.rm_comments?{...t,_commentsRemoved:l}:t}var ke=null,Le=!1,we=null;function Ce(e){const n=z(e.directory);if(n.error)return n.error;const t=n.path;if(!p.statSync(t).isDirectory())return L.notADirectory(e.directory);e.directory=t;const o=ve(e);if(w(o))return o;le(o,e)}function je(e,n=500){ke&&clearTimeout(ke),ke=setTimeout(()=>{if(Le)return;Le=!0,e.quiet||(process.stdout.isTTY&&console.log("[2J[H"),console.log(y.default.cyan("π Changes detected. Rescanning...\n")));const n=Ce(e);w(n)?e.quiet||(console.error(y.default.red(`\nβ Error: ${n.message}`)),n.suggestion&&console.error(y.default.yellow(`\nπ‘ Suggestion: ${n.suggestion}`))):e.quiet||(console.log(y.default.gray("\n"+"β".repeat(60))),console.log(y.default.gray(`π Watching for changes... (Press ${y.default.yellow("Ctrl+C")} to stop)`))),Le=!1},n)}function Se(e){if(e.version)return void console.log(`LocIO ${k()}`);if(e.watch)return void function(e){const n=z(e.directory);n.error&&(console.error(`Error: ${n.error.message}`),process.exit(1));const t=n.path;p.statSync(t).isDirectory()||(console.error(`Error: Not a directory: ${e.directory}`),process.exit(1)),e.quiet||console.log(y.default.cyan("π Starting watch mode...\n"));const o=Ce(e);w(o)&&(console.error(`Error: ${o.message}`),process.exit(1)),e.quiet||(console.log(y.default.gray("\n"+"β".repeat(60))),console.log(y.default.gray(`π Watching for changes... (Press ${y.default.yellow("Ctrl+C")} to stop)`)));try{(we=p.watch(t,{recursive:!0},(n,t)=>{t&&(e.export&&t.startsWith("LocIO-report.")||je(e,500))})).on("error",n=>{e.quiet||console.error(y.default.red(`\nWatch error: ${n.message}`))})}catch(e){console.error(y.default.red(`Failed to start watch mode: ${e instanceof Error?e.message:String(e)}`)),console.error(y.default.yellow("Note: Recursive watching may not be supported on all systems.")),process.exit(1)}const s=()=>{ke&&clearTimeout(ke),we&&we.close(),e.quiet||console.log(y.default.gray("\n\nπ Watch mode stopped.")),process.exit(0)};process.on("SIGINT",s),process.on("SIGTERM",s)}(e);const n=z(e.directory);if(n.error)return n.error;const t=n.path,o=p.statSync(t);let s;if(o.isDirectory()&&!e.quiet){const e=W(t);"unknown"!==e&&console.log(`${y.default.cyan("Detected project type:")} ${y.default.blue.bold(ne(e))}\n`)}if(e.directory=t,e.rm_comments){if(e.quiet||console.log(y.default.cyan("Removing comments from files...\n")),s=o.isFile()?be(e):ve(e),w(s))return s;const n=s._commentsRemoved||0;return void(e.quiet||(n>0?console.log(y.default.green(`\nβ Comments removed successfully from ${n} file(s)!\n`)):console.log(y.default.yellow("\nβΉ No comments found in any files.\n"))))}if(s=o.isFile()?be(e):ve(e),w(s))return s;le(s,e)}(async function(){if(2===m.argv.length&&m.stdin.isTTY){if(!await new Promise((e,n)=>{const t=k();console.log("===================================="),console.log(` LocIO CLI v${t}`),console.log("===================================="),console.log("A fast, flexible line and file counter for your projects.\n"),console.log("Select an option:"),console.log(" 1) Quick scan of current directory (default settings)"),console.log(" 2) Show common command examples"),console.log(" 3) View full help (same as --help)"),console.log(" q) Quit\n"),m.nextTick(()=>{const t=f.createInterface({input:m.stdin,output:m.stdout}),o=()=>{t.question("Enter choice (1/2/3/q): ",n=>{switch(n.trim()){case"1":console.log('\nRunning quick scan on current directory (".") with default settings...\n'),t.close(),e(!0);break;case"2":console.log("\nCommon commands:"),console.log(" locio . # Quick scan"),console.log(" locio . --files-only # Show only file counts"),console.log(" locio . --lines-only # Show only line counts"),console.log(' locio . --exclude "target" # Ignore patterns'),console.log(" locio . --include-ext ts,js # Filter by extension"),console.log(" locio . --export json # Export to JSON\n"),t.close(),e(!1);break;case"3":console.log(),F().outputHelp(),console.log("\n"),t.close(),e(!1);break;case"q":case"Q":console.log("\nThank you for using LocIO."),t.close(),e(!1);break;default:console.log("Invalid choice. Please enter 1, 2, 3, or q.\n"),o()}})};t.on("error",e=>{console.error("\nFailed to read input. Exiting."),t.close(),n(e)}),o()})}))return}!function(e){const n=Se(e);w(n)&&(console.error(function(e){let n=`\nβ Error: ${e.message}\n`;return e.suggestion&&(n+=`\nπ‘ Suggestion:\n${e.suggestion}\n`),e.cause&&(n+=`\nπ Details: ${e.cause.message}\n`),n}(n)),process.exit(1)),e.watch||process.exit(0)}(function(){const e=F();e.parse();const n=e.opts(),t=e.args,o=n.excludeExt?j(n.excludeExt):[],s=n.includeExt?j(n.includeExt):[];return{directory:t[0]||".",files_only:n.filesOnly||!1,lines_only:n.linesOnly||!1,exclude_patterns:n.exclude||[],exclude_extensions:o,include_extensions:s,exclude_dirs:n.excludeDir||[],include_dirs:n.includeDir||[],exclude_names:n.excludeName||[],include_names:n.includeName||[],max_size:n.maxSize,min_size:n.minSize,no_hidden:n.noHidden||!1,no_empty:n.noEmpty||!1,follow_links:n.followLinks||!1,max_depth:n.maxDepth,show_stats:n.stats||!1,show_progress:!0!==n.noProgress,no_binary:n.noBinary||!1,ignore_case:n.ignoreCase||!1,quiet:n.quiet||!1,export:S(n.export),export_path:n.exportPath,version:!1,watch:n.watch||!1,comments:!0!==n.noComments,code_vs_comments:n.codeVsComments||!1,rm_comments:!!n.rmComments&&(!0===n.rmComments||n.rmComments),top_files:n.topFiles,top_dirs:n.topDirs}}())})().catch(e=>{console.error("Unexpected error:",e),m.exit(1)});
|
|
2
|
+
"use strict";var e=require("fs"),t=require("os"),n=require("path"),s=require("@clack/prompts"),o=require("chalk"),i=require("process"),r=require("commander"),l=require("url"),a=require("fast-glob"),c=require("ignore"),d=require("crypto"),u="undefined"!=typeof document?document.currentScript:null;function m(e){return e&&e.__esModule?e:{default:e}}function f(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var s=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,s.get?s:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var p,h,_=f(e),g=f(t),y=f(n),x=f(s),b=m(o),v=f(i),$=m(a),w=m(c),k=f(d),L=Object.defineProperty,S=Object.getOwnPropertyNames,C=(e=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(e,{get:(e,t)=>("undefined"!=typeof require?require:e)[t]}):e)(function(e){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),z={};function E(e){if(0===e)return"0 B";const t=Math.floor(Math.log(e)/Math.log(1024));return`${(e/Math.pow(1024,t)).toFixed(2)} ${["B","KB","MB","GB"][t]}`}function j(e){const t=((e.memoryEnd.heapUsed-e.memoryStart.heapUsed)/e.memoryStart.heapUsed*100).toFixed(1);return[`Duration: ${e.duration}ms`,`Files: ${e.filesProcessed}`,`Errors: ${e.errors}`,`Memory: ${E(e.memoryStart.heapUsed)} β ${E(e.memoryEnd.heapUsed)} (${t}%)`,`Peak Memory: ${E(e.memoryPeak.peakRss)} RSS, ${E(e.memoryPeak.peakHeapUsed)} Heap`].join(" | ")}((e,t)=>{for(var n in t)L(e,n,{get:t[n],enumerable:!0})})(z,{MemoryTracker:()=>p,UsageStatsTracker:()=>h,getPerformanceSummary:()=>j});var F,M,D=(F={"src/utils/metrics.ts"(){p=class{startMemory;peakMemory;checkpoints=[];constructor(){this.startMemory=process.memoryUsage(),this.peakMemory={...this.startMemory}}checkpoint(){const e=process.memoryUsage();this.checkpoints.push({time:Date.now(),memory:e}),e.heapUsed>this.peakMemory.heapUsed&&(this.peakMemory.heapUsed=e.heapUsed),e.rss>this.peakMemory.rss&&(this.peakMemory.rss=e.rss),e.heapTotal>this.peakMemory.heapTotal&&(this.peakMemory.heapTotal=e.heapTotal),e.external>this.peakMemory.external&&(this.peakMemory.external=e.external)}getMetrics(){const e=process.memoryUsage();return{heapUsed:e.heapUsed,heapTotal:e.heapTotal,external:e.external,rss:e.rss,peakHeapUsed:this.peakMemory.heapUsed,peakRss:this.peakMemory.rss}}getStartMemory(){return this.startMemory}},h=class{statsPath;stats;constructor(){const e=g.homedir(),t=y.join(e,".locio");this.statsPath=y.join(t,"usage-stats.json");try{_.existsSync(t)||_.mkdirSync(t,{recursive:!0})}catch{}this.stats=this.loadStats()}loadStats(){try{if(_.existsSync(this.statsPath)){const e=_.readFileSync(this.statsPath,"utf-8");return JSON.parse(e)}}catch{}return{totalScans:0,totalFilesScanned:0,totalLinesScanned:0,averageCodebaseSize:0,optionUsage:{},featureUsage:{},exportFormatUsage:{},lastUpdated:(new Date).toISOString()}}saveStats(){try{this.stats.lastUpdated=(new Date).toISOString(),_.writeFileSync(this.statsPath,JSON.stringify(this.stats,null,2),"utf-8")}catch{}}trackScan(e,t){this.stats.totalScans++,this.stats.totalFilesScanned+=t.total_files,this.stats.totalLinesScanned+=t.total_lines,this.stats.totalScans>0&&(this.stats.averageCodebaseSize=Math.round(this.stats.totalFilesScanned/this.stats.totalScans));const n=["files_only","lines_only","stats","comments","code_vs_comments","watch","no_binary","no_hidden","no_empty","follow_links"];for(const t of n)e[t]&&(this.stats.optionUsage[t]=(this.stats.optionUsage[t]||0)+1);if(e.watch&&(this.stats.featureUsage.watch=(this.stats.featureUsage.watch||0)+1),(e.comments||e.code_vs_comments)&&(this.stats.featureUsage.comments=(this.stats.featureUsage.comments||0)+1),e.rm_comments&&(this.stats.featureUsage.rm_comments=(this.stats.featureUsage.rm_comments||0)+1),(e.top_files||e.top_dirs)&&(this.stats.featureUsage.top_files_dirs=(this.stats.featureUsage.top_files_dirs||0)+1),e.export){const t=Array.isArray(e.export)?e.export:[e.export];for(const e of t){const t=e||"human";this.stats.exportFormatUsage[t]=(this.stats.exportFormatUsage[t]||0)+1}}else this.stats.exportFormatUsage.human=(this.stats.exportFormatUsage.human||0)+1;this.saveStats()}getStats(){return{...this.stats}}getMostCommonOptions(e=5){return Object.entries(this.stats.optionUsage).map(([e,t])=>({option:e,count:t})).sort((e,t)=>t.count-e.count).slice(0,e)}getMostUsedExportFormats(e=5){return Object.entries(this.stats.exportFormatUsage).map(([e,t])=>({format:e,count:t})).sort((e,t)=>t.count-e.count).slice(0,e)}clearStats(){this.stats={totalScans:0,totalFilesScanned:0,totalLinesScanned:0,averageCodebaseSize:0,optionUsage:{},featureUsage:{},exportFormatUsage:{},lastUpdated:(new Date).toISOString()},this.saveStats()}}}},function(){return F&&(M=(0,F[S(F)[0]])(F=0)),M}),T=l.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:u&&"SCRIPT"===u.tagName.toUpperCase()&&u.src||new URL("index.cjs",document.baseURI).href),U=n.dirname(T);function O(){try{const t=[n.join(U,"../package.json"),n.join(U,"../../package.json"),n.join(process.cwd(),"package.json")];for(const n of t)try{const t=JSON.parse(e.readFileSync(n,"utf-8"));if(t.version)return t.version}catch{continue}return"0.0.0"}catch(e){return"0.0.0"}}var P=class e extends Error{suggestion;code;filePath;lineNumber;constructor(e,t,n){super(e),this.name="LineCounterError",this.code=t,this.cause=n?.cause,this.suggestion=n?.suggestion,this.filePath=n?.filePath,this.lineNumber=n?.lineNumber}static io(t,n,s){return new e(`IO error: ${t}`,"IO_ERROR",{cause:n,suggestion:"Check if the file/directory exists, you have read permissions, and there's sufficient disk space.\n - Verify the path is correct\n - Check file system permissions\n - Ensure sufficient disk space is available\n - Try running with elevated permissions if needed",filePath:s})}static invalidSizeFormat(t){return new e(`Invalid size format: ${t}`,"INVALID_SIZE_FORMAT",{suggestion:"Size format should be a number followed by a unit (e.g., '5MB', '1KB', '500B').\nValid units: B, KB, MB, GB, TB (case-insensitive)."})}static invalidRegex(t,n){return new e(`Invalid regex pattern: ${t}${n?`: ${n.message}`:""}`,"INVALID_REGEX",{cause:n,suggestion:"Check your regex pattern syntax. Common issues:\n - Escape special characters with backslash (\\* for literal *)\n - Use proper grouping syntax (parentheses, brackets)\n - Verify quantifiers are properly placed\n - Test your pattern at https://regex101.com"})}static directoryNotFound(t){let n;try{n=y.resolve(t)}catch{n=t}const s=(()=>{try{return C("fs").existsSync(n)}catch{return!1}})(),o=t.includes("\\"),i=t.includes(" "),r=/['"]/.test(t),l=i&&!o&&t.includes(":");let a=`The path "${t}" does not exist.\n`;if(a+=` - Check if the path is correct (resolved: ${n})\n`,l&&(a+=" - β οΈ WARNING: Path appears to be missing backslashes (\\). This usually means the path wasn't properly quoted.\n",a+=' - On Windows, use double quotes: "D:\\path\\with spaces"\n',a+=" - Or use forward slashes: D:/path/with spaces\n",a+=" - Or escape backslashes: D:\\\\path\\\\with spaces\n"),!s){const e=y.dirname(n);a+=(()=>{try{return C("fs").existsSync(e)}catch{return!1}})()?` - Parent directory exists, but "${y.basename(n)}" is missing\n`:` - Parent directory "${e}" also does not exist\n`}return a+=" - Use relative paths like '.' for current directory\n",a+=" - Verify you have read permissions\n",a+=" - Check if it's a file instead of a directory (use the file path directly)\n",(r||i)&&(a+=" - Ensure paths with spaces or special characters are properly quoted in your shell\n"),new e(`Directory not found: ${t}`,"DIRECTORY_NOT_FOUND",{suggestion:a,filePath:t})}static notADirectory(t){return new e(`Not a directory: ${t}`,"NOT_A_DIRECTORY",{suggestion:`"${t}" exists but is not a directory.\n - If it's a file, you can scan it directly: locio <file-path>\n - If you meant a directory, check the path spelling\n - Use 'locio .' to scan the current directory`,filePath:t})}static fileNotFound(t){return new e(`File not found: ${t}`,"FILE_NOT_FOUND",{suggestion:`The file "${t}" does not exist.\n - Check if the file path is correct\n - Verify the file extension\n - Ensure you have read permissions`,filePath:t})}static exportPathError(t,n){return new e(`Export path error: ${t}`,"EXPORT_PATH_ERROR",{suggestion:`Cannot write to export path "${t}": ${n}\n - Ensure the directory exists or can be created\n - Check write permissions\n - Verify there's sufficient disk space\n - Use an absolute path if relative paths aren't working`,filePath:t})}static fileProcessingError(t,n,s){return new e(`File processing error: ${n}`,"FILE_PROCESSING_ERROR",{cause:s,suggestion:`Error processing file "${t}": ${n}\n - Check if the file is readable\n - Verify file encoding (should be UTF-8)\n - Ensure file is not corrupted\n - Check available memory`,filePath:t})}static commentParsingError(t,n,s){return new e(`Comment parsing error: ${n}`,"COMMENT_PARSING_ERROR",{cause:s,suggestion:`Comment parsing failed for "${t}": ${n}\n - File will be processed with basic line counting\n - Comment statistics may be incomplete\n - Check file encoding and syntax`,filePath:t})}};function R(e){return e instanceof P}function I(e,t){return t&&Array.isArray(t)?[...t,e]:[e]}function B(e){return e.split(",").map(e=>e.trim()).filter(Boolean)}function N(e){if(void 0===e)return;if(!0===e)return"human";const t={json:"json",csv:"csv",tsv:"tsv",markdown:"markdown",md:"markdown",html:"html",human:"human",txt:"human"},n=B(e).map(e=>t[e.toLowerCase()]).filter(e=>void 0!==e);return n.length>0?1===n.length?n[0]:n:void 0}function A(e){if(!e||0===e.trim().length)return{path:null,error:P.directoryNotFound("")};let t;try{t=y.resolve(e.trim())}catch(t){return{path:null,error:P.directoryNotFound(e)}}if(!_.existsSync(t))return{path:null,error:P.directoryNotFound(e)};const n=_.statSync(t);return n.isDirectory()||n.isFile()?{path:t,error:null}:{path:null,error:P.notADirectory(e)}}function q(e,t){const n=e.length>t.length?e:t;if(0===n.length)return 1;const s=function(e,t){const n=[];for(let e=0;e<=t.length;e++)n[e]=[e];for(let t=0;t<=e.length;t++){const e=n[0];e&&(e[t]=t)}for(let s=1;s<=t.length;s++){const o=n[s];if(o)for(let i=1;i<=e.length;i++){const r=n[s-1];r&&(t.charAt(s-1)===e.charAt(i-1)?o[i]=r[i-1]??0:o[i]=Math.min((r[i-1]??0)+1,(o[i-1]??0)+1,(r[i]??0)+1))}}const s=n[t.length];return s?.[e.length]??0}(e,t);return(n.length-s)/n.length}function W(){const e=new r.Command,t=["files-only","lines-only","exclude","exclude-ext","include-ext","exclude-dir","include-dir","exclude-name","include-name","max-size","min-size","no-hidden","no-empty","follow-links","max-depth","stats","no-progress","no-binary","ignore-case","quiet","export","export-path","watch","no-comments","code-vs-comments","rm-comments","top-files","top-dirs","version"];return e.configureOutput({writeErr:e=>{if(e.includes("unknown option")){const n=e.match(/unknown option ['"]--?([^'"]+)['"]/);if(n){const e=n[1],s=function(e,t,n=3){return t.map(t=>({option:t,score:q(e,t)})).sort((e,t)=>t.score-e.score).filter(e=>e.score>.3).slice(0,n).map(e=>e.option)}(e,t);if(s.length>0){const t=1===s.length?"Did you mean this?":"Did you mean one of these?";process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ ${t}\n`+s.map(e=>` β’ --${e}`).join("\n")+"\n\nRun 'locio --help' to see all available options.\n\n"),process.exit(1)}process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ This option doesn't exist. Run 'locio --help' to see all available options.\n\n`),process.exit(1)}}process.stderr.write(e)}}),e.name("LocIO").description("A powerful CLI tool to count lines and files in directories").version(O(),"-v, --version","Show version number").argument("[directory]","Directory to scan",".").option("-f, --files-only","Count only files").option("-l, --lines-only","Count only lines").option("-e, --exclude <pattern>","Exclude files matching pattern",I).option("--exclude-ext <extensions>","Exclude file extensions (comma-separated)").option("--include-ext <extensions>","Include only file extensions (comma-separated)").option("--exclude-dir <pattern>","Exclude directories matching pattern",I).option("--include-dir <pattern>","Include only directories matching pattern",I).option("--exclude-name <pattern>","Exclude files by name pattern",I).option("--include-name <pattern>","Include only files by name pattern",I).option("--max-size <size>","Maximum file size (e.g., 5MB)").option("--min-size <size>","Minimum file size (e.g., 1KB)").option("--no-hidden","Exclude hidden files").option("--no-empty","Exclude empty files").option("--follow-links","Follow symbolic links").option("--max-depth <depth>","Maximum directory depth",parseInt).option("--stats","Show detailed statistics").option("--no-progress","Disable progress indicator (enabled by default)").option("--no-binary","Exclude binary files").option("-i, --ignore-case","Case-insensitive pattern matching").option("-q, --quiet","Quiet mode (minimal output)").option("--export [format]","Write report to LocIO-report.{ext} in the given format (human, json, csv, tsv, markdown, html). Multiple formats can be specified comma-separated (e.g., json,html,markdown)").option("--export-path <dir>","Specify output directory for exported reports. Files will use default naming (LocIO-report.{ext}). Directories will be created automatically if they don't exist").option("-w, --watch","Watch directory for changes and auto-rescan").option("--watch-debounce <ms>","Debounce delay for watch mode in milliseconds (default: 500, min: 100, max: 5000)",parseInt).option("--no-comments","Disable comment counting (enabled by default)").option("--code-vs-comments","Show code vs comments ratio (automatically enables --comments)").option("--rm-comments [extensions]","Remove comments from files (modifies files in place). Optionally specify file extensions (comma-separated, e.g., js,ts,py). If no extensions specified, all files are processed.").option("--top-files <n>","Show top N largest files by size",parseInt).option("--top-dirs <n>","Show top N directories with most files",parseInt),e}var G=[{type:"nextjs",files:["next.config.js","next.config.ts","next.config.mjs","next.config.cjs"],packageJsonDeps:["next"],packageJsonDevDeps:["next"],priority:100},{type:"angular",files:["angular.json","angular-cli.json"],packageJsonDeps:["@angular/core"],packageJsonDevDeps:["@angular/cli","@angular/core"],priority:90},{type:"vue",files:["vue.config.js","vue.config.ts","vite.config.js","vite.config.ts"],packageJsonDeps:["vue"],packageJsonDevDeps:["vue","@vitejs/plugin-vue","vite"],dirs:[".nuxt"],priority:85},{type:"react",files:["react-scripts"],packageJsonDeps:["react"],packageJsonDevDeps:["react","react-scripts","@vitejs/plugin-react","vite"],dirs:["node_modules/react"],priority:80},{type:"typescript",files:["tsconfig.json","tsconfig.app.json","tsconfig.base.json"],priority:70},{type:"nodejs",files:["package.json"],priority:75},{type:"rust",files:["Cargo.toml","Cargo.lock"],priority:100},{type:"python",files:["requirements.txt","setup.py","pyproject.toml","Pipfile","poetry.lock","manage.py","setup.cfg","Pipfile.lock"],dirs:["__pycache__"],priority:100},{type:"go",files:["go.mod","go.sum","Gopkg.toml","Gopkg.lock"],priority:100},{type:"java",files:["pom.xml","build.gradle","build.gradle.kts","settings.gradle"],dirs:[".gradle"],priority:100},{type:"csharp",files:["*.csproj","*.sln","project.json","*.fsproj","*.vbproj"],dirs:[".vs"],priority:100},{type:"ruby",files:["Gemfile","Rakefile","Gemfile.lock"],dirs:[".bundle"],priority:100},{type:"php",files:["composer.json","composer.lock","artisan"],dirs:["vendor"],priority:100},{type:"swift",files:["Package.swift","*.xcodeproj","*.xcworkspace"],dirs:[".build"],priority:100},{type:"kotlin",files:["build.gradle.kts","settings.gradle.kts"],dirs:[".gradle"],priority:100},{type:"dart",files:["pubspec.yaml","pubspec.yml","pubspec.lock"],dirs:[".dart_tool"],priority:100}],J={nodejs:{exclude_dirs:["node_modules",".next",".nuxt",".cache","dist","build",".turbo",".vercel",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},nextjs:{exclude_dirs:["node_modules",".next",".vercel","out","dist","build",".turbo"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},react:{exclude_dirs:["node_modules","build","dist",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},vue:{exclude_dirs:["node_modules","dist",".nuxt",".cache","coverage",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},angular:{exclude_dirs:["node_modules","dist",".angular","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},typescript:{exclude_dirs:["node_modules","dist","build",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},rust:{exclude_dirs:["target",".cargo"],exclude_extensions:[],exclude_names:["Cargo.lock"]},python:{exclude_dirs:["__pycache__",".pytest_cache",".mypy_cache",".ruff_cache",".venv","venv","env",".env","build","dist",".*\\.egg-info",".tox",".coverage","htmlcov",".hypothesis"],exclude_extensions:["pyc","pyo","pyd","so"],exclude_names:[".python-version","pip-log.txt","pip-delete-this-directory.txt"]},go:{exclude_dirs:["vendor",".cache"],exclude_extensions:[],exclude_names:["go.sum"]},java:{exclude_dirs:["target","build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar","war","ear"],exclude_names:[".project",".*\\.iml"]},csharp:{exclude_dirs:["bin","obj",".vs","packages","TestResults","[Bb]in","[Oo]bj"],exclude_extensions:["dll","exe","pdb"],exclude_names:[]},ruby:{exclude_dirs:["vendor",".bundle","tmp","log"],exclude_extensions:[],exclude_names:["Gemfile.lock"]},php:{exclude_dirs:["vendor","node_modules"],exclude_extensions:[],exclude_names:["composer.lock"]},swift:{exclude_dirs:[".build",".swiftpm","DerivedData"],exclude_extensions:[],exclude_names:["Package.resolved"]},kotlin:{exclude_dirs:["build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar"],exclude_names:[".project",".*\\.iml"]},dart:{exclude_dirs:[".dart_tool","build"],exclude_extensions:[],exclude_names:["pubspec.lock"]},unknown:{exclude_dirs:[],exclude_extensions:[],exclude_names:[]}};function V(e,t,n){if(!e||!t&&!n)return!1;const s={...e.dependencies||{},...e.devDependencies||{}};if(t)for(const e of t)if(s[e])return!0;if(n)for(const e of n)if(s[e])return!0;return!1}function H(e,t){if(!e||!t||!e.scripts)return!1;for(const n of t)if(e.scripts[n])return!0;return!1}function K(e,t){if(t.includes("*"))try{const n=_.readdirSync(e),s=t.replace(/\*/g,".*"),o=new RegExp(`^${s}$`);return n.some(t=>{const n=y.join(e,t);try{const e=_.statSync(n);return(e.isFile()||e.isDirectory())&&o.test(t)}catch{return!1}})}catch{return!1}else{const n=y.join(e,t);try{if(_.existsSync(n)){return _.statSync(n).isFile()}}catch{}}return!1}function Q(e,t){const n=y.join(e,t);try{if(_.existsSync(n)){return _.statSync(n).isDirectory()}}catch{}return!1}function Y(e,t=2){try{const n=_.readdirSync(e);for(const s of n){const n=y.join(e,s);try{const e=_.statSync(n);if(e.isFile()&&(s.endsWith(".ts")||s.endsWith(".tsx")))return!0;if(e.isDirectory()&&t>0&&!s.startsWith(".")&&"node_modules"!==s&&Y(n,t-1))return!0}catch{}}}catch{}return!1}function Z(e){const t=y.resolve(e);let n=t;try{_.statSync(t).isFile()&&(n=y.dirname(t))}catch{}const s=new Map,o=function(e){const t=y.join(e,"package.json");try{if(_.existsSync(t)){const e=_.readFileSync(t,"utf-8");return JSON.parse(e)}}catch{}return null}(n);for(const e of G){let t=0;const i=[];for(const s of e.files)K(n,s)&&(t+=30,i.push(`file:${s}`));if(e.dirs)for(const s of e.dirs)Q(n,s)&&(t+=20,i.push(`dir:${s}`));if((e.packageJsonDeps||e.packageJsonDevDeps)&&V(o,e.packageJsonDeps,e.packageJsonDevDeps)){t+=50;const n=[...e.packageJsonDeps||[],...e.packageJsonDevDeps||[]];i.push(`dep:${n.join(",")}`)}if(e.packageJsonScripts&&H(o,e.packageJsonScripts)&&(t+=15,i.push(`script:${e.packageJsonScripts.join(",")}`)),"typescript"===e.type&&(K(n,"tsconfig.json")&&(t+=30,i.push("file:tsconfig.json")),Y(n)&&(t+=20,i.push("typescript-files")),o&&K(n,"package.json"))){V(o,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(t=Math.floor(.5*t),i.push("nodejs-backend-penalty"))}if("nodejs"===e.type&&K(n,"package.json")&&(K(n,"tsconfig.json")||Y(n))&&(t+=40,i.push("nodejs-with-typescript")),"react"===e.type)try{const e=_.readdirSync(n);e.some(e=>{const t=y.join(n,e);try{return _.statSync(t).isFile()&&(e.endsWith(".jsx")||e.endsWith(".tsx"))}catch{return!1}})&&(t+=15,i.push("jsx-files"))}catch{}t=Math.floor(t*(1+e.priority/100)),t>0&&s.set(e.type,{type:e.type,score:t,indicators:i})}if(o){if(!Array.from(s.keys()).some(e=>"react"===e||"vue"===e||"angular"===e||"nextjs"===e)){const e=K(n,"tsconfig.json")||Y(n);if(e&&K(n,"package.json")){V(o,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(s.has("nodejs")||s.set("nodejs",{type:"nodejs",score:55,indicators:["package.json","nodejs-backend-with-typescript"]})),s.has("typescript")||s.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]})}else e?s.has("typescript")||s.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]}):s.has("nodejs")||s.set("nodejs",{type:"nodejs",score:30,indicators:["package.json"]})}}return Array.from(s.values()).sort((e,t)=>t.score-e.score)}function X(e){const t=Z(e);return 0===t.length?"unknown":t[0].type}var ee=8192,te=1048576,ne=10485760,se=1e3,oe=104857600,ie=8,re=100,le=500,ae=100,ce=5e3,de="**/*",ue=new Set(["/","/bin","/sbin","/usr/bin","/usr/sbin","/etc","/var","/sys","/proc","/dev","C:\\Windows","C:\\Windows\\System32","C:\\Program Files","C:\\Program Files (x86)",g.homedir()]);function me(e,t){try{if(e.includes("\0"))return!1;const n=e.replace(/\\/g,"/"),s=t.replace(/\\/g,"/"),o=y.resolve(n),i=y.resolve(s),r=y.relative(i,o);if(r.includes("..")||y.isAbsolute(r))return!1;const l=o.replace(/\\/g,"/"),a=i.replace(/\\/g,"/");return!(!l.startsWith(a+"/")&&l!==a)}catch{return!1}}function fe(e,t){if(e.includes("\0"))throw P.exportPathError(e,"Path contains null bytes");let n;n=y.isAbsolute(e)?y.resolve(e):y.resolve(t,e);const s=y.resolve(t),o=y.relative(s,y.dirname(n));if(o.startsWith("..")||y.isAbsolute(o))throw P.exportPathError(e,"Path traversal detected in export path");const i=y.basename(n),r=i.replace(/[<>:"|?*\x00-\x1f]/g,"_");return r!==i&&(n=y.join(y.dirname(n),r)),n}function pe(e,t=oe){try{return _.statSync(e).size<=t}catch{return!1}}function he(e,t=oe){const n=function(e){try{return _.statSync(e).size}catch{return null}}(e);return null===n||n>t}var _e=class{events=[];maxEvents;timeWindow;constructor(e=100,t=1e3){this.maxEvents=e,this.timeWindow=t}shouldAllow(){const e=Date.now();return this.events=this.events.filter(t=>e-t<this.timeWindow),!(this.events.length>=this.maxEvents)&&(this.events.push(e),!0)}reset(){this.events=[]}},ge=new Map;function ye(e){const t=e.toLowerCase().replace(/^\./,"");if(ge.has(t))return ge.get(t);const n=[];let s="",o="",i=!1;switch(t){case"js":case"jsx":case"ts":case"tsx":case"c":case"cpp":case"cc":case"cxx":case"h":case"hpp":case"java":case"cs":case"php":case"swift":case"go":case"rust":case"rs":case"dart":case"kt":case"scala":case"sc":n.push("//"),s="/*",o="*/",i=!0;break;case"sh":case"bash":case"zsh":case"fish":case"py":case"python":case"rb":case"ruby":case"r":case"pl":case"perl":case"yaml":case"yml":case"toml":case"conf":case"ini":case"cfg":case"dockerfile":case"makefile":case"make":case"cmake":case"ps1":case"psm1":case"ex":case"exs":n.push("#");break;case"html":case"htm":case"xml":case"xhtml":case"svg":n.push("\x3c!--"),s="\x3c!--",o="--\x3e",i=!0;break;case"css":case"scss":case"sass":case"less":case"styl":s="/*",o="*/",i=!0;break;case"sql":n.push("--"),s="/*",o="*/",i=!0;break;case"lua":n.push("--"),s="--[[",o="]]",i=!0;break;case"pas":case"p":case"pp":case"fs":case"fsi":case"fsx":n.push("//"),s="(*",o="*)",i=!0;break;case"hs":case"lhs":n.push("--"),s="{-",o="-}",i=!0;break;case"erl":case"hrl":case"m":case"matlab":n.push("%");break;case"vhd":case"vhdl":n.push("--");break;case"bat":case"cmd":n.push("::");break;case"vbs":n.push("'");break;case"clj":case"cljs":case"cljc":case"lisp":case"lsp":case"el":case"rkt":case"rktl":n.push(";");break;case"ml":case"mli":s="(*",o="*)",i=!0;break;default:n.push("//","#","--")}const r={singleLine:n,multiLineStart:s,multiLineEnd:o,supportsMultiLine:i};return ge.set(t,r),r}function xe(e,t,n,s=0){let o=s,i=!1,r=0,l=-1;const a=[];let c=-1,d=-1;for(;r<e.length;){const s=e[r];if(i)i=!1,r++;else if("\\"!==s||0===o){if(3===o&&"$"===s&&r+1<e.length&&"{"===e[r+1]){let t=1;for(r+=2;r<e.length&&t>0;)"{"===e[r]?t++:"}"===e[r]&&t--,r++;continue}if(0===o){if('"'===s)o=2;else if("'"===s)o=1;else if("`"===s)o=3;else if("/"===s&&r+1<e.length){const n=e[r+1];if("/"===n||"*"===n){for(const n of t.singleLine)if(e.substring(r).startsWith(n)){a.push({pos:r,marker:n});break}t.supportsMultiLine&&-1===c&&e.substring(r).startsWith(t.multiLineStart)&&(c=r),r++;continue}{const t=r>0?e[r-1]:" ";/[\s,;=([{!&|?:]/.test(t)&&(o=4,l=r)}}}else if(2===o&&'"'===s)o=0;else if(1===o&&"'"===s)o=0;else if(3===o&&"`"===s)o=0;else if(4===o){if("\\"===s){r+1<e.length?r+=2:r++;continue}if("/"===s)if(r+1<e.length){const t=e[r+1];if(/[gimsuvy]/.test(t)){let t=r+1;for(;t<e.length&&/[gimsuvy]/.test(e[t]);)t++;(t>=e.length||!/[a-zA-Z0-9_]/.test(e[t]))&&(o=0,l=-1,r=t-1)}else/[a-zA-Z0-9_]/.test(t)||(o=0,l=-1)}else o=0,l=-1;else if(" "===s||"\t"===s){const t=r-l-1;let n=!0;for(let t=l+1;t<r;t++)if(" "!==e[t]&&"\t"!==e[t]){n=!1;break}if(n&&t<=2){let t=r+1;for(;t<e.length&&(" "===e[t]||"\t"===e[t]);)t++;t<e.length&&/[0-9;,)}\]\]]/.test(e[t])&&(o=0,l=-1)}}else/[;,)}\]\]]/.test(s)&&(o=0,l=-1)}if(0===o){const s=a.length;for(const n of t.singleLine)if(e.substring(r).startsWith(n)){a.push({pos:r,marker:n});break}if(a.length>s)break;if(t.supportsMultiLine&&-1===c&&e.substring(r).startsWith(t.multiLineStart)){c=r;break}if(t.supportsMultiLine&&n&&e.substring(r).startsWith(t.multiLineEnd)){d=r;break}}r++}else i=!0,r++}if(n){if(-1!==d){const n=e.substring(0,d).trim(),s=e.substring(d+t.multiLineEnd.length).trim();return{commentStart:0,commentEnd:d+t.multiLineEnd.length,isMultiLine:!0,endsMultiLine:!0,commentMarker:t.multiLineEnd,hasCodeBefore:n.length>0,hasCodeAfter:s.length>0,stringState:0}}return{commentStart:0,commentEnd:e.length,isMultiLine:!0,endsMultiLine:!1,commentMarker:t.multiLineEnd,hasCodeBefore:!1,hasCodeAfter:!1,stringState:0}}if(t.supportsMultiLine&&-1!==c){const n=e.substring(0,c).trim(),s=e.indexOf(t.multiLineEnd,c),o=-1!==s,i=o?e.substring(s+t.multiLineEnd.length).trim():"";return{commentStart:c,commentEnd:o?s+t.multiLineEnd.length:e.length,isMultiLine:!0,endsMultiLine:o,commentMarker:t.multiLineStart,hasCodeBefore:n.length>0,hasCodeAfter:i.length>0,stringState:0}}if(a.length>0){const t=a[0],n=e.substring(0,t.pos).trim();return{commentStart:t.pos,commentEnd:e.length,isMultiLine:!1,endsMultiLine:!1,commentMarker:t.marker,hasCodeBefore:n.length>0,hasCodeAfter:!1,stringState:0}}return{commentStart:0,commentEnd:0,isMultiLine:!1,endsMultiLine:!1,commentMarker:"",hasCodeBefore:!1,hasCodeAfter:!1,stringState:o}}function be(e,t){try{const n=(t||_.readFileSync(e,"utf-8")).split(/\r?\n/),s=ye(y.extname(e));let o=n.length,i=0,r=0,l=0,a=0,c=0,d=!1,u=0;for(const e of n){if(0===e.trim().length){d?(r++,l++):c++;continue}const t=xe(e,s,d,u);if(t&&(u=t.stringState),t&&t.commentMarker){t.isMultiLine&&(d=!t.endsMultiLine);!t.hasCodeBefore?(l++,t.hasCodeAfter&&i++):(a++,i++),r++}else d?(r++,l++):i++}return{totalLines:o,codeLines:i,commentLines:r,fullLineComments:l,inlineComments:a,blankLines:c}}catch{return null}}function ve(e){try{const t=_.readFileSync(e,"utf-8"),n=t.split(/\r?\n/),s=ye(y.extname(e));let o=!1;const i=[];let r=!1;for(const e of n){const t=e,n=we(e,s,o);n.line!==t&&(r=!0),!n.line.trim()&&n.isEmpty||i.push(n.line),o=n.inMultiLineComment}const l=i.join("\n");return r||l!==t?(_.writeFileSync(e,l,"utf-8"),{success:!0,commentsFound:!0}):{success:!0,commentsFound:!1}}catch{return{success:!1,commentsFound:!1}}}function $e(e){const t=e.replace(/^\/\//,"").replace(/^\/\*/,"").replace(/\*\/$/,"").trim().toLowerCase();return t.startsWith("eslint")||t.startsWith("@eslint")||t.includes("eslint-disable")||t.includes("eslint-enable")}function we(e,t,n){if(n){const n=e.indexOf(t.multiLineEnd);if(-1!==n){const s=e.substring(0,n+t.multiLineEnd.length),o=e.substring(n+t.multiLineEnd.length);return $e(s)?{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length}:{line:o.trimEnd(),inMultiLineComment:!1,isEmpty:0===o.trim().length}}return $e(e)?{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length}:{line:"",inMultiLineComment:!0,isEmpty:!0}}let s=0,o=!1,i=0,r=-1;const l=[];let a=-1;for(;i<e.length;){const n=e[i];if(o)o=!1,i++;else if("\\"!==n||0===s){if(3===s&&"$"===n&&i+1<e.length&&"{"===e[i+1]){let t=1;for(i+=2;i<e.length&&t>0;)"{"===e[i]?t++:"}"===e[i]&&t--,i++;continue}if(0===s){if('"'===n)s=2;else if("'"===n)s=1;else if("`"===n)s=3;else if("/"===n&&i+1<e.length){const n=e[i+1];if("/"===n||"*"===n){for(const n of t.singleLine)if(e.substring(i).startsWith(n)){l.push(i);break}t.supportsMultiLine&&-1===a&&e.substring(i).startsWith(t.multiLineStart)&&(a=i),i++;continue}{const t=i>0?e[i-1]:" ";/[\s,;=([{!&|?:]/.test(t)&&(s=4,r=i)}}}else if(2===s&&'"'===n)s=0;else if(1===s&&"'"===n)s=0;else if(3===s&&"`"===n)s=0;else if(4===s){if("\\"===n){i+1<e.length?i+=2:i++;continue}if("/"===n)if(i+1<e.length){const t=e[i+1];if(/[gimsuvy]/.test(t)){let t=i+1;for(;t<e.length&&/[gimsuvy]/.test(e[t]);)t++;(t>=e.length||!/[a-zA-Z0-9_]/.test(e[t]))&&(s=0,r=-1,i=t-1)}else/[a-zA-Z0-9_]/.test(t)||(s=0,r=-1)}else s=0,r=-1;else if(" "===n||"\t"===n){const t=i-r-1;let n=!0;for(let t=r+1;t<i;t++)if(" "!==e[t]&&"\t"!==e[t]){n=!1;break}if(n&&t<=2){let t=i+1;for(;t<e.length&&(" "===e[t]||"\t"===e[t]);)t++;t<e.length&&/[0-9;,)}\]\]]/.test(e[t])&&(s=0,r=-1)}}else/[;,)}\]\]]/.test(n)&&(s=0,r=-1)}if(0===s){for(const n of t.singleLine)if(e.substring(i).startsWith(n)){l.push(i);break}t.supportsMultiLine&&-1===a&&e.substring(i).startsWith(t.multiLineStart)&&(a=i)}i++}else o=!0,i++}if(-1!==a){const n=e.substring(0,a),s=e.indexOf(t.multiLineEnd,a+t.multiLineStart.length);if(-1!==s){const o=e.substring(a,s+t.multiLineEnd.length),i=e.substring(s+t.multiLineEnd.length);if($e(o))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};const r=(n+i).trimEnd();return{line:r,inMultiLineComment:!1,isEmpty:0===r.length}}{if($e(e.substring(a)))return{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length};const t=n.trimEnd();return{line:t,inMultiLineComment:!0,isEmpty:0===t.length}}}if(l.length>0){const n=l[0];for(const s of t.singleLine)if(e.substring(n).startsWith(s)){if($e(e.substring(n+s.length)))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};break}const s=e.substring(0,n).trimEnd();return{line:s,inMultiLineComment:!1,isEmpty:0===s.length}}return{line:e,inMultiLineComment:!1,isEmpty:!1}}function ke(e){const t=["B","KB","MB","GB","TB"];let n=e,s=0;for(;n>=1024&&s<t.length-1;)n/=1024,s+=1;return 0===s?`${Math.floor(n)} ${t[s]}`:`${n.toFixed(2)} ${t[s]}`}function Le(){return v.stdout.columns||80}var Se={success:b.default.green,info:b.default.cyan,warning:b.default.yellow,error:b.default.red,highlight:b.default.white.bold,muted:b.default.gray};function Ce(e){return{codeLines:e.code_lines||0,commentLines:e.comment_lines||0,fullLineComments:e.full_line_comments||0,inlineComments:e.inline_comments||0}}function ze(e,t,n,s,o){let i=` (${e} code, ${t} comments`;return void 0!==o&&o>0&&(i+=`, ${o} blank`),(n>0||s>0)&&(i+=`: ${n} full-line, ${s} inline`),i+=")",i}function Ee(e,t,n,s,o){let i=` ${b.default.gray(`(${b.default.blue(e)} code, ${b.default.cyan(t)} comments`)}`;return void 0!==o&&o>0&&(i+=b.default.gray(`, ${b.default.gray(o)} blank`)),(n>0||s>0)&&(i+=b.default.gray(`: ${b.default.yellow(n)} full-line, ${b.default.magenta(s)} inline`)),i+=b.default.gray(")"),i}function je(e,t){return(e.comments||e.show_stats)&&!e.files_only&&t}function Fe(e,t,n){return{sizeStr:ke(e),linesStr:null===t||n.files_only?"":` | ${t} lines`}}function Me(e){const t={};for(const n of e)t[n.directory]||(t[n.directory]=[]),t[n.directory].push(n);return t}function De(e){try{return _.statSync(e.directory).isFile()}catch{return!1}}function Te(e){const t=e.directory;try{if(_.statSync(t).isFile())return y.basename(t)}catch{}return"."===t?"current":t}function Ue(e){return{nodejs:"Node.js",rust:"Rust",python:"Python",go:"Go",java:"Java",csharp:"C#",ruby:"Ruby",php:"PHP",swift:"Swift",kotlin:"Kotlin",dart:"Dart",typescript:"TypeScript",vue:"Vue.js",react:"React",angular:"Angular",nextjs:"Next.js",unknown:"Unknown"}[e]||e}function Oe(e,t){return[...e.details].sort((e,t)=>t.size-e.size).slice(0,t)}function Pe(e,t){const n={};for(const t of e.details)n[t.directory]||(n[t.directory]={fileCount:0,totalSize:0,totalLines:0}),n[t.directory].fileCount+=1,n[t.directory].totalSize+=t.size,null!==t.lines&&(n[t.directory].totalLines+=t.lines);return Object.entries(n).map(([e,t])=>({directory:e,...t})).sort((e,t)=>t.fileCount-e.fileCount).slice(0,t)}function Re(e){return e.files_by_extension?Object.keys(e.files_by_extension).sort():[]}function Ie(e,t,n){switch(e){case"human":return function(e,t){let n="";if(t.quiet)return n+=`${e.total_files} ${e.total_lines}\n`,n;const s=Le(),o=Math.min(60,s-2),i="=".repeat(o);n+=i+"\n",n+="LocIO RESULTS".padStart(Math.floor(o/2)+6).padEnd(o)+"\n",n+=i+"\n\n",n+=`Directory: ${Te(t)}\n`,t.lines_only||(De(t)?n+=`\nSize: ${ke(e.total_size)}\n`:(n+=`\nTotal Files: ${e.total_files}\n`,n+=`\nTotal Files Size: ${ke(e.total_size)}\n`)),!t.files_only&&(n+=`\nTotal Lines: ${e.total_lines}\n`,(t.comments||t.show_stats)&&void 0!==e.total_comment_lines&&(n+=`Total Comment Lines: ${e.total_comment_lines}\n`,void 0!==e.total_full_line_comments&&(n+=` - Full Line Comments: ${e.total_full_line_comments}\n`),void 0!==e.total_inline_comments&&(n+=` - Inline Comments: ${e.total_inline_comments}\n`),void 0!==e.total_code_lines&&(n+=`Total Code Lines: ${e.total_code_lines}\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(n+=`Total Blank Lines: ${e.total_blank_lines}\n`),t.code_vs_comments&&void 0!==e.total_code_lines))&&(n+=`Code vs Comments Ratio: ${e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00"}:1 (${e.total_comment_lines} comments per ${e.total_code_lines} code lines)\n`);const r=Re(e);if(r.length>0&&(n+=`\nExtensions: ${r.join(", ")}\n`),t.show_stats&&r.length>0){n+="\nStatistics by Extension:\n",n+="-".repeat(60)+"\n";for(const s of r){const o=e.files_by_extension[s],i=e.size_by_extension[s]||0,r=e.lines_by_extension[s]||0;if(n+=` ${s}: ${o} files`,t.lines_only||(n+=`, ${ke(i)}`),!t.files_only&&(n+=`, ${r} lines`,je(t,void 0!==e.comment_lines_by_extension?.[s]))){const o=Ce({comment_lines:e.comment_lines_by_extension?.[s]||0,code_lines:e.code_lines_by_extension?.[s]||0,full_line_comments:e.full_line_comments_by_extension?.[s]||0,inline_comments:e.inline_comments_by_extension?.[s]||0}),i=e.blank_lines_by_extension?.[s]||0;n+=ze(o.codeLines,o.commentLines,o.fullLineComments,o.inlineComments,i),t.code_vs_comments&&o.codeLines>0&&(n+=` [${(o.commentLines/o.codeLines).toFixed(2)}:1]`)}n+="\n"}}if(t.show_stats&&e.details&&e.details.length>0){n+="\nFiles by Directory:\n",n+="-".repeat(60)+"\n";const s=Me(e.details),o=Object.keys(s).sort();for(const e of o){const o=s[e];n+=`Directory: ${e}\n`;for(const e of o){const s=ke(e.size),o=null===e.lines||t.files_only?"":` | ${e.lines} lines`;let i="";if(je(t,void 0!==e.comment_lines&&null!==e.comment_lines)){const t=Ce(e);i=ze(t.codeLines,t.commentLines,t.fullLineComments,t.inlineComments,e.blank_lines||void 0)}n+=` - ${e.name} (${e.extension}, ${s}${o}${i})\n`}n+="\n"}}if(t.top_files&&t.top_files>0){const s=Oe(e,t.top_files);n+=`\nTop ${t.top_files} Largest Files:\n`,n+="-".repeat(60)+"\n";for(const e of s){const{sizeStr:s,linesStr:o}=Fe(e.size,e.lines,t);n+=` ${s.padEnd(10)} ${e.name} (${e.extension})${o}\n`}}if(t.top_dirs&&t.top_dirs>0){const s=Pe(e,t.top_dirs);n+=`\nTop ${t.top_dirs} Directories (by file count):\n`,n+="-".repeat(60)+"\n";for(const e of s){const s=ke(e.totalSize),o=t.files_only?"":` | ${e.totalLines} lines`;n+=` ${e.fileCount.toString().padEnd(5)} files ${e.directory} (${s}${o})\n`}}return n+="\n",n}(t,n);case"json":return function(e,t){const n=X(t.directory),s={directory:Te(t)};if("unknown"!==n&&(s.project_type=n,s.project_type_display=Ue(n)),De(t)||(s.files=e.total_files,s.size=e.total_size,s.size_formatted=ke(e.total_size)),t.files_only||(s.lines=e.total_lines,t.comments&&(s.comment_lines=e.total_comment_lines||0,s.code_lines=e.total_code_lines||0,s.blank_lines=e.total_blank_lines||0,s.full_line_comments=e.total_full_line_comments||0,s.inline_comments=e.total_inline_comments||0,t.code_vs_comments&&void 0!==e.total_code_lines&&(s.code_vs_comments_ratio=e.total_code_lines>0?parseFloat((e.total_comment_lines/e.total_code_lines).toFixed(2)):0))),t.show_stats){const n={},o=Re(e);if(o.length>0)for(const s of o)n[s]={files:e.files_by_extension[s],lines:e.lines_by_extension[s]||0,size:e.size_by_extension[s]||0},t.comments&&(n[s].comment_lines=e.comment_lines_by_extension?.[s]||0,n[s].code_lines=e.code_lines_by_extension?.[s]||0,n[s].blank_lines=e.blank_lines_by_extension?.[s]||0,n[s].full_line_comments=e.full_line_comments_by_extension?.[s]||0,n[s].inline_comments=e.inline_comments_by_extension?.[s]||0,t.code_vs_comments&&e.code_lines_by_extension?.[s]&&e.code_lines_by_extension[s]>0&&(n[s].code_vs_comments_ratio=parseFloat(((e.comment_lines_by_extension[s]||0)/e.code_lines_by_extension[s]).toFixed(2))));s.stats=n,s.by_extension=n}if(t.top_files&&t.top_files>0){const n=Oe(e,t.top_files);s.top_files=n.map(e=>({name:e.name,directory:e.directory,extension:e.extension,size:e.size,size_formatted:ke(e.size),lines:e.lines}))}if(t.top_dirs&&t.top_dirs>0){const n=Pe(e,t.top_dirs);s.top_directories=n.map(e=>({directory:e.directory,file_count:e.fileCount,total_size:e.totalSize,total_size_formatted:ke(e.totalSize),total_lines:e.totalLines}))}return JSON.stringify(s,null,2)}(t,n);case"csv":return function(e,t){const n=X(t.directory);let s=`# Directory,${Te(t)}\n`;if("unknown"!==n&&(s+=`# Project Type,${Ue(n)}\n`),t.comments){s+="Extension,Files,Lines,Code Lines,Comment Lines,Blank Lines,Size",t.code_vs_comments&&(s+=",Code vs Comments Ratio"),s+="\n";const n=Re(e);for(const o of n){const n=e.files_by_extension[o],i=e.lines_by_extension[o]||0,r=e.code_lines_by_extension?.[o]||0,l=e.comment_lines_by_extension?.[o]||0;s+=`${o},${n},${i},${r},${l},${e.blank_lines_by_extension?.[o]||0},${e.size_by_extension[o]||0}`,t.code_vs_comments&&r>0&&(s+=`,${((l||0)/r).toFixed(2)}`),s+="\n"}}else{s+="Extension,Files,Lines,Size\n";const t=Re(e);for(const n of t)s+=`${n},${e.files_by_extension[n]},${e.lines_by_extension[n]||0},${e.size_by_extension[n]||0}\n`}return s}(t,n);case"tsv":return function(e,t){const n=X(t.directory);let s=`# Directory\t${Te(t)}\n`;if("unknown"!==n&&(s+=`# Project Type\t${Ue(n)}\n`),t.comments){s+="Extension\tFiles\tLines\tCode Lines\tComment Lines\tBlank Lines\tSize",t.code_vs_comments&&(s+="\tCode vs Comments Ratio"),s+="\n";const n=Re(e);for(const o of n){const n=e.files_by_extension[o],i=e.lines_by_extension[o]||0,r=e.code_lines_by_extension?.[o]||0,l=e.comment_lines_by_extension?.[o]||0;s+=`${o}\t${n}\t${i}\t${r}\t${l}\t${e.blank_lines_by_extension?.[o]||0}\t${e.size_by_extension[o]||0}`,t.code_vs_comments&&r>0&&(s+=`\t${((l||0)/r).toFixed(2)}`),s+="\n"}}else{s+="Extension\tFiles\tLines\tSize\n";const t=Re(e);for(const n of t)s+=`${n}\t${e.files_by_extension[n]}\t${e.lines_by_extension[n]||0}\t${e.size_by_extension[n]||0}\n`}return s}(t,n);case"markdown":return function(e,t){const n=X(t.directory);let s="# LocIO Report\n\n";s+=`**Directory:** ${Te(t)}\n`,"unknown"!==n&&(s+=`**Project Type:** ${Ue(n)}\n`),s+="\n",s+="## Summary\n\n",s+="| Metric | Value |\n",s+="|--------|-------|\n",s+=`| Total Files | ${e.total_files} |\n`,s+=`| Total Size | ${ke(e.total_size)} |\n`,!t.files_only&&(s+=`| Total Lines | ${e.total_lines} |\n`,t.comments&&void 0!==e.total_comment_lines&&(s+=`| Comment Lines | ${e.total_comment_lines} |\n`,void 0!==e.total_code_lines&&(s+=`| Code Lines | ${e.total_code_lines} |\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(s+=`| Blank Lines | ${e.total_blank_lines} |\n`),t.code_vs_comments&&void 0!==e.total_code_lines&&e.total_code_lines>0))&&(s+=`| Code vs Comments Ratio | ${(e.total_comment_lines/e.total_code_lines).toFixed(2)}:1 |\n`);const o=Re(e);if(o.length>0){s+="\n## Statistics by Extension\n\n",s+="| Extension | Files |",t.lines_only||(s+=" Size |"),t.files_only||(s+=" Lines |",t.comments&&(s+=" Code | Comments |",t.code_vs_comments&&(s+=" Ratio |"))),s+="\n",s+="|----------|-------|",t.lines_only||(s+="------|"),t.files_only||(s+="-------|",t.comments&&(s+="------|-----------|",t.code_vs_comments&&(s+="-------|"))),s+="\n";for(const n of o){const o=e.files_by_extension[n],i=e.size_by_extension[n]||0,r=e.lines_by_extension[n]||0,l=e.code_lines_by_extension?.[n]||0,a=e.comment_lines_by_extension?.[n]||0;s+=`| \`${n}\` | ${o} |`,t.lines_only||(s+=` ${ke(i)} |`),!t.files_only&&(s+=` ${r} |`,t.comments)&&(s+=` ${l} | ${a} |`,t.code_vs_comments&&l>0?s+=` ${((a||0)/l).toFixed(2)}:1 |`:t.code_vs_comments&&(s+=" - |")),s+="\n"}}if(t.show_stats&&e.details&&e.details.length>0){s+="\n## Files by Directory\n\n";const n=Me(e.details),o=Object.keys(n).sort();for(const e of o){const o=n[e];s+=`### ${e}\n\n`,s+="| File | Extension | Size |",t.files_only||(s+=" Lines |",(t.comments||t.show_stats)&&(s+=" Code | Comments | Blank | Full-Line | Inline |")),s+="\n",s+="|------|-----------|------|",t.files_only||(s+="-------|",(t.comments||t.show_stats)&&(s+="------|----------|-------|----------|--------|")),s+="\n";for(const e of o)s+=`| ${e.name} | \`${e.extension}\` | ${ke(e.size)} |`,!t.files_only&&null!==e.lines&&(s+=` ${e.lines} |`,t.comments||t.show_stats)&&(s+=` ${e.code_lines||0} | ${e.comment_lines||0} | ${e.blank_lines||0} | ${e.full_line_comments||0} | ${e.inline_comments||0} |`),s+="\n";s+="\n"}}if(t.top_files&&t.top_files>0){const n=Oe(e,t.top_files);s+=`\n## Top ${t.top_files} Largest Files\n\n`,s+="| Size | File | Extension |",t.files_only||(s+=" Lines |"),s+="\n",s+="|------|------|-----------|",t.files_only||(s+="-------|"),s+="\n";for(const e of n)s+=`| ${ke(e.size)} | ${e.name} | \`${e.extension}\` |`,t.files_only||null===e.lines||(s+=` ${e.lines} |`),s+="\n";s+="\n"}if(t.top_dirs&&t.top_dirs>0){const n=Pe(e,t.top_dirs);s+=`\n## Top ${t.top_dirs} Directories (by file count)\n\n`,s+="| Files | Directory | Size |",t.files_only||(s+=" Lines |"),s+="\n",s+="|-------|-----------|------|",t.files_only||(s+="-------|"),s+="\n";for(const e of n)s+=`| ${e.fileCount} | ${e.directory} | ${ke(e.totalSize)} |`,t.files_only||(s+=` ${e.totalLines} |`),s+="\n";s+="\n"}return s+="\n---\n\n",s+="*Generated by [LocIO](https://locio.js.org)*\n",s}(t,n);case"html":return function(e,t){const n=X(t.directory),s=Re(e),o=s.map(t=>({ext:t,files:e.files_by_extension?.[t]||0,lines:e.lines_by_extension?.[t]||0,size:e.size_by_extension?.[t]||0,codeLines:e.code_lines_by_extension?.[t]||0,commentLines:e.comment_lines_by_extension?.[t]||0,blankLines:e.blank_lines_by_extension?.[t]||0}));return`<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>LocIO Report - ${Te(t)}</title>\n <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"><\/script>\n <script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"><\/script>\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh;\n padding: 20px;\n }\n .container {\n max-width: 1200px;\n margin: 0 auto;\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n overflow: hidden;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 40px;\n text-align: center;\n }\n .header h1 {\n font-size: 2.5em;\n margin-bottom: 10px;\n }\n .header p {\n opacity: 0.9;\n font-size: 1.1em;\n }\n .content {\n padding: 40px;\n }\n .summary-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 20px;\n margin-bottom: 40px;\n }\n .card {\n background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n padding: 25px;\n border-radius: 10px;\n text-align: center;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n }\n .card h3 {\n color: #667eea;\n font-size: 0.9em;\n text-transform: uppercase;\n letter-spacing: 1px;\n margin-bottom: 10px;\n }\n .card .value {\n font-size: 2.5em;\n font-weight: bold;\n color: #2d3748;\n }\n .section {\n margin-bottom: 40px;\n }\n .section h2 {\n color: #2d3748;\n margin-bottom: 20px;\n padding-bottom: 10px;\n border-bottom: 3px solid #667eea;\n }\n .chart-container {\n position: relative;\n height: 400px;\n margin: 20px 0;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n margin-top: 20px;\n background: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n th {\n background: #667eea;\n color: white;\n padding: 15px;\n text-align: left;\n font-weight: 600;\n }\n td {\n padding: 12px 15px;\n border-bottom: 1px solid #e2e8f0;\n }\n tr:hover {\n background: #f7fafc;\n }\n .footer {\n text-align: center;\n padding: 20px;\n color: #718096;\n border-top: 1px solid #e2e8f0;\n }\n .footer a {\n color: #667eea;\n text-decoration: none;\n }\n #dependencyGraph {\n width: 100%;\n height: 600px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: #f7fafc;\n margin-top: 20px;\n }\n .graph-legend {\n margin-top: 15px;\n padding: 15px;\n background: #f7fafc;\n border-radius: 8px;\n border: 1px solid #e2e8f0;\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n }\n .legend-item {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .legend-color {\n width: 20px;\n height: 20px;\n border-radius: 4px;\n border: 2px solid #3e3e3e;\n }\n .legend-dir { background: #667eea; }\n .legend-file { background: #4ec9b0; }\n .legend-edge { background: #848484; }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="header">\n <h1>LocIO Report</h1>\n <p>Directory: ${Te(t)}</p>\n ${"unknown"!==n?`<p>Project Type: <strong>${Ue(n)}</strong></p>`:""}\n </div>\n <div class="content">\n <div class="summary-cards">\n <div class="card">\n <h3>Total Files</h3>\n <div class="value">${e.total_files}</div>\n </div>\n <div class="card">\n <h3>Total Size</h3>\n <div class="value">${ke(e.total_size)}</div>\n </div>\n ${t.files_only?"":`<div class="card">\n <h3>Total Lines</h3>\n <div class="value">${e.total_lines}</div>\n </div>`}\n ${t.comments&&void 0!==e.total_comment_lines?`<div class="card">\n <h3>Comment Lines</h3>\n <div class="value">${e.total_comment_lines}</div>\n </div>\n <div class="card">\n <h3>Code Lines</h3>\n <div class="value">${e.total_code_lines||0}</div>\n </div>\n ${void 0!==e.total_blank_lines&&e.total_blank_lines>0?`<div class="card">\n <h3>Blank Lines</h3>\n <div class="value">${e.total_blank_lines}</div>\n </div>`:""}`:""}\n </div>\n\n ${s.length>0?`<div class="section">\n <h2>π Statistics by Extension</h2>\n <div class="chart-container">\n <canvas id="extensionChart"></canvas>\n </div>\n <table>\n <thead>\n <tr>\n <th>Extension</th>\n <th>Files</th>\n ${t.lines_only?"":"<th>Size</th>"}\n ${t.files_only?"":"<th>Lines</th>"}\n ${t.comments?"<th>Code</th><th>Comments</th><th>Blank</th>":""}\n </tr>\n </thead>\n <tbody>\n ${o.map(e=>`<tr>\n <td><strong>${e.ext}</strong></td>\n <td>${e.files}</td>\n ${t.lines_only?"":`<td>${ke(e.size)}</td>`}\n ${t.files_only?"":`<td>${e.lines}</td>`}\n ${t.comments?`<td>${e.codeLines}</td><td>${e.commentLines}</td><td>${e.blankLines}</td>`:""}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`:""}\n\n ${t.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?'<div class="section">\n <h2>π¬ Code vs Comments</h2>\n <div class="chart-container">\n <canvas id="commentChart"></canvas>\n </div>\n </div>':""}\n\n ${t.top_files&&t.top_files>0?(()=>{const n=Oe(e,t.top_files);return`<div class="section">\n <h2>π Top ${t.top_files} Largest Files</h2>\n <table>\n <thead>\n <tr>\n <th>Size</th>\n <th>File</th>\n <th>Extension</th>\n ${t.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${n.map(e=>`<tr>\n <td><strong>${ke(e.size)}</strong></td>\n <td>${e.name}</td>\n <td><code>${e.extension}</code></td>\n ${t.files_only||null===e.lines?"":`<td>${e.lines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${t.top_dirs&&t.top_dirs>0?(()=>{const n=Pe(e,t.top_dirs);return`<div class="section">\n <h2>π Top ${t.top_dirs} Directories (by file count)</h2>\n <table>\n <thead>\n <tr>\n <th>Files</th>\n <th>Directory</th>\n <th>Size</th>\n ${t.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${n.map(e=>`<tr>\n <td><strong>${e.fileCount}</strong></td>\n <td>${e.directory}</td>\n <td>${ke(e.totalSize)}</td>\n ${t.files_only?"":`<td>${e.totalLines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${"html"===t.export&&e.details&&e.details.length>0?(()=>{const n={},s=new Set,o=new Map,i=new Map;for(const t of e.details){const e=t.directory.replace(/\\/g,"/");n[e]||(n[e]={fileCount:0,totalSize:0,totalLines:0},o.set(e,t.directory)),n[e].fileCount+=1,n[e].totalSize+=t.size,null!==t.lines&&(n[e].totalLines+=t.lines);const r=e.split("/").filter(e=>e);for(let e=0;e<r.length;e++){const t=r.slice(0,e+1).join("/");s.add(t),o.has(t)||o.set(t,t)}const l=y.join(t.directory,t.name);i.set(l,e)}const r=[],l=[],a={};for(const e of s)a[e]=n[e]?{...n[e]}:{fileCount:0,totalSize:0,totalLines:0};const c=Array.from(s).sort((e,t)=>{const n=e.split("/").filter(e=>e).length;return t.split("/").filter(e=>e).length-n});for(const e of c){const t=""===e?"":e+"/";for(const n of c){if(n===e)continue;const s=n.split("/").filter(e=>e),o=e.split("/").filter(e=>e);if(s.length===o.length+1&&(""===e||n.startsWith(t))){const t=a[n];t&&(a[e].fileCount+=t.fileCount,a[e].totalSize+=t.totalSize,a[e].totalLines+=t.totalLines)}}}const d=new Map,u=new Map;let m=0;const f=Array.from(s).sort();for(const e of f){const n="dir_"+m++;d.set(e,n);const s=a[e]||{fileCount:0,totalSize:0,totalLines:0},o=e.split("/").pop()||e;r.push({id:n,label:o,group:0,title:`${e}\nFiles: ${s.fileCount}\nSize: ${ke(s.totalSize)}${t.files_only?"":`\nLines: ${s.totalLines}`}`,value:Math.max(s.fileCount,1)});const i=e.split("/").filter(e=>e);if(i.length>1){const e=i.slice(0,-1).join("/"),t=d.get(e);t&&l.push({from:t,to:n,arrows:"to",color:{color:"#667eea"},title:"contains"})}}const p=e.details.sort((e,t)=>t.size-e.size).slice(0,100);for(const e of p){const n=e.directory.replace(/\\/g,"/"),s=y.join(e.directory,e.name),o="file_"+m++;u.set(s,o),r.push({id:o,label:e.name,group:1,title:`${s}\nSize: ${ke(e.size)}${t.files_only||null===e.lines?"":`\nLines: ${e.lines}`}\nExtension: ${e.extension}`,value:Math.max(Math.floor(e.size/100),1)});const i=d.get(n);i&&l.push({from:i,to:o,arrows:"to",color:{color:"#848484"},title:"contains"})}const h=Object.entries(n),_=Math.max(...h.map(([,e])=>e.fileCount),1),g=Math.max(...h.map(([,e])=>e.totalSize),1);return`<div class="section">\n <h2>πΊοΈ Directory Structure Graph</h2>\n <div id="dependencyGraph"></div>\n <div class="graph-legend">\n <div class="legend-item">\n <span class="legend-color legend-dir"></span>\n <span>Directories</span>\n </div>\n <div class="legend-item">\n <span class="legend-color legend-file"></span>\n <span>Files</span>\n </div>\n <div class="legend-item">\n <span class="legend-color legend-edge"></span>\n <span>Contains</span>\n </div>\n </div>\n <script type="text/javascript">\n const nodes = new vis.DataSet(${JSON.stringify(r)});\n const edges = new vis.DataSet(${JSON.stringify(l)});\n\n const data = {\n nodes: nodes,\n edges: edges\n };\n\n const options = {\n nodes: {\n shape: 'dot',\n size: 16,\n font: {\n size: 14,\n color: '#2d3748'\n },\n borderWidth: 2,\n shadow: true\n },\n edges: {\n width: 2,\n shadow: true,\n smooth: {\n type: 'continuous',\n roundness: 0.5\n }\n },\n groups: {\n 0: {\n color: {\n background: '#667eea',\n border: '#4a5568',\n highlight: {\n border: '#4a5568',\n background: '#764ba2'\n }\n },\n shape: 'box',\n size: 25\n },\n 1: {\n color: {\n background: '#4ec9b0',\n border: '#2d3748',\n highlight: {\n border: '#2d3748',\n background: '#6ec9b0'\n }\n },\n shape: 'dot',\n size: 15\n }\n },\n physics: {\n enabled: true,\n stabilization: {\n enabled: true,\n iterations: 200\n },\n barnesHut: {\n gravitationalConstant: -2000,\n centralGravity: 0.1,\n springLength: 200,\n springConstant: 0.04,\n damping: 0.09\n }\n },\n interaction: {\n hover: true,\n tooltipDelay: 100,\n zoomView: true,\n dragView: true\n }\n };\n\n const container = document.getElementById('dependencyGraph');\n const network = new vis.Network(container, data, options);\n\n network.on('click', function(params) {\n if (params.nodes.length > 0) {\n const nodeId = params.nodes[0];\n const node = nodes.get(nodeId);\n if (node) {\n console.log('Selected:', node.title);\n }\n }\n });\n <\/script>\n </div>\n <div class="section">\n <h2>π Directory Heatmap</h2>\n <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; margin-top: 20px;">\n ${h.map(([e,n])=>{const s=(n.fileCount/_*100+n.totalSize/g*100)/2,o=240-1.2*s;return`<div style="\n background: linear-gradient(135deg, hsl(${o}, 70%, ${85-.3*s}%), hsl(${o}, 70%, ${75-.3*s}%));\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n color: ${s>50?"white":"#2d3748"};\n ">\n <div style="font-weight: bold; margin-bottom: 8px; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="${e}">${e.split("/").pop()||e}</div>\n <div style="font-size: 0.8em; opacity: 0.9;">\n <div>π ${n.fileCount} files</div>\n <div>πΎ ${ke(n.totalSize)}</div>\n ${t.files_only?"":`<div>π ${n.totalLines} lines</div>`}\n </div>\n </div>`}).join("")}\n </div>\n </div>`})():""}\n </div>\n <div class="footer">\n Generated by <a href="https://locio.js.org">LocIO</a>\n </div>\n </div>\n\n <script>\n ${s.length>0?`const extensionCtx = document.getElementById('extensionChart');\n new Chart(extensionCtx, {\n type: 'bar',\n data: {\n labels: ${JSON.stringify(s)},\n datasets: [\n ${t.files_only?"":`{\n label: 'Lines',\n data: ${JSON.stringify(s.map(t=>e.lines_by_extension[t]||0))},\n backgroundColor: 'rgba(102, 126, 234, 0.8)',\n borderColor: 'rgba(102, 126, 234, 1)',\n borderWidth: 2\n },`}\n {\n label: 'Files',\n data: ${JSON.stringify(s.map(t=>e.files_by_extension?.[t]||0))},\n backgroundColor: 'rgba(118, 75, 162, 0.8)',\n borderColor: 'rgba(118, 75, 162, 1)',\n borderWidth: 2\n }\n ]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'top',\n },\n title: {\n display: true,\n text: 'Files and Lines by Extension'\n }\n }\n }\n });`:""}\n\n ${t.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?`const commentCtx = document.getElementById('commentChart');\n new Chart(commentCtx, {\n type: 'doughnut',\n data: {\n labels: ['Code Lines', 'Comment Lines'],\n datasets: [{\n data: [${e.total_code_lines}, ${e.total_comment_lines||0}],\n backgroundColor: [\n 'rgba(102, 126, 234, 0.8)',\n 'rgba(118, 75, 162, 0.8)'\n ],\n borderColor: [\n 'rgba(102, 126, 234, 1)',\n 'rgba(118, 75, 162, 1)'\n ],\n borderWidth: 2\n }]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'bottom',\n },\n title: {\n display: true,\n text: 'Code vs Comments Distribution'\n }\n }\n }\n });`:""}\n <\/script>\n</body>\n</html>`}(t,n)}}function Be(e){const t=function(e){switch(e){case"human":return"txt";case"json":return"json";case"csv":return"csv";case"tsv":return"tsv";case"markdown":return"md";case"html":return"html"}}(e);return`LocIO-report.${t}`}function Ne(e,t){void 0===t.export?function(e,t){if(t.quiet)return void console.log(`${e.total_files} ${e.total_lines}`);const n=Le(),s=Math.min(60,n-2),o="=".repeat(s),i=Math.floor(s/2)+6;if(console.log("\n"+Se.info(o)),console.log(Se.info.bold("LocIO RESULTS".padStart(i).padEnd(s))),console.log(Se.info(o)),console.log(`\n${b.default.green.bold("Directory:")} ${Te(t)}`),t.lines_only||(De(t)?console.log(`\n${b.default.green.bold("Size:")} ${b.default.white(ke(e.total_size))}`):(console.log(`\n${b.default.green.bold("Total Files:")} ${b.default.yellow(e.total_files)}`),console.log(`\n${b.default.green.bold("Total Files Size:")} ${b.default.white(ke(e.total_size))}`))),!t.files_only&&(console.log(`\n${b.default.green.bold("Total Lines:")} ${b.default.yellow(e.total_lines)}`),(t.comments||t.show_stats)&&void 0!==e.total_comment_lines&&(console.log(`\n${b.default.green.bold("Total Comment Lines:")} ${b.default.cyan(e.total_comment_lines)}`),void 0!==e.total_full_line_comments&&console.log(` ${b.default.gray("β")} ${b.default.green("Full Line Comments:")} ${b.default.cyan(e.total_full_line_comments)}`),void 0!==e.total_inline_comments&&console.log(` ${b.default.gray("β")} ${b.default.green("Inline Comments:")} ${b.default.cyan(e.total_inline_comments)}`),void 0!==e.total_code_lines&&console.log(`\n${b.default.green.bold("Total Code Lines:")} ${b.default.blue(e.total_code_lines)}`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&console.log(`\n${b.default.green.bold("Total Blank Lines:")} ${b.default.gray(e.total_blank_lines)}`),t.code_vs_comments&&void 0!==e.total_code_lines))){const t=e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00";console.log(`\n${b.default.green.bold("Code vs Comments Ratio:")} ${b.default.magenta(t)}:1 ${b.default.gray(`(${e.total_comment_lines} comments per ${e.total_code_lines} code lines)`)}`)}const r=Re(e);if(r.length>0&&console.log(`\n${b.default.green.bold("Extensions:")} ${b.default.white(r.join(", "))}`),t.show_stats&&r.length>0){const n=Le(),s=Math.min(60,n-2);console.log(`\n${Se.info.bold("Statistics by Extension:")}`),console.log(Se.muted("-".repeat(s)));for(const n of r){const s=e.files_by_extension[n],o=e.size_by_extension[n]||0,i=e.lines_by_extension[n]||0;let r=` ${b.default.white(n)}: ${b.default.yellow(s)} files`;if(t.lines_only||(r+=`, ${b.default.white(ke(o))}`),!t.files_only&&(r+=`, ${b.default.yellow(i)} lines`,je(t,void 0!==e.comment_lines_by_extension?.[n]))){const s=Ce({comment_lines:e.comment_lines_by_extension?.[n]||0,code_lines:e.code_lines_by_extension?.[n]||0,full_line_comments:e.full_line_comments_by_extension?.[n]||0,inline_comments:e.inline_comments_by_extension?.[n]||0}),o=e.blank_lines_by_extension?.[n]||0;if(r+=Ee(s.codeLines,s.commentLines,s.fullLineComments,s.inlineComments,o),t.code_vs_comments&&s.codeLines>0){const e=(s.commentLines/s.codeLines).toFixed(2);r+=` ${b.default.magenta(`[${e}:1]`)}`}}console.log(r)}}if(t.show_stats&&e.details&&e.details.length>0){console.log(`\n${b.default.cyan.bold("Files by Directory:")}`),console.log(b.default.gray("-".repeat(60)));const n=Me(e.details),s=Object.keys(n).sort();for(const e of s){const s=n[e];console.log(b.default.green.bold(`Directory: ${e}`));for(const e of s){const n=ke(e.size),s=null===e.lines||t.files_only?"":` | ${e.lines} lines`;let o="";if(je(t,void 0!==e.comment_lines&&null!==e.comment_lines)){const t=Ce(e);o=Ee(t.codeLines,t.commentLines,t.fullLineComments,t.inlineComments,e.blank_lines||void 0)}console.log(` - ${b.default.white(e.name)} (${b.default.blue(e.extension)}, ${b.default.white(n)}${s}${o})`)}console.log()}}if(t.top_files&&t.top_files>0){const n=Oe(e,t.top_files);console.log(`\n${b.default.cyan.bold(`Top ${t.top_files} Largest Files:`)}`),console.log(b.default.gray("-".repeat(60)));for(const e of n){const{sizeStr:n,linesStr:s}=Fe(e.size,e.lines,t);console.log(` ${b.default.yellow(n.padEnd(10))} ${b.default.white(e.name)} ${b.default.blue(`(${e.extension})`)}${s}`)}}if(t.top_dirs&&t.top_dirs>0){const n=Pe(e,t.top_dirs);console.log(`\n${b.default.cyan.bold(`Top ${t.top_dirs} Directories (by file count):`)}`),console.log(b.default.gray("-".repeat(60)));for(const e of n){const n=ke(e.totalSize),s=t.files_only?"":` | ${e.totalLines} lines`;console.log(` ${b.default.yellow(e.fileCount.toString().padEnd(5))} files ${b.default.white(e.directory)} ${b.default.gray(`(${n}${s})`)}`)}}console.log()}(e,t):function(e,t){const n=Array.isArray(t.export)?t.export:[t.export||"human"];for(let s=0;s<n.length;s++){const o=n[s],i=Ie(o,e,t),r=Be(o);let l=r;try{let e;if(t.export_path)try{const n=fe(t.export_path,t.directory);e=n,l=y.join(n,r)}catch(e){const n=e instanceof Error?e:new Error(String(e));console.error(`\nβ Invalid export path: ${t.export_path}`),console.error(`π Error: ${n.message}`);continue}else e=y.join(t.directory,"reports"),l=y.join(e,r);e&&"."!==e&&e!==r&&_.mkdirSync(e,{recursive:!0}),_.writeFileSync(l,i,"utf-8"),t.quiet||console.log(`Report written to ${l}`)}catch(e){const t=(e instanceof Error?e:new Error(String(e))).message||String(e);let n="";n=t.includes("ENOENT")?`The directory for "${r}" does not exist.\n - Ensure the parent directory exists\n - Check if the path is correct`:t.includes("EACCES")||t.includes("permission")?`Permission denied when writing to "${r}".\n - Check write permissions for the directory\n - Try running with appropriate permissions\n - Use a different output directory`:t.includes("ENOSPC")?"Insufficient disk space.\n - Free up disk space\n - Choose a different location":"Check if the path is valid and you have write permissions.",console.error(`\nβ Failed to create report file ${l||r}`),console.error(`π Error: ${t}`),n&&console.error(`\nπ‘ Suggestion:\n${n}`)}}}(e,t)}var Ae=new Set(["exe","dll","so","dylib","bin","o","a","lib","jpg","jpeg","png","gif","bmp","ico","svg","pdf","zip","tar","gz","bz2","xz","7z","rar","mp3","mp4","avi","mov","wmv","flv","woff","woff2","ttf","otf","eot"]);function qe(e){const t=e.trim().toUpperCase();let n,s;t.endsWith("KB")?(n=t.slice(0,-2),s=1024):t.endsWith("MB")?(n=t.slice(0,-2),s=1048576):t.endsWith("GB")?(n=t.slice(0,-2),s=1073741824):t.endsWith("B")&&t.length>1?(n=t.slice(0,-1),s=1):(n=t,s=1);const o=parseFloat(n);return isNaN(o)?P.invalidSizeFormat(e):Math.floor(o*s)}function We(e,t){const n=y.extname(e).replace(/^\./,"").toLowerCase();if(Ae.has(n))return!0;try{const t=ee,n=Buffer.alloc(t),s=_.openSync(e,"r"),o=_.readSync(s,n,0,t,0);if(_.closeSync(s),0===o)return!1;for(let e=0;e<o;e++)if(0===n[e])return!0;return!1}catch{return!1}}var Ge=te,Je=ne;function Ve(e,t){try{if(!pe(e,oe))return P.io(`File too large to process: exceeds maximum safe size (${oe/1048576}MB)`,void 0,e);const t=_.statSync(e);if(t.size<Ge){return He(_.readFileSync(e,"utf-8"))}if(t.size>=Je)try{return He(_.readFileSync(e,"utf-8"))}catch(t){return P.io(`Failed to read large file: ${e}`,t instanceof Error?t:void 0)}return He(_.readFileSync(e,"utf-8"))}catch(t){return P.io(`Failed to read file: ${e}`,t instanceof Error?t:void 0)}}function He(e){if(e.length>oe)throw new Error(`Content too large: exceeds maximum safe size (${oe/1048576}MB)`);return e.split(/\r?\n/).length}function Ke(e){if(e.length>oe)throw new Error(`Content too large: exceeds maximum safe size (${oe/1048576}MB)`);const t=e.split(/\r?\n/);let n=0,s=0;for(const e of t)0===e.trim().length?n++:s++;return{total:t.length,blank:n,code:s}}function Qe(e,t){try{if(!pe(e,oe))return P.io(`File too large to process: exceeds maximum safe size (${oe/1048576}MB)`,void 0,e);if(_.statSync(e).size<Ge){return Ke(_.readFileSync(e,"utf-8"))}return Ke(_.readFileSync(e,"utf-8"))}catch(t){return P.io(`Failed to read file: ${e}`,t instanceof Error?t:void 0)}}var Ye=["jpg","jpeg","png","gif","bmp","svg","ico","webp","tiff","tif","psd","raw","heic","heif","avif","mp3","wav","flac","aac","ogg","wma","m4a","opus","aiff","au","mp4","avi","mkv","mov","wmv","flv","webm","m4v","mpg","mpeg","3gp","ogv","zip","rar","7z","tar","gz","bz2","xz","z","cab","iso","dmg","pkg","deb","rpm","pdf","doc","docx","xls","xlsx","ppt","pptx","odt","ods","odp","exe","dll","so","dylib","app","msi","bin","run","ttf","otf","woff","woff2","eot","db","sqlite","sqlite3","mdb","accdb","ps","eps","ai","sketch","fig","xd"],Ze=["md","markdown","txt","rst","adoc","asciidoc","org","wiki","json","yaml","yml","toml","ini","cfg","conf","config","properties","env","dotenv","csv","tsv","xml","html","htm","xhtml","log","lock","lockfile"];function Xe(e){try{if(e.max_size){const t=qe(e.max_size);if(t instanceof P)return t}if(e.min_size){const t=qe(e.min_size);if(t instanceof P)return t}const t=X(e.directory),n=J[t]||J.unknown,s=e.exclude_patterns.map(t=>{try{return new RegExp(t,e.ignore_case?"i":void 0)}catch(e){throw P.invalidRegex(t,e instanceof Error?e:void 0)}}),o=[...e.exclude_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),...n.exclude_extensions.map(e=>e.toLowerCase()),...Ye.map(e=>e.toLowerCase())],i=Array.from(new Set(o)).sort(),r=new Set(i),l=e.include_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),a=new Set(l),c=[...e.exclude_dirs,...n.exclude_dirs].map(t=>new RegExp(t,e.ignore_case?"i":void 0)),d=e.include_dirs.map(t=>new RegExp(t,e.ignore_case?"i":void 0)),u=[...e.exclude_names,...n.exclude_names].map(t=>new RegExp(t,e.ignore_case?"i":void 0)),m=e.include_names.map(t=>new RegExp(t,e.ignore_case?"i":void 0)),f=s.length>0?new RegExp(s.map(e=>`(?:${e.source})`).join("|"),e.ignore_case?"i":void 0):null,p=c.length>0?new RegExp(c.map(e=>`(?:${e.source})`).join("|"),e.ignore_case?"i":void 0):null,h=u.length>0?new RegExp(u.map(e=>`(?:${e.source})`).join("|"),e.ignore_case?"i":void 0):null;return{exclude_patterns:s,exclude_extensions:i,include_extensions:l,exclude_dirs:c,include_dirs:d,exclude_names:u,include_names:m,detected_project_type:t,exclude_extensions_set:r,include_extensions_set:a,combined_exclude_patterns:f,combined_exclude_dirs:p,combined_exclude_names:h}}catch(e){return e instanceof P?e:P.io(`Failed to create filter patterns: ${e instanceof Error?e.message:String(e)}`)}}var et=new Map([[".ts","ts"],[".js","js"],[".tsx","tsx"],[".jsx","jsx"],[".json","json"],[".md","md"],[".css","css"],[".html","html"],[".xml","xml"],[".yaml","yaml"],[".yml","yml"],[".py","py"],[".java","java"],[".cpp","cpp"],[".c","c"],[".h","h"],[".hpp","hpp"],[".cs","cs"],[".php","php"],[".rb","rb"],[".go","go"],[".rs","rs"],[".swift","swift"],[".kt","kt"],[".scala","scala"],[".sh","sh"],[".bash","bash"],[".zsh","zsh"],[".fish","fish"],[".ps1","ps1"],[".bat","bat"],[".cmd","cmd"]]),tt=new class{cache=new Map;normalize(e){if(this.cache.has(e))return this.cache.get(e);const t=y.extname(e).toLowerCase(),n=et.get(t);if(n)return this.cache.set(e,n),n;const s=t.replace(/^\./,"")||"no-ext";return this.cache.set(e,s),s}normalizeFast(e){const t=y.extname(e).toLowerCase(),n=et.get(t);return n||this.normalize(e)}clear(){this.cache.clear()}};function nt(e){return tt.normalize(e)}function st(e){const t=null!==e.commentLines,n=null!==e.codeLines&&null!==e.blankLines;return t||n?{totalLines:e.lines||0,commentLines:e.commentLines||0,codeLines:e.codeLines||0,fullLineComments:e.fullLineComments||0,inlineComments:e.inlineComments||0,blankLines:e.blankLines||0}:null}function ot(e,t,n,s,o){if(e.total_files+=1,e.total_size+=n,e.files_by_extension[t]=(e.files_by_extension[t]||0)+1,e.size_by_extension[t]=(e.size_by_extension[t]||0)+n,null!==s&&(e.total_lines+=s,e.lines_by_extension[t]=(e.lines_by_extension[t]||0)+s),o){const n=o.codeLines+o.commentLines+o.blankLines;o.totalLines!==n&&(o.totalLines=n),e.total_comment_lines=(e.total_comment_lines||0)+o.commentLines,e.total_code_lines=(e.total_code_lines||0)+o.codeLines,e.total_blank_lines=(e.total_blank_lines||0)+o.blankLines,e.total_full_line_comments=(e.total_full_line_comments||0)+o.fullLineComments,e.total_inline_comments=(e.total_inline_comments||0)+o.inlineComments,e.comment_lines_by_extension[t]=(e.comment_lines_by_extension[t]||0)+o.commentLines,e.code_lines_by_extension[t]=(e.code_lines_by_extension[t]||0)+o.codeLines,e.blank_lines_by_extension||(e.blank_lines_by_extension={}),e.blank_lines_by_extension[t]=(e.blank_lines_by_extension[t]||0)+o.blankLines,e.full_line_comments_by_extension[t]=(e.full_line_comments_by_extension[t]||0)+o.fullLineComments,e.inline_comments_by_extension[t]=(e.inline_comments_by_extension[t]||0)+o.inlineComments}}function it(e,t){if(!t.comments&&!t.code_vs_comments){const t=Ve(e);return R(t)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:t}:{lines:t,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}const n=nt(e),s=Ze.map(e=>e.toLowerCase()).includes(n);if(t.comments||t.code_vs_comments){if(!s)try{const t=be(e);if(t)return{lines:t.totalLines,commentLines:t.commentLines,codeLines:t.codeLines,fullLineComments:t.fullLineComments,inlineComments:t.inlineComments,blankLines:t.blankLines,error:null}}catch(t){const n=Qe(e);return R(n)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:n}:{lines:n.total,commentLines:0,codeLines:n.code,fullLineComments:0,inlineComments:0,blankLines:n.blank,error:t instanceof Error?P.commentParsingError(e,t.message,t):null}}const t=Qe(e);return R(t)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:t}:{lines:t.total,commentLines:0,codeLines:t.code,fullLineComments:0,inlineComments:0,blankLines:t.blank,error:null}}const o=Ve(e);return R(o)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:o}:{lines:o,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}function rt(e,t,n,s,o,i,r,l,a){return{directory:y.dirname(e),name:y.basename(e),extension:n,size:t,lines:s,comment_lines:o,code_lines:i,blank_lines:a,full_line_comments:r,inline_comments:l}}var lt=class{progressBar;updateQueue=[];lastUpdate=0;throttleMs=100;pendingUpdate=null;constructor(e){this.progressBar=e}update(e,t,n){this.updateQueue.push({files:e,errors:t,currentFile:n}),this.scheduleUpdate()}scheduleUpdate(){if(this.pendingUpdate)return;const e=Date.now()-this.lastUpdate;if(e>=this.throttleMs)this.flushUpdate();else{const t=this.throttleMs-e;this.pendingUpdate=setTimeout(()=>{this.flushUpdate()},t)}}flushUpdate(){if(0===this.updateQueue.length)return void(this.pendingUpdate=null);const e=this.updateQueue[this.updateQueue.length-1];this.progressBar.update(e.files,e.errors,e.currentFile),this.updateQueue=[],this.lastUpdate=Date.now(),this.pendingUpdate=null}finish(){this.pendingUpdate&&(clearTimeout(this.pendingUpdate),this.pendingUpdate=null),this.flushUpdate(),this.progressBar.finish()}},at=class{total;current=0;startTime;width=40;errors=0;currentFile="";lastUpdateTime;filesPerSecond=0;constructor(e){this.total=e,this.startTime=Date.now(),this.lastUpdateTime=this.startTime}update(e,t=0,n){this.current=e,this.errors=t,n&&(this.currentFile=n);const s=Date.now(),o=s-this.lastUpdateTime;if(o>0){const t=e-(this.current-1);this.filesPerSecond=t/o*1e3}this.lastUpdateTime=s,this.render()}increment(e=0){this.current++,e>0&&(this.errors=e),this.render()}formatTime(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;return`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3)}s`}calculateETA(){if(0===this.current)return"calculating...";const e=Date.now()-this.startTime,t=this.current/e,n=(this.total-this.current)/t;return n<0||!isFinite(n)?"calculating...":this.formatTime(n)}formatSpeed(){return 0!==this.filesPerSecond&&isFinite(this.filesPerSecond)?this.filesPerSecond>=1e3?`${(this.filesPerSecond/1e3).toFixed(1)}k files/s`:`${Math.round(this.filesPerSecond)} files/s`:"calculating..."}formatCurrentFile(){if(!this.currentFile)return"";return this.currentFile.length>40?" | "+("..."+this.currentFile.slice(-37)):` | ${this.currentFile}`}render(){const e=this.total>0?this.current/this.total*100:0,t=e.toFixed(1).padStart(5),n=String(this.current).padStart(String(this.total).length),s=this.errors>0?b.default.red(` (${this.errors} errors)`):"",o=Date.now()-this.startTime,i=this.formatTime(o),r=this.calculateETA(),l=this.formatSpeed(),a=this.formatCurrentFile();if(!process.stderr.isTTY){if(this.current%100==0||this.current===this.total){const e=this.currentFile?` | Current: ${this.currentFile}`:"";process.stderr.write(`\rProcessed: ${n}/${this.total} (${t}%) | ${i} elapsed | ETA: ${r} | ${l}${e}${s}`)}return}const c=process.stderr.columns||80;this.width=Math.min(40,Math.max(20,Math.floor(c/4)));const d=Math.round(e/100*this.width),u=this.width-d,m=`\r${b.default.green("β".repeat(d))+b.default.gray("β".repeat(u))} ${t}% | ${n}/${this.total} files | ${i} elapsed | ETA: ${r} | ${b.default.cyan(l)}${a}${s}`;process.stderr.write("[K"+m)}finish(){const e=Date.now()-this.startTime,t=this.formatTime(e),n=this.errors>0?b.default.red(` (${this.errors} errors)`):"";if(process.stderr.isTTY){const e=100,s=b.default.green("β".repeat(this.width)),o=String(this.current).padStart(String(this.total).length);process.stderr.write(`\r${s} ${e.toFixed(1).padStart(5)}% | ${o}/${this.total} files | ${t}${n}\n`)}else process.stderr.write(`\rProcessed: ${this.current}/${this.total} files in ${t}${n}\n`)}};var ct=class{cache=new Map;get(e){if(this.cache.has(e))return this.cache.get(e);try{const t=_.statSync(e);return this.cache.set(e,t),t}catch{return null}}async getAsync(e){if(this.cache.has(e))return this.cache.get(e);try{const t=await _.promises.stat(e);return this.cache.set(e,t),t}catch{return null}}clear(){this.cache.clear()}},dt=class{cache=new Map;maxCacheSize=se;async get(e){if(this.cache.has(e))return this.cache.get(e);try{const t=await _.promises.stat(e),n={content:await _.promises.readFile(e,"utf-8"),stats:t};if(this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;void 0!==e&&this.cache.delete(e)}return this.cache.set(e,n),n}catch{return null}}clear(){this.cache.clear()}},ut=new class{cache=new Map;getGitignorePaths(e,t){const n=[];return function e(t,s){const o=y.join(t,".gitignore");try{if(_.existsSync(o)&&_.statSync(o).isFile()){const e=_.statSync(o);n.push({path:o,mtime:e.mtimeMs})}}catch{}try{const n=_.readdirSync(t);for(const s of n){const n=y.join(t,s);try{_.statSync(n).isDirectory()&&".git"!==s&&e(n)}catch{}}}catch{}}(e),n}isCacheValid(e,t){const n=this.getGitignorePaths(e,e);if(n.length!==t.gitignorePaths.length)return!1;for(const e of n){const n=t.gitignorePaths.find(t=>t.path===e.path);if(!n)return!1;if(e.mtime!==n.mtime)return!1}return!0}buildIgnoreInstance(e){const t=this.cache.get(e);if(t&&this.isCacheValid(e,t))return t.instance;const n=w.default();n.add(".git"),n.add(".gitignore"),n.add(".lcignore");const s=[];return function e(t,o){const i=y.join(t,".gitignore");try{if(_.existsSync(i)&&_.statSync(i).isFile()){const e=_.statSync(i);s.push({path:i,mtime:e.mtimeMs});!function(e,t,s){const o=y.relative(t,e)||".",i="."===o?"":o.replace(/\\/g,"/")+"/",r=s.split("\n");for(const e of r){const t=e.trim();if(!t||t.startsWith("#"))continue;const s=t.replace(/\\/g,"/");if("."===o)n.add(s);else if(s.startsWith("!")){const e=s.slice(1);e.startsWith("/")?n.add("!"+(i+e.slice(1)).replace(/\/+/g,"/")):n.add("!"+(i+e).replace(/\/+/g,"/"))}else if(s.startsWith("/")){const e=s.slice(1);n.add((i+e).replace(/\/+/g,"/"))}else if(s.includes("**"))n.add(s),i&&n.add((i+s).replace(/\/+/g,"/"));else{const e=(i+s).replace(/\/+/g,"/");n.add(e)}}}(t,o,_.readFileSync(i,"utf-8"))}}catch{}try{const n=_.readdirSync(t);for(const s of n){const n=y.join(t,s);try{_.statSync(n).isDirectory()&&".git"!==s&&e(n,o)}catch{}}}catch{}}(e,e),this.cache.set(e,{instance:n,gitignorePaths:s}),n}clearCache(){this.cache.clear()}};function mt(e,t,n,s,o,i=!1){if(!i&&void 0!==t.max_depth&&function(e,t,n){return y.relative(t,e).split(y.sep).length-1>n}(e,s,t.max_depth))return{shouldSkip:!0};if(!me(e,s))return{shouldSkip:!0};const r=o.get(e);if(!r||!r.isFile())return{shouldSkip:!0};if(he(e,oe))return{shouldSkip:!0};const l=r.size,a=nt(e);if(i){if(t.no_empty&&0===l)return{shouldSkip:!0};if(t.no_binary&&We(e))return{shouldSkip:!0};const s=a.toLowerCase().replace(/^\./,"");if(n.exclude_extensions.length>0&&n.exclude_extensions.includes(s))return{shouldSkip:!0};if(n.include_extensions.length>0&&!n.include_extensions.includes(s))return{shouldSkip:!0};if(t.max_size){const e=qe(t.max_size);if(!(e instanceof P)&&l>e)return{shouldSkip:!0}}if(t.min_size){const e=qe(t.min_size);if(!(e instanceof P)&&l<e)return{shouldSkip:!0}}for(const t of n.exclude_patterns)if(t.test(e))return{shouldSkip:!0};const o=y.basename(e);for(const e of n.exclude_names)if(e.test(o))return{shouldSkip:!0};if(n.include_names.length>0){let e=!1;for(const t of n.include_names)if(t.test(o)){e=!0;break}if(!e)return{shouldSkip:!0}}if(t.no_hidden&&o.startsWith("."))return{shouldSkip:!0}}else if(function(e,t,n){const s=e,o=y.basename(e);if(n.combined_exclude_patterns){if(n.combined_exclude_patterns.test(s))return!0}else for(const e of n.exclude_patterns)if(e.test(s))return!0;const i=y.extname(e).replace(/^\./,"").toLowerCase();if(i){if(n.exclude_extensions_set){if(n.exclude_extensions_set.has(i))return!0}else for(const e of n.exclude_extensions)if(i===e.toLowerCase())return!0;if(n.include_extensions_set&&n.include_extensions_set.size>0){if(!n.include_extensions_set.has(i))return!0}else if(n.include_extensions.length>0){let e=!1;for(const t of n.include_extensions)if(i===t.toLowerCase()){e=!0;break}if(!e)return!0}}else if(n.include_extensions_set&&n.include_extensions_set.size>0||n.include_extensions.length>0)return!0;const r=y.dirname(e);if(n.combined_exclude_dirs){if(n.combined_exclude_dirs.test(r))return!0}else for(const e of n.exclude_dirs)if(e.test(r))return!0;if(n.include_dirs.length>0){let e=!1;for(const t of n.include_dirs)if(t.test(r)){e=!0;break}if(!e)return!0}if(n.combined_exclude_names){if(n.combined_exclude_names.test(o))return!0}else for(const e of n.exclude_names)if(e.test(o))return!0;if(n.include_names.length>0){let e=!1;for(const t of n.include_names)if(t.test(o)){e=!0;break}if(!e)return!0}if(t.no_hidden&&o.startsWith("."))return!0;try{const n=_.statSync(e).size;if(t.max_size){const e=qe(t.max_size);if(!(e instanceof P)&&n>e)return!0}if(t.min_size){const e=qe(t.min_size);if(!(e instanceof P)&&n<e)return!0}if(t.no_empty&&0===n)return!0}catch{}return!(!t.no_binary||!We(e))}(e,t,n))return{shouldSkip:!0};return{shouldSkip:!1,stats:r,size:l,ext:a}}async function ft(e,t,n,s,o,i,r){try{return await pt(e,t,n,s,o,i,r)}catch(t){return t instanceof Error&&(t instanceof P||P.fileProcessingError(e,t.message,t)),{processed:0,errors:1}}}async function pt(e,t,n,s,o,i,r){let l=0,a=0;const c=mt(e,t,s,o,i,!0);if(c.shouldSkip)return{processed:l,errors:a};const{stats:d,size:u,ext:m}=c;if(!d||void 0===u||void 0===m)return{processed:l,errors:a};if(t.rm_comments){const n=m.toLowerCase().replace(/^\./,"");if(Ze.map(e=>e.toLowerCase()).includes(n))return{processed:l,errors:a};if((()=>{if(!0===t.rm_comments)return!0;if("string"==typeof t.rm_comments){const e=B(t.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return e.includes(n)||e.includes(`.${n}`)}return!1})()){const n=ve(e);if(n.success){if(n.commentsFound){if(!t.quiet){const t=y.relative(o,e);console.log(`β Removed comments from ${t}`)}l+=1}}else{if(!t.quiet){const t=y.relative(o,e);console.error(`β Failed to remove comments from ${t}`)}a+=1}}return{processed:l,errors:a}}l+=1;let f=null,p=null,h=null,_=null,g=null,x=null,b=null;if(!t.files_only){const n=await r.get(e);let s;if(s=n?await async function(e,t,n){if(!t.comments&&!t.code_vs_comments)return{lines:He(n),commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null};const s=nt(e),o=Ze.map(e=>e.toLowerCase()).includes(s);if(t.comments||t.code_vs_comments){if(!o)try{const t=be(e,n);if(t)return{lines:t.totalLines,commentLines:t.commentLines,codeLines:t.codeLines,fullLineComments:t.fullLineComments,inlineComments:t.inlineComments,blankLines:t.blankLines,error:null}}catch(t){const s=Ke(n);return{lines:s.total,commentLines:0,codeLines:s.code,fullLineComments:0,inlineComments:0,blankLines:s.blank,error:t instanceof Error?P.commentParsingError(e,t.message,t):null}}const t=Ke(n);return{lines:t.total,commentLines:0,codeLines:t.code,fullLineComments:0,inlineComments:0,blankLines:t.blank,error:null}}return{lines:He(n),commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}(e,t,n.content):it(e,t),s.error){if("COMMENT_PARSING_ERROR"!==s.error.code||null===s.lines)return t.quiet||console.error(`Warning: Could not count lines in ${e}: ${s.error.message}`),a+=1,{processed:l,errors:a};t.quiet,f=s.lines,p=null,h=null,_=null,g=null,x=null,b=null}else f=s.lines,p=s.commentLines,h=s.codeLines,_=s.fullLineComments,g=s.inlineComments,x=s.blankLines,b=st(s)}ot(n,m,u,f,b);return!1!==t.collect_details&&(!t.max_details||n.details.length<t.max_details)&&n.details.push(rt(e,u,m,f,p,h,_,g,x)),{processed:l,errors:a}}function ht(e,t,n,s){if(e.show_progress&&!e.quiet){const e=`${Date.now()-t}ms`;process.stderr.write(`\rProcessed: ${n} files (${s} errors) in ${e}\n`)}}function _t(e){return!1}async function gt(e){const t=Date.now(),n={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},s=Xe(e);if(R(s))return s;const o=y.resolve(e.directory),i=y.dirname(o);if(!me(o,i))return P.io("Path traversal detected: file path is not safe",void 0,o);try{if(!_.statSync(o).isFile())return P.notADirectory(o);if(he(o,oe))return P.io(`File too large: exceeds maximum safe size (${oe/1048576}MB)`,void 0,o)}catch(e){return P.fileNotFound(o)}const r=new ct,l=new dt;r.get(o);const{processed:a,errors:c}=await pt(o,e,n,s,i,r,l);if(ht(e,t,a,c),0===a&&0===n.total_files){if(!mt(o,e,s,i,r,!0).shouldSkip)try{const t=_.statSync(o);if(t.isFile()){const s=nt(o),i=t.size;if(e.files_only)ot(n,s,i,null,null),!1!==e.collect_details&&n.details.push(rt(o,i,s,null,null,null,null,null,null));else{const t=it(o,e);if(!t.error){const r=st(t);ot(n,s,i,t.lines,r),!1!==e.collect_details&&n.details.push(rt(o,i,s,t.lines,t.commentLines,t.codeLines,t.fullLineComments,t.inlineComments,t.blankLines))}}}}catch(e){}}return e.rm_comments?{...n,_commentsRemoved:a}:n}async function yt(e){const t=Date.now(),{MemoryTracker:n}=await Promise.resolve().then(()=>(D(),z)),s=new n;s.checkpoint();const o={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},i=Xe(e);if(R(i))return i;const r=(l=e.directory,ut.buildIgnoreInstance(l));var l;const a=new ct,c=new dt,d=de,u={cwd:e.directory,absolute:!0,onlyFiles:!0,ignore:[],dot:!e.no_hidden,followSymbolicLinks:e.follow_links};let m=0,f=0,p=null,h=null,_=0;try{const t=function(e){return e.map(e=>"string"==typeof e?e:String("object"==typeof e&&null!==e&&"path"in e?e.path:e))}(await $.default(d,u));e.show_progress&&!e.quiet&&(p=new at(t.length),h=new lt(p));const n=function(e,t,n,s,o,i){const r=[];for(const l of e){const e=y.relative(s,l);if(i.ignores(e))continue;const a=mt(l,t,n,s,o);if(a.shouldSkip)continue;const{stats:c,ext:d}=a;if(c&&void 0!==d&&(!(n.include_extensions.length>0)||n.include_extensions.includes(d))){if(t.max_size){const e=qe(t.max_size);if(!(e instanceof P)&&c.size>e)continue}if(t.min_size){const e=qe(t.min_size);if(!(e instanceof P)&&c.size<e)continue}t.no_empty&&0===c.size||r.push(l)}}return r}(t,e,i,e.directory,a,r),l=function(e,t){const n=[];for(let s=0;s<e.length;s+=t)n.push(e.slice(s,s+t));return n}(n,Math.min(g.cpus().length,ie));for(const t of l){const r=await Promise.allSettled(t.map(t=>ft(t,e,o,i,e.directory,a,c)));s.checkpoint();for(let s=0;s<r.length;s++){const o=r[s],i=t[s];_++;const l=y.relative(e.directory,i);if(h?h.update(_,f,l):p&&(_%re!==0&&_!==n.length||p.update(_,f,l)),"fulfilled"===o.status){const e=o.value;m+=e.processed,f+=e.errors}else f++,!e.quiet&&_t()&&console.error(`Failed to process ${i}: ${o.reason}`)}}if(e.rm_comments){const t=function(e,t,n){let s=0,o=0;for(const i of e){const e=nt(i).toLowerCase().replace(/^\./,"");if(!Ze.map(e=>e.toLowerCase()).includes(e)&&(()=>{if(!0===t.rm_comments)return!0;if("string"==typeof t.rm_comments){const n=B(t.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return n.includes(e)||n.includes(`.${e}`)}return!1})()){const e=ve(i);if(e.success){if(e.commentsFound){if(!t.quiet){const e=y.relative(n,i);console.log(`β Removed comments from ${e}`)}s+=1}}else{if(!t.quiet){const e=y.relative(n,i);console.error(`β Failed to remove comments from ${e}`)}o+=1}}}return{processed:s,errors:o}}(n,e,e.directory);m+=t.processed,f+=t.errors}h?h.finish():p&&p.finish(),a.clear(),c.clear(),tt.clear(),ut.clearCache()}catch(t){return h?h.finish():p&&p.finish(),P.io(`Failed to scan directory: ${t instanceof Error?t.message:String(t)}`,t instanceof Error?t:void 0,e.directory)}s.checkpoint();const x=s.getMetrics();return o._memoryMetrics=x,ht(e,t,m,f),e.rm_comments?{...o,_commentsRemoved:m}:o}var xt=class{quiet;verboseMode;constructor(e){this.quiet=e.quiet||!1,this.verboseMode=!1}info(e){this.quiet||console.log(e)}success(e){this.quiet||console.log(b.default.green(e))}warn(e){this.quiet||console.warn(b.default.yellow(e))}error(e){console.error(b.default.red(e))}debug(e){this.verboseMode&&!this.quiet&&console.log(b.default.gray(`[DEBUG] ${e}`))}verbose(e){this.verboseMode&&!this.quiet&&console.log(b.default.gray(e))}};function bt(e){return new xt(e)}D();var vt=null,$t=!1,wt=null,kt=new Set,Lt=null,St=class{cache=new Map;getFileHash(e){try{const t=_.readFileSync(e,"utf-8");return k.createHash("sha256").update(t).digest("hex")}catch{return""}}isFileChanged(e){try{const t=_.statSync(e),n=this.cache.get(e);if(!n)return!0;if(t.mtimeMs!==n.mtime)return!0;return this.getFileHash(e)!==n.hash}catch{return!0}}updateFile(e){try{const t=_.statSync(e),n=this.getFileHash(e);this.cache.set(e,{path:e,hash:n,mtime:t.mtimeMs})}catch{}}removeFile(e){this.cache.delete(e)}clear(){this.cache.clear()}},Ct=null;async function zt(e,t=!1,n){const s=A(e.directory);if(s.error)return s.error;const o=s.path;if(!_.statSync(o).isDirectory())return P.notADirectory(e.directory);if(e.directory=o,Ct||(Ct=new St),t&&kt.size>0){const e=Array.from(kt).slice(0,10);n.info(b.default.cyan("π Changed files: "+(kt.size>10?`${kt.size} files`:e.length+" file(s)"))),e.length>0&&(e.forEach(e=>{n.verbose(` ${b.default.gray("β’")} ${e}`)}),kt.size>10&&n.verbose(b.default.gray(` ... and ${kt.size-10} more`))),n.info("")}const i=await yt(e);if(R(i))return i;kt.clear(),Ne(i,e)}function Et(e){return void 0!==e.watch_debounce?Math.max(ae,Math.min(ce,e.watch_debounce)):le}async function jt(e){const t=bt(e),n=A(e.directory);n.error&&(t.error(`Error: ${n.error.message}`),process.exit(1));const s=n.path;_.statSync(s).isDirectory()||(t.error(`Error: Not a directory: ${e.directory}`),process.exit(1)),function(e){try{const t=y.resolve(e);for(const e of ue){const n=y.resolve(e);if(t===n||t.startsWith(n+y.sep))return!1}return t!==y.parse(t).root}catch{return!1}}(s)||(t.error(`Error: Cannot watch sensitive directory: ${s}\n - System directories and root directories are not allowed\n - Please specify a project directory instead`),process.exit(1)),t.info(b.default.cyan("π Starting watch mode...\n"));const o=Et(e);void 0!==e.watch_debounce&&t.verbose(b.default.gray(`β±οΈ Watch debounce: ${o}ms\n`)),Ct=new St,kt.clear(),Lt=new _e(100,1e3);const i=await zt(e,!1,t);R(i)&&(t.error(`Error: ${i.message}`),process.exit(1)),t.info(b.default.gray("\n"+"β".repeat(60))),t.info(b.default.gray(`π Watching for changes... (Press ${b.default.yellow("Ctrl+C")} to stop)`));try{wt=_.watch(s,{recursive:!0},(n,s)=>{s&&(Lt&&!Lt.shouldAllow()||e.export&&s.startsWith("LocIO-report.")||function(e,t,n){vt&&clearTimeout(vt),t&&kt.add(t);const s=Et(e);vt=setTimeout(async()=>{if($t)return;$t=!0,n.info(b.default.cyan("π Changes detected. Rescanning...\n"));const t=await zt(e,!0,n);R(t)?(n.error(`\nβ Error: ${t.message}`),t.suggestion&&n.warn(`\nπ‘ Suggestion: ${t.suggestion}`)):(n.info(b.default.gray("\n"+"β".repeat(60))),n.info(b.default.gray(`π Watching for changes... (Press ${b.default.yellow("Ctrl+C")} to stop)`))),$t=!1},s)}(e,s,t))}),wt.on("error",e=>{t.error(`\nWatch error: ${e.message}`),t.warn("Note: Recursive watching may not be supported on all systems.")})}catch(e){t.error(`Failed to start watch mode: ${e instanceof Error?e.message:String(e)}`),t.warn("Note: Recursive watching may not be supported on all systems."),process.exit(1)}const r=()=>{vt&&clearTimeout(vt),wt&&wt.close(),Ct&&(Ct.clear(),Ct=null),kt.clear(),t.info(b.default.gray("\n\nπ Watch mode stopped.")),process.exit(0)};process.on("SIGINT",r),process.on("SIGTERM",r)}async function Ft(e){const t=await async function(e){const t=bt(e);if(e.version)return void t.info(`LocIO ${O()}`);if(e.watch)return void await jt(e);const n=A(e.directory);if(n.error)return n.error;const s=n.path,o=_.statSync(s);let i;if(o.isDirectory()){const e=X(s);"unknown"!==e&&t.info(`${b.default.cyan("Detected project type:")} ${b.default.blue.bold(Ue(e))}\n`)}e.directory=s;const r=e.quiet?null:new h;if(e.rm_comments){if(t.info(b.default.cyan("Removing comments from files...\n")),i=o.isFile()?await gt(e):await yt(e),R(i))return i;const n=i._commentsRemoved||0;return void(n>0?t.success(`\nβ Comments removed successfully from ${n} file(s)!\n`):t.warn("\nβΉ No comments found in any files.\n"))}if(i=o.isFile()?await gt(e):await yt(e),R(i))return i;r&&!R(i)&&r.trackScan(e,i),Ne(i,e)}(e);R(t)&&(console.error(function(e){let t=`\n${b.default.red.bold("β Error:")} ${b.default.white(e.message)}\n`;e.filePath&&(t+=`${b.default.gray("π File:")} ${b.default.white(e.filePath)}\n`),e.suggestion&&(t+=`\n${b.default.yellow.bold("π‘ Suggestion:")}\n${b.default.yellow(e.suggestion)}\n`);const n=(s=e.code,{DIRECTORY_NOT_FOUND:["locio . # Scan current directory","locio ./src # Scan specific directory","locio /path/to/directory # Scan absolute path"],FILE_NOT_FOUND:["locio ./file.ts # Scan a specific file","locio src/index.ts # Scan file with relative path"],NOT_A_DIRECTORY:["locio ./file.ts # Use file path directly","locio . # Use current directory instead"],INVALID_SIZE_FORMAT:["locio . --max-size 5MB # Valid: number + unit","locio . --min-size 1KB # Valid: KB, MB, GB, TB"],INVALID_REGEX:["locio . --exclude 'node_modules' # Simple pattern","locio . --exclude '.*\\.log$' # Escaped regex"],EXPORT_PATH_ERROR:["locio . --export json # Export to default location","locio . --export json --export-path ./reports # Custom path"]}[s]||[]);var s;return n.length>0&&(t+=`\n${b.default.cyan.bold("π Example Commands:")}\n`,n.forEach(e=>{t+=` ${b.default.gray("$")} ${b.default.white(e)}\n`})),t+=`\n${b.default.blue("π Documentation:")} ${b.default.underline("https://locio.js.org")}\n`,e.cause&&"object"==typeof e.cause&&"message"in e.cause&&(t+=`\n${b.default.gray("π Details:")} ${b.default.gray(String(e.cause.message))}\n`),t}(t)),process.exit(1)),e.watch||process.exit(0)}(async function(){if(2===v.argv.length&&v.stdin.isTTY){if(!await async function(){const e=O();x.intro(b.default.cyan.bold(`LocIO CLI v${e}`)),x.note("A fast, flexible line and file counter for your projects.","About");const t=await x.select({message:"Select an option:",options:[{value:"1",label:"Quick scan of current directory (default settings)"},{value:"2",label:"Show common command examples"},{value:"3",label:"View full help (same as --help)"},{value:"q",label:"Quit"}]});if(x.isCancel(t))return x.outro(b.default.green("Thank you for using LocIO.")),!1;switch(t){case"1":return x.note('Running quick scan on current directory (".") with default settings...',"Starting scan"),!0;case"2":return x.note(["locio . # Quick scan","locio . --files-only # Show only file counts","locio . --lines-only # Show only line counts",'locio . --exclude "target" # Ignore patterns',"locio . --include-ext ts,js # Filter by extension","locio . --export json # Export to JSON"].join("\n"),"Common Commands"),x.note("Use --help for more options","Tip"),!1;case"3":return console.log(),W().outputHelp(),console.log(),!1;case"q":return x.outro(b.default.green("Thank you for using LocIO.")),!1;default:return!1}}())return}const e=function(){const e=W();e.parse();const t=e.opts(),n=e.args,s=t.excludeExt?B(t.excludeExt):[],o=t.includeExt?B(t.includeExt):[];return{directory:n[0]||".",files_only:t.filesOnly||!1,lines_only:t.linesOnly||!1,exclude_patterns:t.exclude||[],exclude_extensions:s,include_extensions:o,exclude_dirs:t.excludeDir||[],include_dirs:t.includeDir||[],exclude_names:t.excludeName||[],include_names:t.includeName||[],max_size:t.maxSize,min_size:t.minSize,no_hidden:t.noHidden||!1,no_empty:t.noEmpty||!1,follow_links:t.followLinks||!1,max_depth:t.maxDepth,show_stats:t.stats||!1,show_progress:!0!==t.noProgress,no_binary:t.noBinary||!1,ignore_case:t.ignoreCase||!1,quiet:t.quiet||!1,export:N(t.export),export_path:t.exportPath,version:!1,watch:t.watch||!1,watch_debounce:t.watchDebounce,comments:!0!==t.noComments,code_vs_comments:t.codeVsComments||!1,rm_comments:(()=>{const e=t.rmComments;return!!e&&(!0===e||e)})(),top_files:t.topFiles,top_dirs:t.topDirs}}();await Ft(e)})().catch(e=>{console.error("Unexpected error:",e),v.exit(1)});
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import*as e from"process";import*as n from"readline";import{Command as t}from"commander";import*as o from"fs";import{readFileSync as s}from"fs";import*as i from"path";import{dirname as r,join as l}from"path";import{fileURLToPath as c}from"url";import a from"chalk";import d from"fast-glob";import m from"ignore";var u=Object.defineProperty,f=(e,n,t)=>((e,n,t)=>n in e?u(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t)(e,"symbol"!=typeof n?n+"":n,t),p=r(c(import.meta.url));function _(){try{const e=[l(p,"../package.json"),l(p,"../../package.json"),l(process.cwd(),"package.json")];for(const n of e)try{const e=JSON.parse(s(n,"utf-8"));if(e.version)return e.version}catch{continue}return"0.0.0"}catch(e){return"0.0.0"}}var y=class e extends Error{constructor(e,n,t){super(e),this.cause=n,f(this,"suggestion"),this.name="LineCounterError",this.suggestion=t}static io(n,t){return new e(`IO error: ${n}`,t,"Check if the file/directory exists, you have read permissions, and there's sufficient disk space.")}static invalidSizeFormat(n){return new e(`Invalid size format: ${n}`,void 0,"Size format should be a number followed by a unit (e.g., '5MB', '1KB', '500B').\nValid units: B, KB, MB, GB, TB (case-insensitive).")}static invalidRegex(n,t){return new e(`Invalid regex pattern: ${n}${t?`: ${t.message}`:""}`,t,"Check your regex pattern syntax. Common issues:\n - Escape special characters with backslash (\\* for literal *)\n - Use proper grouping syntax (parentheses, brackets)\n - Verify quantifiers are properly placed\n - Test your pattern at https://regex101.com")}static directoryNotFound(n){let t;try{t=i.resolve(n)}catch{t=n}return new e(`Directory not found: ${n}`,void 0,`The path "${n}" does not exist.\n - Check if the path is correct (resolved: ${t})\n - Use relative paths like '.' for current directory\n - Verify you have read permissions\n - Check if it's a file instead of a directory (use the file path directly)`)}static notADirectory(n){return new e(`Not a directory: ${n}`,void 0,`"${n}" exists but is not a directory.\n - If it's a file, you can scan it directly: locio <file-path>\n - If you meant a directory, check the path spelling\n - Use 'locio .' to scan the current directory`)}static fileNotFound(n){return new e(`File not found: ${n}`,void 0,`The file "${n}" does not exist.\n - Check if the file path is correct\n - Verify the file extension\n - Ensure you have read permissions`)}static exportPathError(n,t){return new e(`Export path error: ${n}`,void 0,`Cannot write to export path "${n}": ${t}\n - Ensure the directory exists or can be created\n - Check write permissions\n - Verify there's sufficient disk space\n - Use an absolute path if relative paths aren't working`)}};function h(e){return e instanceof y}function g(e,n){return n&&Array.isArray(n)?[...n,e]:[e]}function x(e){return e.split(",").map(e=>e.trim()).filter(Boolean)}function b(e){if(void 0===e)return;if(!0===e)return"human";const n={json:"json",csv:"csv",tsv:"tsv",markdown:"markdown",md:"markdown",html:"html",human:"human",txt:"human"},t=x(e).map(e=>n[e.toLowerCase()]).filter(e=>void 0!==e);return t.length>0?1===t.length?t[0]:t:void 0}function $(e){const n=i.resolve(e);if(!o.existsSync(n))return{path:null,error:y.directoryNotFound(e)};const t=o.statSync(n);return t.isDirectory()||t.isFile()?{path:n,error:null}:{path:null,error:y.notADirectory(e)}}function v(e,n){const t=e.length>n.length?e:n;if(0===t.length)return 1;const o=function(e,n){const t=[];for(let e=0;e<=n.length;e++)t[e]=[e];for(let n=0;n<=e.length;n++)t[0][n]=n;for(let o=1;o<=n.length;o++)for(let s=1;s<=e.length;s++)n.charAt(o-1)===e.charAt(s-1)?t[o][s]=t[o-1][s-1]:t[o][s]=Math.min(t[o-1][s-1]+1,t[o][s-1]+1,t[o-1][s]+1);return t[n.length][e.length]}(e,n);return(t.length-o)/t.length}function k(){const e=new t,n=["files-only","lines-only","exclude","exclude-ext","include-ext","exclude-dir","include-dir","exclude-name","include-name","max-size","min-size","no-hidden","no-empty","follow-links","max-depth","stats","no-progress","no-binary","ignore-case","quiet","export","export-path","watch","no-comments","code-vs-comments","rm-comments","top-files","top-dirs","version"];return e.configureOutput({writeErr:e=>{if(e.includes("unknown option")){const t=e.match(/unknown option ['"]--?([^'"]+)['"]/);if(t){const e=t[1],o=function(e,n,t=3){return n.map(n=>({option:n,score:v(e,n)})).sort((e,n)=>n.score-e.score).filter(e=>e.score>.3).slice(0,t).map(e=>e.option)}(e,n);if(o.length>0){const n=1===o.length?"Did you mean this?":"Did you mean one of these?";process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ ${n}\n`+o.map(e=>` β’ --${e}`).join("\n")+"\n\nRun 'locio --help' to see all available options.\n\n"),process.exit(1)}process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ This option doesn't exist. Run 'locio --help' to see all available options.\n\n`),process.exit(1)}}process.stderr.write(e)}}),e.name("LocIO").description("A powerful CLI tool to count lines and files in directories").version(_(),"-v, --version","Show version number").argument("[directory]","Directory to scan",".").option("-f, --files-only","Count only files").option("-l, --lines-only","Count only lines").option("-e, --exclude <pattern>","Exclude files matching pattern",g).option("--exclude-ext <extensions>","Exclude file extensions (comma-separated)").option("--include-ext <extensions>","Include only file extensions (comma-separated)").option("--exclude-dir <pattern>","Exclude directories matching pattern",g).option("--include-dir <pattern>","Include only directories matching pattern",g).option("--exclude-name <pattern>","Exclude files by name pattern",g).option("--include-name <pattern>","Include only files by name pattern",g).option("--max-size <size>","Maximum file size (e.g., 5MB)").option("--min-size <size>","Minimum file size (e.g., 1KB)").option("--no-hidden","Exclude hidden files").option("--no-empty","Exclude empty files").option("--follow-links","Follow symbolic links").option("--max-depth <depth>","Maximum directory depth",parseInt).option("--stats","Show detailed statistics").option("--no-progress","Disable progress indicator (enabled by default)").option("--no-binary","Exclude binary files").option("-i, --ignore-case","Case-insensitive pattern matching").option("-q, --quiet","Quiet mode (minimal output)").option("--export [format]","Write report to LocIO-report.{ext} in the given format (human, json, csv, tsv, markdown, html). Multiple formats can be specified comma-separated (e.g., json,html,markdown)").option("--export-path <dir>","Specify output directory for exported reports. Files will use default naming (LocIO-report.{ext}). Directories will be created automatically if they don't exist").option("-w, --watch","Watch directory for changes and auto-rescan").option("--no-comments","Disable comment counting (enabled by default)").option("--code-vs-comments","Show code vs comments ratio (automatically enables --comments)").option("--rm-comments [extensions]","Remove comments from files (modifies files in place). Optionally specify file extensions (comma-separated, e.g., js,ts,py). If no extensions specified, all files are processed.").option("--top-files <n>","Show top N largest files by size",parseInt).option("--top-dirs <n>","Show top N directories with most files",parseInt),e}var L=[{type:"nextjs",files:["next.config.js","next.config.ts","next.config.mjs","next.config.cjs"],packageJsonDeps:["next"],packageJsonDevDeps:["next"],priority:100},{type:"angular",files:["angular.json","angular-cli.json"],packageJsonDeps:["@angular/core"],packageJsonDevDeps:["@angular/cli","@angular/core"],priority:90},{type:"vue",files:["vue.config.js","vue.config.ts","vite.config.js","vite.config.ts"],packageJsonDeps:["vue"],packageJsonDevDeps:["vue","@vitejs/plugin-vue","vite"],dirs:[".nuxt"],priority:85},{type:"react",files:["react-scripts"],packageJsonDeps:["react"],packageJsonDevDeps:["react","react-scripts","@vitejs/plugin-react","vite"],dirs:["node_modules/react"],priority:80},{type:"typescript",files:["tsconfig.json","tsconfig.app.json","tsconfig.base.json"],priority:70},{type:"nodejs",files:["package.json"],priority:75},{type:"rust",files:["Cargo.toml","Cargo.lock"],priority:100},{type:"python",files:["requirements.txt","setup.py","pyproject.toml","Pipfile","poetry.lock","manage.py","setup.cfg","Pipfile.lock"],dirs:["__pycache__"],priority:100},{type:"go",files:["go.mod","go.sum","Gopkg.toml","Gopkg.lock"],priority:100},{type:"java",files:["pom.xml","build.gradle","build.gradle.kts","settings.gradle"],dirs:[".gradle"],priority:100},{type:"csharp",files:["*.csproj","*.sln","project.json","*.fsproj","*.vbproj"],dirs:[".vs"],priority:100},{type:"ruby",files:["Gemfile","Rakefile","Gemfile.lock"],dirs:[".bundle"],priority:100},{type:"php",files:["composer.json","composer.lock","artisan"],dirs:["vendor"],priority:100},{type:"swift",files:["Package.swift","*.xcodeproj","*.xcworkspace"],dirs:[".build"],priority:100},{type:"kotlin",files:["build.gradle.kts","settings.gradle.kts"],dirs:[".gradle"],priority:100},{type:"dart",files:["pubspec.yaml","pubspec.yml","pubspec.lock"],dirs:[".dart_tool"],priority:100}],w={nodejs:{exclude_dirs:["node_modules",".next",".nuxt",".cache","dist","build",".turbo",".vercel",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},nextjs:{exclude_dirs:["node_modules",".next",".vercel","out","dist","build",".turbo"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},react:{exclude_dirs:["node_modules","build","dist",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},vue:{exclude_dirs:["node_modules","dist",".nuxt",".cache","coverage",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},angular:{exclude_dirs:["node_modules","dist",".angular","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},typescript:{exclude_dirs:["node_modules","dist","build",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},rust:{exclude_dirs:["target",".cargo"],exclude_extensions:[],exclude_names:["Cargo.lock"]},python:{exclude_dirs:["__pycache__",".pytest_cache",".mypy_cache",".ruff_cache",".venv","venv","env",".env","build","dist",".*\\.egg-info",".tox",".coverage","htmlcov",".hypothesis"],exclude_extensions:["pyc","pyo","pyd","so"],exclude_names:[".python-version","pip-log.txt","pip-delete-this-directory.txt"]},go:{exclude_dirs:["vendor",".cache"],exclude_extensions:[],exclude_names:["go.sum"]},java:{exclude_dirs:["target","build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar","war","ear"],exclude_names:[".project",".*\\.iml"]},csharp:{exclude_dirs:["bin","obj",".vs","packages","TestResults","[Bb]in","[Oo]bj"],exclude_extensions:["dll","exe","pdb"],exclude_names:[]},ruby:{exclude_dirs:["vendor",".bundle","tmp","log"],exclude_extensions:[],exclude_names:["Gemfile.lock"]},php:{exclude_dirs:["vendor","node_modules"],exclude_extensions:[],exclude_names:["composer.lock"]},swift:{exclude_dirs:[".build",".swiftpm","DerivedData"],exclude_extensions:[],exclude_names:["Package.resolved"]},kotlin:{exclude_dirs:["build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar"],exclude_names:[".project",".*\\.iml"]},dart:{exclude_dirs:[".dart_tool","build"],exclude_extensions:[],exclude_names:["pubspec.lock"]},unknown:{exclude_dirs:[],exclude_extensions:[],exclude_names:[]}};function C(e,n,t){if(!e||!n&&!t)return!1;const o={...e.dependencies||{},...e.devDependencies||{}};if(n)for(const e of n)if(o[e])return!0;if(t)for(const e of t)if(o[e])return!0;return!1}function S(e,n){if(!e||!n||!e.scripts)return!1;for(const t of n)if(e.scripts[t])return!0;return!1}function j(e,n){if(n.includes("*"))try{const t=o.readdirSync(e),s=n.replace(/\*/g,".*"),r=new RegExp(`^${s}$`);return t.some(n=>{const t=i.join(e,n);try{const e=o.statSync(t);return(e.isFile()||e.isDirectory())&&r.test(n)}catch{return!1}})}catch{return!1}else{const t=i.join(e,n);try{if(o.existsSync(t)){return o.statSync(t).isFile()}}catch{}}return!1}function z(e,n){const t=i.join(e,n);try{if(o.existsSync(t)){return o.statSync(t).isDirectory()}}catch{}return!1}function E(e,n=2){try{const t=o.readdirSync(e);for(const s of t){const t=i.join(e,s);try{const e=o.statSync(t);if(e.isFile()&&(s.endsWith(".ts")||s.endsWith(".tsx")))return!0;if(e.isDirectory()&&n>0&&!s.startsWith(".")&&"node_modules"!==s&&E(t,n-1))return!0}catch{}}}catch{}return!1}function F(e){const n=i.resolve(e);let t=n;try{o.statSync(n).isFile()&&(t=i.dirname(n))}catch{}const s=new Map,r=function(e){const n=i.join(e,"package.json");try{if(o.existsSync(n)){const e=o.readFileSync(n,"utf-8");return JSON.parse(e)}}catch{}return null}(t);for(const e of L){let n=0;const l=[];for(const o of e.files)j(t,o)&&(n+=30,l.push(`file:${o}`));if(e.dirs)for(const o of e.dirs)z(t,o)&&(n+=20,l.push(`dir:${o}`));if((e.packageJsonDeps||e.packageJsonDevDeps)&&C(r,e.packageJsonDeps,e.packageJsonDevDeps)){n+=50;const t=[...e.packageJsonDeps||[],...e.packageJsonDevDeps||[]];l.push(`dep:${t.join(",")}`)}if(e.packageJsonScripts&&S(r,e.packageJsonScripts)&&(n+=15,l.push(`script:${e.packageJsonScripts.join(",")}`)),"typescript"===e.type&&(j(t,"tsconfig.json")&&(n+=30,l.push("file:tsconfig.json")),E(t)&&(n+=20,l.push("typescript-files")),r&&j(t,"package.json"))){C(r,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(n=Math.floor(.5*n),l.push("nodejs-backend-penalty"))}if("nodejs"===e.type&&j(t,"package.json")&&(j(t,"tsconfig.json")||E(t))&&(n+=40,l.push("nodejs-with-typescript")),"react"===e.type)try{const e=o.readdirSync(t);e.some(e=>{const n=i.join(t,e);try{return o.statSync(n).isFile()&&(e.endsWith(".jsx")||e.endsWith(".tsx"))}catch{return!1}})&&(n+=15,l.push("jsx-files"))}catch{}n=Math.floor(n*(1+e.priority/100)),n>0&&s.set(e.type,{type:e.type,score:n,indicators:l})}if(r){if(!Array.from(s.keys()).some(e=>"react"===e||"vue"===e||"angular"===e||"nextjs"===e)){const e=j(t,"tsconfig.json")||E(t);if(e&&j(t,"package.json")){C(r,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(s.has("nodejs")||s.set("nodejs",{type:"nodejs",score:55,indicators:["package.json","nodejs-backend-with-typescript"]})),s.has("typescript")||s.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]})}else e?s.has("typescript")||s.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]}):s.has("nodejs")||s.set("nodejs",{type:"nodejs",score:30,indicators:["package.json"]})}}return Array.from(s.values()).sort((e,n)=>n.score-e.score)}function D(e){const n=F(e);return 0===n.length?"unknown":n[0].type}function T(e){const n=[];let t="",o="",s=!1;switch(e.toLowerCase().replace(/^\./,"")){case"js":case"jsx":case"ts":case"tsx":case"c":case"cpp":case"cc":case"cxx":case"h":case"hpp":case"java":case"cs":case"php":case"swift":case"go":case"rust":case"rs":case"dart":case"kt":case"scala":case"sc":n.push("//"),t="/*",o="*/",s=!0;break;case"sh":case"bash":case"zsh":case"fish":case"py":case"python":case"rb":case"ruby":case"r":case"pl":case"perl":case"yaml":case"yml":case"toml":case"conf":case"ini":case"cfg":case"dockerfile":case"makefile":case"make":case"cmake":case"ps1":case"psm1":case"ex":case"exs":n.push("#");break;case"html":case"htm":case"xml":case"xhtml":case"svg":n.push("\x3c!--"),t="\x3c!--",o="--\x3e",s=!0;break;case"css":case"scss":case"sass":case"less":case"styl":t="/*",o="*/",s=!0;break;case"sql":n.push("--"),t="/*",o="*/",s=!0;break;case"lua":n.push("--"),t="--[[",o="]]",s=!0;break;case"pas":case"p":case"pp":case"fs":case"fsi":case"fsx":n.push("//"),t="(*",o="*)",s=!0;break;case"hs":case"lhs":n.push("--"),t="{-",o="-}",s=!0;break;case"erl":case"hrl":case"m":case"matlab":n.push("%");break;case"vhd":case"vhdl":n.push("--");break;case"bat":case"cmd":n.push("::");break;case"vbs":n.push("'");break;case"clj":case"cljs":case"cljc":case"lisp":case"lsp":case"el":case"rkt":case"rktl":n.push(";");break;case"ml":case"mli":t="(*",o="*)",s=!0;break;default:n.push("//","#","--")}return{singleLine:n,multiLineStart:t,multiLineEnd:o,supportsMultiLine:s}}function O(e,n,t){let o=0,s=!1,i=0,r=-1;const l=[];let c=-1,a=-1;for(;i<e.length;){const d=e[i];if(s)s=!1,i++;else if("\\"!==d||0===o){if(3===o&&"$"===d&&i+1<e.length&&"{"===e[i+1]){let n=1;for(i+=2;i<e.length&&n>0;)"{"===e[i]?n++:"}"===e[i]&&n--,i++;continue}if(0===o){if('"'===d)o=2;else if("'"===d)o=1;else if("`"===d)o=3;else if("/"===d&&i+1<e.length){const t=e[i+1];if("/"===t||"*"===t){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){l.push({pos:i,marker:t});break}n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i),i++;continue}{const n=i>0?e[i-1]:" ";/[\s,;=([{!&|?:]/.test(n)&&(o=4,r=i)}}}else if(2===o&&'"'===d)o=0;else if(1===o&&"'"===d)o=0;else if(3===o&&"`"===d)o=0;else if(4===o){if("\\"===d){i+1<e.length?i+=2:i++;continue}if("/"===d)if(i+1<e.length){const n=e[i+1];if(/[gimsuvy]/.test(n)){let n=i+1;for(;n<e.length&&/[gimsuvy]/.test(e[n]);)n++;(n>=e.length||!/[a-zA-Z0-9_]/.test(e[n]))&&(o=0,r=-1,i=n-1)}else/[a-zA-Z0-9_]/.test(n)||(o=0,r=-1)}else o=0,r=-1;else if(" "===d||"\t"===d){const n=i-r-1;let t=!0;for(let n=r+1;n<i;n++)if(" "!==e[n]&&"\t"!==e[n]){t=!1;break}if(t&&n<=2){let n=i+1;for(;n<e.length&&(" "===e[n]||"\t"===e[n]);)n++;n<e.length&&/[0-9;,)}\]\]]/.test(e[n])&&(o=0,r=-1)}}else/[;,)}\]\]]/.test(d)&&(o=0,r=-1)}if(0===o){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){l.push({pos:i,marker:t});break}if(n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i),n.supportsMultiLine&&t&&e.substring(i).startsWith(n.multiLineEnd)){a=i;break}}i++}else s=!0,i++}if(t){if(-1!==a){const t=e.substring(0,a).trim(),o=e.substring(a+n.multiLineEnd.length).trim();return{commentStart:0,commentEnd:a+n.multiLineEnd.length,isMultiLine:!0,endsMultiLine:!0,commentMarker:n.multiLineEnd,hasCodeBefore:t.length>0,hasCodeAfter:o.length>0}}return{commentStart:0,commentEnd:e.length,isMultiLine:!0,endsMultiLine:!1,commentMarker:n.multiLineEnd,hasCodeBefore:!1,hasCodeAfter:!1}}if(n.supportsMultiLine&&-1!==c){const t=e.substring(0,c).trim(),o=e.indexOf(n.multiLineEnd,c),s=-1!==o,i=s?e.substring(o+n.multiLineEnd.length).trim():"";return{commentStart:c,commentEnd:s?o+n.multiLineEnd.length:e.length,isMultiLine:!0,endsMultiLine:s,commentMarker:n.multiLineStart,hasCodeBefore:t.length>0,hasCodeAfter:i.length>0}}if(l.length>0){const n=l[0],t=e.substring(0,n.pos).trim();return{commentStart:n.pos,commentEnd:e.length,isMultiLine:!1,endsMultiLine:!1,commentMarker:n.marker,hasCodeBefore:t.length>0,hasCodeAfter:!1}}return null}function M(e){try{const n=o.readFileSync(e,"utf-8"),t=n.split(/\r?\n/),s=T(i.extname(e));let r=!1;const l=[];let c=!1;for(const e of t){const n=e,t=R(e,s,r);t.line!==n&&(c=!0),!t.line.trim()&&t.isEmpty||l.push(t.line),r=t.inMultiLineComment}const a=l.join("\n");return c||a!==n?(o.writeFileSync(e,a,"utf-8"),{success:!0,commentsFound:!0}):{success:!0,commentsFound:!1}}catch{return{success:!1,commentsFound:!1}}}function I(e){const n=e.replace(/^\/\//,"").replace(/^\/\*/,"").replace(/\*\/$/,"").trim().toLowerCase();return n.startsWith("eslint")||n.startsWith("@eslint")||n.includes("eslint-disable")||n.includes("eslint-enable")}function R(e,n,t){if(t){const t=e.indexOf(n.multiLineEnd);if(-1!==t){const o=e.substring(0,t+n.multiLineEnd.length),s=e.substring(t+n.multiLineEnd.length);return I(o)?{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length}:{line:s.trimEnd(),inMultiLineComment:!1,isEmpty:0===s.trim().length}}return I(e)?{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length}:{line:"",inMultiLineComment:!0,isEmpty:!0}}let o=0,s=!1,i=0,r=-1;const l=[];let c=-1;for(;i<e.length;){const t=e[i];if(s)s=!1,i++;else if("\\"!==t||0===o){if(3===o&&"$"===t&&i+1<e.length&&"{"===e[i+1]){let n=1;for(i+=2;i<e.length&&n>0;)"{"===e[i]?n++:"}"===e[i]&&n--,i++;continue}if(0===o){if('"'===t)o=2;else if("'"===t)o=1;else if("`"===t)o=3;else if("/"===t&&i+1<e.length){const t=e[i+1];if("/"===t||"*"===t){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){l.push(i);break}n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i),i++;continue}{const n=i>0?e[i-1]:" ";/[\s,;=([{!&|?:]/.test(n)&&(o=4,r=i)}}}else if(2===o&&'"'===t)o=0;else if(1===o&&"'"===t)o=0;else if(3===o&&"`"===t)o=0;else if(4===o){if("\\"===t){i+1<e.length?i+=2:i++;continue}if("/"===t)if(i+1<e.length){const n=e[i+1];if(/[gimsuvy]/.test(n)){let n=i+1;for(;n<e.length&&/[gimsuvy]/.test(e[n]);)n++;(n>=e.length||!/[a-zA-Z0-9_]/.test(e[n]))&&(o=0,r=-1,i=n-1)}else/[a-zA-Z0-9_]/.test(n)||(o=0,r=-1)}else o=0,r=-1;else if(" "===t||"\t"===t){const n=i-r-1;let t=!0;for(let n=r+1;n<i;n++)if(" "!==e[n]&&"\t"!==e[n]){t=!1;break}if(t&&n<=2){let n=i+1;for(;n<e.length&&(" "===e[n]||"\t"===e[n]);)n++;n<e.length&&/[0-9;,)}\]\]]/.test(e[n])&&(o=0,r=-1)}}else/[;,)}\]\]]/.test(t)&&(o=0,r=-1)}if(0===o){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){l.push(i);break}n.supportsMultiLine&&-1===c&&e.substring(i).startsWith(n.multiLineStart)&&(c=i)}i++}else s=!0,i++}if(-1!==c){const t=e.substring(0,c),o=e.indexOf(n.multiLineEnd,c+n.multiLineStart.length);if(-1!==o){const s=e.substring(c,o+n.multiLineEnd.length),i=e.substring(o+n.multiLineEnd.length);if(I(s))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};const r=(t+i).trimEnd();return{line:r,inMultiLineComment:!1,isEmpty:0===r.length}}{if(I(e.substring(c)))return{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length};const n=t.trimEnd();return{line:n,inMultiLineComment:!0,isEmpty:0===n.length}}}if(l.length>0){const t=l[0];for(const o of n.singleLine)if(e.substring(t).startsWith(o)){if(I(e.substring(t+o.length)))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};break}const o=e.substring(0,t).trimEnd();return{line:o,inMultiLineComment:!1,isEmpty:0===o.length}}return{line:e,inMultiLineComment:!1,isEmpty:!1}}function q(e){const n=["B","KB","MB","GB","TB"];let t=e,o=0;for(;t>=1024&&o<n.length-1;)t/=1024,o+=1;return 0===o?`${Math.floor(t)} ${n[o]}`:`${t.toFixed(2)} ${n[o]}`}function B(e){return{codeLines:e.code_lines||0,commentLines:e.comment_lines||0,fullLineComments:e.full_line_comments||0,inlineComments:e.inline_comments||0}}function W(e,n,t,o,s){let i=` (${e} code, ${n} comments`;return void 0!==s&&s>0&&(i+=`, ${s} blank`),(t>0||o>0)&&(i+=`: ${t} full-line, ${o} inline`),i+=")",i}function A(e,n,t,o,s){let i=` ${a.gray(`(${a.blue(e)} code, ${a.cyan(n)} comments`)}`;return void 0!==s&&s>0&&(i+=a.gray(`, ${a.gray(s)} blank`)),(t>0||o>0)&&(i+=a.gray(`: ${a.yellow(t)} full-line, ${a.magenta(o)} inline`)),i+=a.gray(")"),i}function J(e,n){return(e.comments||e.show_stats)&&!e.files_only&&n}function N(e,n,t){return{sizeStr:q(e),linesStr:null===n||t.files_only?"":` | ${n} lines`}}function P(e){const n={};for(const t of e)n[t.directory]||(n[t.directory]=[]),n[t.directory].push(t);return n}function U(e){try{return o.statSync(e.directory).isFile()}catch{return!1}}function G(e){const n=e.directory;try{if(o.statSync(n).isFile())return i.basename(n)}catch{}return"."===n?"current":n}function V(e){return{nodejs:"Node.js",rust:"Rust",python:"Python",go:"Go",java:"Java",csharp:"C#",ruby:"Ruby",php:"PHP",swift:"Swift",kotlin:"Kotlin",dart:"Dart",typescript:"TypeScript",vue:"Vue.js",react:"React",angular:"Angular",nextjs:"Next.js",unknown:"Unknown"}[e]||e}function K(e,n){return[...e.details].sort((e,n)=>n.size-e.size).slice(0,n)}function H(e,n){const t={};for(const n of e.details)t[n.directory]||(t[n.directory]={fileCount:0,totalSize:0,totalLines:0}),t[n.directory].fileCount+=1,t[n.directory].totalSize+=n.size,null!==n.lines&&(t[n.directory].totalLines+=n.lines);return Object.entries(t).map(([e,n])=>({directory:e,...n})).sort((e,n)=>n.fileCount-e.fileCount).slice(0,n)}function Q(e,n,t){switch(e){case"human":return function(e,n){let t="";if(n.quiet)return t+=`${e.total_files} ${e.total_lines}\n`,t;t+="=".repeat(60)+"\n",t+="LocIO RESULTS".padStart(37).padEnd(60)+"\n",t+="=".repeat(60)+"\n\n",t+=`Directory: ${G(n)}\n`,n.lines_only||(U(n)?t+=`\nSize: ${q(e.total_size)}\n`:(t+=`\nTotal Files: ${e.total_files}\n`,t+=`\nTotal Files Size: ${q(e.total_size)}\n`)),!n.files_only&&(t+=`\nTotal Lines: ${e.total_lines}\n`,(n.comments||n.show_stats)&&void 0!==e.total_comment_lines&&(t+=`Total Comment Lines: ${e.total_comment_lines}\n`,void 0!==e.total_full_line_comments&&(t+=` - Full Line Comments: ${e.total_full_line_comments}\n`),void 0!==e.total_inline_comments&&(t+=` - Inline Comments: ${e.total_inline_comments}\n`),void 0!==e.total_code_lines&&(t+=`Total Code Lines: ${e.total_code_lines}\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(t+=`Total Blank Lines: ${e.total_blank_lines}\n`),n.code_vs_comments&&void 0!==e.total_code_lines))&&(t+=`Code vs Comments Ratio: ${e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00"}:1 (${e.total_comment_lines} comments per ${e.total_code_lines} code lines)\n`);Object.keys(e.files_by_extension).length>0&&(t+=`\nExtensions: ${Object.keys(e.files_by_extension).sort().join(", ")}\n`);if(n.show_stats&&Object.keys(e.files_by_extension).length>0){const o=Object.keys(e.files_by_extension).sort();t+="\nStatistics by Extension:\n",t+="-".repeat(60)+"\n";for(const s of o){const o=e.files_by_extension[s],i=e.size_by_extension[s]||0,r=e.lines_by_extension[s]||0;if(t+=` ${s}: ${o} files`,n.lines_only||(t+=`, ${q(i)}`),!n.files_only&&(t+=`, ${r} lines`,J(n,void 0!==e.comment_lines_by_extension?.[s]))){const o=B({comment_lines:e.comment_lines_by_extension?.[s]||0,code_lines:e.code_lines_by_extension?.[s]||0,full_line_comments:e.full_line_comments_by_extension?.[s]||0,inline_comments:e.inline_comments_by_extension?.[s]||0}),i=e.blank_lines_by_extension?.[s]||0;t+=W(o.codeLines,o.commentLines,o.fullLineComments,o.inlineComments,i),n.code_vs_comments&&o.codeLines>0&&(t+=` [${(o.commentLines/o.codeLines).toFixed(2)}:1]`)}t+="\n"}}if(n.show_stats&&e.details.length>0){t+="\nFiles by Directory:\n",t+="-".repeat(60)+"\n";const o=P(e.details),s=Object.keys(o).sort();for(const e of s){const s=o[e];t+=`Directory: ${e}\n`;for(const e of s){const o=q(e.size),s=null===e.lines||n.files_only?"":` | ${e.lines} lines`;let i="";if(J(n,void 0!==e.comment_lines&&null!==e.comment_lines)){const n=B(e);i=W(n.codeLines,n.commentLines,n.fullLineComments,n.inlineComments,e.blank_lines||void 0)}t+=` - ${e.name} (${e.extension}, ${o}${s}${i})\n`}t+="\n"}}if(n.top_files&&n.top_files>0){const o=K(e,n.top_files);t+=`\nTop ${n.top_files} Largest Files:\n`,t+="-".repeat(60)+"\n";for(const e of o){const{sizeStr:o,linesStr:s}=N(e.size,e.lines,n);t+=` ${o.padEnd(10)} ${e.name} (${e.extension})${s}\n`}}if(n.top_dirs&&n.top_dirs>0){const o=H(e,n.top_dirs);t+=`\nTop ${n.top_dirs} Directories (by file count):\n`,t+="-".repeat(60)+"\n";for(const e of o){const o=q(e.totalSize),s=n.files_only?"":` | ${e.totalLines} lines`;t+=` ${e.fileCount.toString().padEnd(5)} files ${e.directory} (${o}${s})\n`}}return t+="\n",t}(n,t);case"json":return function(e,n){const t=D(n.directory),o={directory:G(n)};if("unknown"!==t&&(o.project_type=t,o.project_type_display=V(t)),U(n)||(o.files=e.total_files,o.size=e.total_size,o.size_formatted=q(e.total_size)),n.files_only||(o.lines=e.total_lines,n.comments&&(o.comment_lines=e.total_comment_lines||0,o.code_lines=e.total_code_lines||0,o.blank_lines=e.total_blank_lines||0,o.full_line_comments=e.total_full_line_comments||0,o.inline_comments=e.total_inline_comments||0,n.code_vs_comments&&void 0!==e.total_code_lines&&(o.code_vs_comments_ratio=e.total_code_lines>0?parseFloat((e.total_comment_lines/e.total_code_lines).toFixed(2)):0))),n.show_stats){const t={};for(const o of Object.keys(e.files_by_extension))t[o]={files:e.files_by_extension[o],lines:e.lines_by_extension[o]||0,size:e.size_by_extension[o]||0},n.comments&&(t[o].comment_lines=e.comment_lines_by_extension?.[o]||0,t[o].code_lines=e.code_lines_by_extension?.[o]||0,t[o].blank_lines=e.blank_lines_by_extension?.[o]||0,t[o].full_line_comments=e.full_line_comments_by_extension?.[o]||0,t[o].inline_comments=e.inline_comments_by_extension?.[o]||0,n.code_vs_comments&&e.code_lines_by_extension?.[o]&&e.code_lines_by_extension[o]>0&&(t[o].code_vs_comments_ratio=parseFloat(((e.comment_lines_by_extension[o]||0)/e.code_lines_by_extension[o]).toFixed(2))));o.by_extension=t}if(n.top_files&&n.top_files>0){const t=K(e,n.top_files);o.top_files=t.map(e=>({name:e.name,directory:e.directory,extension:e.extension,size:e.size,size_formatted:q(e.size),lines:e.lines}))}if(n.top_dirs&&n.top_dirs>0){const t=H(e,n.top_dirs);o.top_directories=t.map(e=>({directory:e.directory,file_count:e.fileCount,total_size:e.totalSize,total_size_formatted:q(e.totalSize),total_lines:e.totalLines}))}return JSON.stringify(o,null,2)}(n,t);case"csv":return function(e,n){const t=D(n.directory);let o=`# Directory,${G(n)}\n`;if("unknown"!==t&&(o+=`# Project Type,${V(t)}\n`),n.comments){o+="Extension,Files,Lines,Code Lines,Comment Lines,Blank Lines,Size",n.code_vs_comments&&(o+=",Code vs Comments Ratio"),o+="\n";for(const t of Object.keys(e.files_by_extension)){const s=e.files_by_extension[t],i=e.lines_by_extension[t]||0,r=e.code_lines_by_extension?.[t]||0,l=e.comment_lines_by_extension?.[t]||0;o+=`${t},${s},${i},${r},${l},${e.blank_lines_by_extension?.[t]||0},${e.size_by_extension[t]||0}`,n.code_vs_comments&&r>0&&(o+=`,${((l||0)/r).toFixed(2)}`),o+="\n"}}else{o+="Extension,Files,Lines,Size\n";for(const n of Object.keys(e.files_by_extension))o+=`${n},${e.files_by_extension[n]},${e.lines_by_extension[n]||0},${e.size_by_extension[n]||0}\n`}return o}(n,t);case"tsv":return function(e,n){const t=D(n.directory);let o=`# Directory\t${G(n)}\n`;if("unknown"!==t&&(o+=`# Project Type\t${V(t)}\n`),n.comments){o+="Extension\tFiles\tLines\tCode Lines\tComment Lines\tBlank Lines\tSize",n.code_vs_comments&&(o+="\tCode vs Comments Ratio"),o+="\n";for(const t of Object.keys(e.files_by_extension)){const s=e.files_by_extension[t],i=e.lines_by_extension[t]||0,r=e.code_lines_by_extension?.[t]||0,l=e.comment_lines_by_extension?.[t]||0;o+=`${t}\t${s}\t${i}\t${r}\t${l}\t${e.blank_lines_by_extension?.[t]||0}\t${e.size_by_extension[t]||0}`,n.code_vs_comments&&r>0&&(o+=`\t${((l||0)/r).toFixed(2)}`),o+="\n"}}else{o+="Extension\tFiles\tLines\tSize\n";for(const n of Object.keys(e.files_by_extension))o+=`${n}\t${e.files_by_extension[n]}\t${e.lines_by_extension[n]||0}\t${e.size_by_extension[n]||0}\n`}return o}(n,t);case"markdown":return function(e,n){const t=D(n.directory);let o="# LocIO Report\n\n";o+=`**Directory:** ${G(n)}\n`,"unknown"!==t&&(o+=`**Project Type:** ${V(t)}\n`),o+="\n",o+="## Summary\n\n",o+="| Metric | Value |\n",o+="|--------|-------|\n",o+=`| Total Files | ${e.total_files} |\n`,o+=`| Total Size | ${q(e.total_size)} |\n`,!n.files_only&&(o+=`| Total Lines | ${e.total_lines} |\n`,n.comments&&void 0!==e.total_comment_lines&&(o+=`| Comment Lines | ${e.total_comment_lines} |\n`,void 0!==e.total_code_lines&&(o+=`| Code Lines | ${e.total_code_lines} |\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(o+=`| Blank Lines | ${e.total_blank_lines} |\n`),n.code_vs_comments&&void 0!==e.total_code_lines&&e.total_code_lines>0))&&(o+=`| Code vs Comments Ratio | ${(e.total_comment_lines/e.total_code_lines).toFixed(2)}:1 |\n`);if(Object.keys(e.files_by_extension).length>0){o+="\n## Statistics by Extension\n\n",o+="| Extension | Files |",n.lines_only||(o+=" Size |"),n.files_only||(o+=" Lines |",n.comments&&(o+=" Code | Comments |",n.code_vs_comments&&(o+=" Ratio |"))),o+="\n",o+="|----------|-------|",n.lines_only||(o+="------|"),n.files_only||(o+="-------|",n.comments&&(o+="------|-----------|",n.code_vs_comments&&(o+="-------|"))),o+="\n";const t=Object.keys(e.files_by_extension).sort();for(const s of t){const t=e.files_by_extension[s],i=e.size_by_extension[s]||0,r=e.lines_by_extension[s]||0,l=e.code_lines_by_extension?.[s]||0,c=e.comment_lines_by_extension?.[s]||0;o+=`| \`${s}\` | ${t} |`,n.lines_only||(o+=` ${q(i)} |`),!n.files_only&&(o+=` ${r} |`,n.comments)&&(o+=` ${l} | ${c} |`,n.code_vs_comments&&l>0?o+=` ${((c||0)/l).toFixed(2)}:1 |`:n.code_vs_comments&&(o+=" - |")),o+="\n"}}if(n.show_stats&&e.details.length>0){o+="\n## Files by Directory\n\n";const t=P(e.details),s=Object.keys(t).sort();for(const e of s){const s=t[e];o+=`### ${e}\n\n`,o+="| File | Extension | Size |",n.files_only||(o+=" Lines |",(n.comments||n.show_stats)&&(o+=" Code | Comments | Blank | Full-Line | Inline |")),o+="\n",o+="|------|-----------|------|",n.files_only||(o+="-------|",(n.comments||n.show_stats)&&(o+="------|----------|-------|----------|--------|")),o+="\n";for(const e of s)o+=`| ${e.name} | \`${e.extension}\` | ${q(e.size)} |`,!n.files_only&&null!==e.lines&&(o+=` ${e.lines} |`,n.comments||n.show_stats)&&(o+=` ${e.code_lines||0} | ${e.comment_lines||0} | ${e.blank_lines||0} | ${e.full_line_comments||0} | ${e.inline_comments||0} |`),o+="\n";o+="\n"}}if(n.top_files&&n.top_files>0){const t=K(e,n.top_files);o+=`\n## Top ${n.top_files} Largest Files\n\n`,o+="| Size | File | Extension |",n.files_only||(o+=" Lines |"),o+="\n",o+="|------|------|-----------|",n.files_only||(o+="-------|"),o+="\n";for(const e of t)o+=`| ${q(e.size)} | ${e.name} | \`${e.extension}\` |`,n.files_only||null===e.lines||(o+=` ${e.lines} |`),o+="\n";o+="\n"}if(n.top_dirs&&n.top_dirs>0){const t=H(e,n.top_dirs);o+=`\n## Top ${n.top_dirs} Directories (by file count)\n\n`,o+="| Files | Directory | Size |",n.files_only||(o+=" Lines |"),o+="\n",o+="|-------|-----------|------|",n.files_only||(o+="-------|"),o+="\n";for(const e of t)o+=`| ${e.fileCount} | ${e.directory} | ${q(e.totalSize)} |`,n.files_only||(o+=` ${e.totalLines} |`),o+="\n";o+="\n"}return o+="\n---\n\n",o+="*Generated by [LocIO](https://locio.js.org)*\n",o}(n,t);case"html":return function(e,n){const t=D(n.directory),o=Object.keys(e.files_by_extension).sort(),s=o.map(n=>({ext:n,files:e.files_by_extension[n],lines:e.lines_by_extension[n]||0,size:e.size_by_extension[n]||0,codeLines:e.code_lines_by_extension?.[n]||0,commentLines:e.comment_lines_by_extension?.[n]||0,blankLines:e.blank_lines_by_extension?.[n]||0}));return`<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>LocIO Report - ${G(n)}</title>\n <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"><\/script>\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh;\n padding: 20px;\n }\n .container {\n max-width: 1200px;\n margin: 0 auto;\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n overflow: hidden;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 40px;\n text-align: center;\n }\n .header h1 {\n font-size: 2.5em;\n margin-bottom: 10px;\n }\n .header p {\n opacity: 0.9;\n font-size: 1.1em;\n }\n .content {\n padding: 40px;\n }\n .summary-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 20px;\n margin-bottom: 40px;\n }\n .card {\n background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n padding: 25px;\n border-radius: 10px;\n text-align: center;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n }\n .card h3 {\n color: #667eea;\n font-size: 0.9em;\n text-transform: uppercase;\n letter-spacing: 1px;\n margin-bottom: 10px;\n }\n .card .value {\n font-size: 2.5em;\n font-weight: bold;\n color: #2d3748;\n }\n .section {\n margin-bottom: 40px;\n }\n .section h2 {\n color: #2d3748;\n margin-bottom: 20px;\n padding-bottom: 10px;\n border-bottom: 3px solid #667eea;\n }\n .chart-container {\n position: relative;\n height: 400px;\n margin: 20px 0;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n margin-top: 20px;\n background: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n th {\n background: #667eea;\n color: white;\n padding: 15px;\n text-align: left;\n font-weight: 600;\n }\n td {\n padding: 12px 15px;\n border-bottom: 1px solid #e2e8f0;\n }\n tr:hover {\n background: #f7fafc;\n }\n .footer {\n text-align: center;\n padding: 20px;\n color: #718096;\n border-top: 1px solid #e2e8f0;\n }\n .footer a {\n color: #667eea;\n text-decoration: none;\n }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="header">\n <h1>LocIO Report</h1>\n <p>Directory: ${G(n)}</p>\n ${"unknown"!==t?`<p>Project Type: <strong>${V(t)}</strong></p>`:""}\n </div>\n <div class="content">\n <div class="summary-cards">\n <div class="card">\n <h3>Total Files</h3>\n <div class="value">${e.total_files}</div>\n </div>\n <div class="card">\n <h3>Total Size</h3>\n <div class="value">${q(e.total_size)}</div>\n </div>\n ${n.files_only?"":`<div class="card">\n <h3>Total Lines</h3>\n <div class="value">${e.total_lines}</div>\n </div>`}\n ${n.comments&&void 0!==e.total_comment_lines?`<div class="card">\n <h3>Comment Lines</h3>\n <div class="value">${e.total_comment_lines}</div>\n </div>\n <div class="card">\n <h3>Code Lines</h3>\n <div class="value">${e.total_code_lines||0}</div>\n </div>\n ${void 0!==e.total_blank_lines&&e.total_blank_lines>0?`<div class="card">\n <h3>Blank Lines</h3>\n <div class="value">${e.total_blank_lines}</div>\n </div>`:""}`:""}\n </div>\n\n ${o.length>0?`<div class="section">\n <h2>π Statistics by Extension</h2>\n <div class="chart-container">\n <canvas id="extensionChart"></canvas>\n </div>\n <table>\n <thead>\n <tr>\n <th>Extension</th>\n <th>Files</th>\n ${n.lines_only?"":"<th>Size</th>"}\n ${n.files_only?"":"<th>Lines</th>"}\n ${n.comments?"<th>Code</th><th>Comments</th><th>Blank</th>":""}\n </tr>\n </thead>\n <tbody>\n ${s.map(e=>`<tr>\n <td><strong>${e.ext}</strong></td>\n <td>${e.files}</td>\n ${n.lines_only?"":`<td>${q(e.size)}</td>`}\n ${n.files_only?"":`<td>${e.lines}</td>`}\n ${n.comments?`<td>${e.codeLines}</td><td>${e.commentLines}</td><td>${e.blankLines}</td>`:""}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`:""}\n\n ${n.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?'<div class="section">\n <h2>π¬ Code vs Comments</h2>\n <div class="chart-container">\n <canvas id="commentChart"></canvas>\n </div>\n </div>':""}\n\n ${n.top_files&&n.top_files>0?(()=>{const t=K(e,n.top_files);return`<div class="section">\n <h2>π Top ${n.top_files} Largest Files</h2>\n <table>\n <thead>\n <tr>\n <th>Size</th>\n <th>File</th>\n <th>Extension</th>\n ${n.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${t.map(e=>`<tr>\n <td><strong>${q(e.size)}</strong></td>\n <td>${e.name}</td>\n <td><code>${e.extension}</code></td>\n ${n.files_only||null===e.lines?"":`<td>${e.lines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${n.top_dirs&&n.top_dirs>0?(()=>{const t=H(e,n.top_dirs);return`<div class="section">\n <h2>π Top ${n.top_dirs} Directories (by file count)</h2>\n <table>\n <thead>\n <tr>\n <th>Files</th>\n <th>Directory</th>\n <th>Size</th>\n ${n.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${t.map(e=>`<tr>\n <td><strong>${e.fileCount}</strong></td>\n <td>${e.directory}</td>\n <td>${q(e.totalSize)}</td>\n ${n.files_only?"":`<td>${e.totalLines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${"html"===n.export?(()=>{const t={};for(const n of e.details)t[n.directory]||(t[n.directory]={fileCount:0,totalSize:0,totalLines:0}),t[n.directory].fileCount+=1,t[n.directory].totalSize+=n.size,null!==n.lines&&(t[n.directory].totalLines+=n.lines);const o=Object.entries(t),s=Math.max(...o.map(([,e])=>e.fileCount)),i=Math.max(...o.map(([,e])=>e.totalSize));return`<div class="section">\n <h2>πΊοΈ Directory Heatmap</h2>\n <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; margin-top: 20px;">\n ${o.map(([e,t])=>{const o=(t.fileCount/s*100+t.totalSize/i*100)/2,r=240-1.2*o;return`<div style="\n background: linear-gradient(135deg, hsl(${r}, 70%, ${85-.3*o}%), hsl(${r}, 70%, ${75-.3*o}%));\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n color: ${o>50?"white":"#2d3748"};\n ">\n <div style="font-weight: bold; margin-bottom: 8px; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="${e}">${e.split("/").pop()||e}</div>\n <div style="font-size: 0.8em; opacity: 0.9;">\n <div>π ${t.fileCount} files</div>\n <div>πΎ ${q(t.totalSize)}</div>\n ${n.files_only?"":`<div>π ${t.totalLines} lines</div>`}\n </div>\n </div>`}).join("")}\n </div>\n </div>`})():""}\n </div>\n <div class="footer">\n Generated by <a href="https://locio.js.org">LocIO</a>\n </div>\n </div>\n\n <script>\n ${o.length>0?`const extensionCtx = document.getElementById('extensionChart');\n new Chart(extensionCtx, {\n type: 'bar',\n data: {\n labels: ${JSON.stringify(o)},\n datasets: [\n ${n.files_only?"":`{\n label: 'Lines',\n data: ${JSON.stringify(o.map(n=>e.lines_by_extension[n]||0))},\n backgroundColor: 'rgba(102, 126, 234, 0.8)',\n borderColor: 'rgba(102, 126, 234, 1)',\n borderWidth: 2\n },`}\n {\n label: 'Files',\n data: ${JSON.stringify(o.map(n=>e.files_by_extension[n]))},\n backgroundColor: 'rgba(118, 75, 162, 0.8)',\n borderColor: 'rgba(118, 75, 162, 1)',\n borderWidth: 2\n }\n ]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'top',\n },\n title: {\n display: true,\n text: 'Files and Lines by Extension'\n }\n }\n }\n });`:""}\n\n ${n.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?`const commentCtx = document.getElementById('commentChart');\n new Chart(commentCtx, {\n type: 'doughnut',\n data: {\n labels: ['Code Lines', 'Comment Lines'],\n datasets: [{\n data: [${e.total_code_lines}, ${e.total_comment_lines||0}],\n backgroundColor: [\n 'rgba(102, 126, 234, 0.8)',\n 'rgba(118, 75, 162, 0.8)'\n ],\n borderColor: [\n 'rgba(102, 126, 234, 1)',\n 'rgba(118, 75, 162, 1)'\n ],\n borderWidth: 2\n }]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'bottom',\n },\n title: {\n display: true,\n text: 'Code vs Comments Distribution'\n }\n }\n }\n });`:""}\n <\/script>\n</body>\n</html>`}(n,t)}}function Y(e,n,t){const o=function(e){switch(e){case"human":return"txt";case"json":return"json";case"csv":return"csv";case"tsv":return"tsv";case"markdown":return"md";case"html":return"html"}}(e);let s;return s=Array.isArray(n.export)&&n.export.length>1&&void 0!==t?`LocIO-report-${t+1}.${o}`:`LocIO-report.${o}`,n.export_path?i.join(n.export_path,s):s}function Z(e,n){void 0===n.export?function(e,n){if(n.quiet)console.log(`${e.total_files} ${e.total_lines}`);else{if(console.log("\n"+a.cyan("=".repeat(60))),console.log(a.cyan.bold("LocIO RESULTS".padStart(37).padEnd(60))),console.log(a.cyan("=".repeat(60))),console.log(`\n${a.green.bold("Directory:")} ${G(n)}`),n.lines_only||(U(n)?console.log(`\n${a.green.bold("Size:")} ${a.white(q(e.total_size))}`):(console.log(`\n${a.green.bold("Total Files:")} ${a.yellow(e.total_files)}`),console.log(`\n${a.green.bold("Total Files Size:")} ${a.white(q(e.total_size))}`))),!n.files_only&&(console.log(`\n${a.green.bold("Total Lines:")} ${a.yellow(e.total_lines)}`),(n.comments||n.show_stats)&&void 0!==e.total_comment_lines&&(console.log(`\n${a.green.bold("Total Comment Lines:")} ${a.cyan(e.total_comment_lines)}`),void 0!==e.total_full_line_comments&&console.log(` ${a.gray("β")} ${a.green("Full Line Comments:")} ${a.cyan(e.total_full_line_comments)}`),void 0!==e.total_inline_comments&&console.log(` ${a.gray("β")} ${a.green("Inline Comments:")} ${a.cyan(e.total_inline_comments)}`),void 0!==e.total_code_lines&&console.log(`\n${a.green.bold("Total Code Lines:")} ${a.blue(e.total_code_lines)}`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&console.log(`\n${a.green.bold("Total Blank Lines:")} ${a.gray(e.total_blank_lines)}`),n.code_vs_comments&&void 0!==e.total_code_lines))){const n=e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00";console.log(`\n${a.green.bold("Code vs Comments Ratio:")} ${a.magenta(n)}:1 ${a.gray(`(${e.total_comment_lines} comments per ${e.total_code_lines} code lines)`)}`)}if(Object.keys(e.files_by_extension).length>0){const n=Object.keys(e.files_by_extension).sort();console.log(`\n${a.green.bold("Extensions:")} ${a.white(n.join(", "))}`)}if(n.show_stats&&Object.keys(e.files_by_extension).length>0){console.log(`\n${a.cyan.bold("Statistics by Extension:")}`),console.log(a.gray("-".repeat(60)));const t=Object.keys(e.files_by_extension).sort();for(const o of t){const t=e.files_by_extension[o],s=e.size_by_extension[o]||0,i=e.lines_by_extension[o]||0;let r=` ${a.white(o)}: ${a.yellow(t)} files`;if(n.lines_only||(r+=`, ${a.white(q(s))}`),!n.files_only&&(r+=`, ${a.yellow(i)} lines`,J(n,void 0!==e.comment_lines_by_extension?.[o]))){const t=B({comment_lines:e.comment_lines_by_extension?.[o]||0,code_lines:e.code_lines_by_extension?.[o]||0,full_line_comments:e.full_line_comments_by_extension?.[o]||0,inline_comments:e.inline_comments_by_extension?.[o]||0}),s=e.blank_lines_by_extension?.[o]||0;if(r+=A(t.codeLines,t.commentLines,t.fullLineComments,t.inlineComments,s),n.code_vs_comments&&t.codeLines>0){const e=(t.commentLines/t.codeLines).toFixed(2);r+=` ${a.magenta(`[${e}:1]`)}`}}console.log(r)}}if(n.show_stats&&e.details.length>0){console.log(`\n${a.cyan.bold("Files by Directory:")}`),console.log(a.gray("-".repeat(60)));const t=P(e.details),o=Object.keys(t).sort();for(const e of o){const o=t[e];console.log(a.green.bold(`Directory: ${e}`));for(const e of o){const t=q(e.size),o=null===e.lines||n.files_only?"":` | ${e.lines} lines`;let s="";if(J(n,void 0!==e.comment_lines&&null!==e.comment_lines)){const n=B(e);s=A(n.codeLines,n.commentLines,n.fullLineComments,n.inlineComments,e.blank_lines||void 0)}console.log(` - ${a.white(e.name)} (${a.blue(e.extension)}, ${a.white(t)}${o}${s})`)}console.log()}}if(n.top_files&&n.top_files>0){const t=K(e,n.top_files);console.log(`\n${a.cyan.bold(`Top ${n.top_files} Largest Files:`)}`),console.log(a.gray("-".repeat(60)));for(const e of t){const{sizeStr:t,linesStr:o}=N(e.size,e.lines,n);console.log(` ${a.yellow(t.padEnd(10))} ${a.white(e.name)} ${a.blue(`(${e.extension})`)}${o}`)}}if(n.top_dirs&&n.top_dirs>0){const t=H(e,n.top_dirs);console.log(`\n${a.cyan.bold(`Top ${n.top_dirs} Directories (by file count):`)}`),console.log(a.gray("-".repeat(60)));for(const e of t){const t=q(e.totalSize),o=n.files_only?"":` | ${e.totalLines} lines`;console.log(` ${a.yellow(e.fileCount.toString().padEnd(5))} files ${a.white(e.directory)} ${a.gray(`(${t}${o})`)}`)}}console.log()}}(e,n):function(e,n){const t=Array.isArray(n.export)?n.export:[n.export||"human"];for(let s=0;s<t.length;s++){const r=t[s],l=Q(r,e,n),c=Y(r,n,s);try{let e;e=n.export_path?n.export_path:i.dirname(c),"."!==e&&e!==c&&o.mkdirSync(e,{recursive:!0}),o.writeFileSync(c,l,"utf-8"),n.quiet||console.log(`Report written to ${c}`)}catch(e){const n=(e instanceof Error?e:new Error(String(e))).message||String(e);let t="";t=n.includes("ENOENT")?`The directory for "${c}" does not exist.\n - Ensure the parent directory exists\n - Check if the path is correct`:n.includes("EACCES")||n.includes("permission")?`Permission denied when writing to "${c}".\n - Check write permissions for the directory\n - Try running with appropriate permissions\n - Use a different output directory`:n.includes("ENOSPC")?"Insufficient disk space.\n - Free up disk space\n - Choose a different location":"Check if the path is valid and you have write permissions.",console.error(`\nβ Failed to create report file ${c}`),console.error(`π Error: ${n}`),t&&console.error(`\nπ‘ Suggestion:\n${t}`)}}}(e,n)}function X(e){const n=e.trim().toUpperCase();let t,o;n.endsWith("KB")?(t=n.slice(0,-2),o=1024):n.endsWith("MB")?(t=n.slice(0,-2),o=1048576):n.endsWith("GB")?(t=n.slice(0,-2),o=1073741824):n.endsWith("B")&&n.length>1?(t=n.slice(0,-1),o=1):(t=n,o=1);const s=parseFloat(t);return isNaN(s)?y.invalidSizeFormat(e):Math.floor(s*o)}var ee=["jpg","jpeg","png","gif","bmp","svg","ico","webp","tiff","tif","psd","raw","heic","heif","avif","mp3","wav","flac","aac","ogg","wma","m4a","opus","aiff","au","mp4","avi","mkv","mov","wmv","flv","webm","m4v","mpg","mpeg","3gp","ogv","zip","rar","7z","tar","gz","bz2","xz","z","cab","iso","dmg","pkg","deb","rpm","pdf","doc","docx","xls","xlsx","ppt","pptx","odt","ods","odp","exe","dll","so","dylib","app","msi","bin","run","ttf","otf","woff","woff2","eot","db","sqlite","sqlite3","mdb","accdb","ps","eps","ai","sketch","fig","xd"],ne=["md","markdown","txt","rst","adoc","asciidoc","org","wiki","json","yaml","yml","toml","ini","cfg","conf","config","properties","env","dotenv","csv","tsv","xml","html","htm","xhtml","log","lock","lockfile"];function te(e){try{if(e.max_size){const n=X(e.max_size);if(n instanceof y)return n}if(e.min_size){const n=X(e.min_size);if(n instanceof y)return n}const n=D(e.directory),t=w[n]||w.unknown,o=e.exclude_patterns.map(n=>{try{return new RegExp(n,e.ignore_case?"i":void 0)}catch(e){throw y.invalidRegex(n,e instanceof Error?e:void 0)}}),s=[...e.exclude_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),...t.exclude_extensions.map(e=>e.toLowerCase()),...ee.map(e=>e.toLowerCase())],i=Array.from(new Set(s)).sort(),r=e.include_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),l=[...e.exclude_dirs,...t.exclude_dirs].map(n=>new RegExp(n,e.ignore_case?"i":void 0)),c=e.include_dirs.map(n=>new RegExp(n,e.ignore_case?"i":void 0)),a=[...e.exclude_names,...t.exclude_names].map(n=>new RegExp(n,e.ignore_case?"i":void 0));return{exclude_patterns:o,exclude_extensions:i,include_extensions:r,exclude_dirs:l,include_dirs:c,exclude_names:a,include_names:e.include_names.map(n=>new RegExp(n,e.ignore_case?"i":void 0)),detected_project_type:n}}catch(e){return e instanceof y?e:y.io(`Failed to create filter patterns: ${e instanceof Error?e.message:String(e)}`)}}function oe(e,n,t){const s=e,r=i.basename(e);for(const e of t.exclude_patterns)if(e.test(s))return!0;const l=i.extname(e).replace(/^\./,"").toLowerCase();if(l){for(const e of t.exclude_extensions)if(l===e.toLowerCase())return!0;if(t.include_extensions.length>0){let e=!1;for(const n of t.include_extensions)if(l===n.toLowerCase()){e=!0;break}if(!e)return!0}}else if(t.include_extensions.length>0)return!0;const c=i.dirname(e);for(const e of t.exclude_dirs)if(e.test(c))return!0;if(t.include_dirs.length>0){let e=!1;for(const n of t.include_dirs)if(n.test(c)){e=!0;break}if(!e)return!0}for(const e of t.exclude_names)if(e.test(r))return!0;if(t.include_names.length>0){let e=!1;for(const n of t.include_names)if(n.test(r)){e=!0;break}if(!e)return!0}if(n.no_hidden&&r.startsWith("."))return!0;try{const t=o.statSync(e).size;if(n.max_size){const e=X(n.max_size);if(!(e instanceof y)&&t>e)return!0}if(n.min_size){const e=X(n.min_size);if(!(e instanceof y)&&t<e)return!0}if(n.no_empty&&0===t)return!0}catch{}return!(!n.no_binary||!function(e){try{const n=Buffer.alloc(8192),t=o.openSync(e,"r"),s=o.readSync(t,n,0,8192,0);if(o.closeSync(t),0===s)return!1;for(let e=0;e<s;e++)if(0===n[e])return!0;return!1}catch{return!1}}(e))}function se(e){return i.extname(e).replace(/^\./,"").toLowerCase()||"no-ext"}function ie(e){const n=null!==e.commentLines,t=null!==e.codeLines&&null!==e.blankLines;return n||t?{totalLines:e.lines||0,commentLines:e.commentLines||0,codeLines:e.codeLines||0,fullLineComments:e.fullLineComments||0,inlineComments:e.inlineComments||0,blankLines:e.blankLines||0}:null}function re(e,n,t,o,s){if(e.total_files+=1,e.total_size+=t,e.files_by_extension[n]=(e.files_by_extension[n]||0)+1,e.size_by_extension[n]=(e.size_by_extension[n]||0)+t,null!==o&&(e.total_lines+=o,e.lines_by_extension[n]=(e.lines_by_extension[n]||0)+o),s){const t=s.codeLines+s.commentLines+s.blankLines;s.totalLines!==t&&(s.totalLines=t),e.total_comment_lines=(e.total_comment_lines||0)+s.commentLines,e.total_code_lines=(e.total_code_lines||0)+s.codeLines,e.total_blank_lines=(e.total_blank_lines||0)+s.blankLines,e.total_full_line_comments=(e.total_full_line_comments||0)+s.fullLineComments,e.total_inline_comments=(e.total_inline_comments||0)+s.inlineComments,e.comment_lines_by_extension[n]=(e.comment_lines_by_extension[n]||0)+s.commentLines,e.code_lines_by_extension[n]=(e.code_lines_by_extension[n]||0)+s.codeLines,e.blank_lines_by_extension||(e.blank_lines_by_extension={}),e.blank_lines_by_extension[n]=(e.blank_lines_by_extension[n]||0)+s.blankLines,e.full_line_comments_by_extension[n]=(e.full_line_comments_by_extension[n]||0)+s.fullLineComments,e.inline_comments_by_extension[n]=(e.inline_comments_by_extension[n]||0)+s.inlineComments}}function le(e,n){const t=i.extname(e).replace(/^\./,"").toLowerCase(),s=ne.map(e=>e.toLowerCase()).includes(t);if(n.comments){if(!s){const n=function(e){try{const n=o.readFileSync(e,"utf-8").split(/\r?\n/),t=T(i.extname(e));let s=n.length,r=0,l=0,c=0,a=0,d=0,m=!1;for(const e of n){if(0===e.trim().length){m?(l++,c++):d++;continue}const n=O(e,t,m);n?(n.isMultiLine&&(m=!n.endsMultiLine),n.hasCodeBefore?(a++,r++,n.hasCodeAfter):(c++,n.hasCodeAfter&&r++),l++):m?(l++,c++):r++}return{totalLines:s,codeLines:r,commentLines:l,fullLineComments:c,inlineComments:a,blankLines:d}}catch{return null}}(e);if(n)return{lines:n.totalLines,commentLines:n.commentLines,codeLines:n.codeLines,fullLineComments:n.fullLineComments,inlineComments:n.inlineComments,blankLines:n.blankLines,error:null}}const n=function(e){try{const n=o.readFileSync(e,"utf-8").split(/\r?\n/);let t=0,s=0;for(const e of n)0===e.trim().length?t++:s++;return{total:n.length,blank:t,code:s}}catch(n){return y.io(`Failed to read file: ${e}`,n instanceof Error?n:void 0)}}(e);return h(n)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:n}:{lines:n.total,commentLines:0,codeLines:n.code,fullLineComments:0,inlineComments:0,blankLines:n.blank,error:null}}const r=function(e){try{return o.readFileSync(e,"utf-8").split(/\r?\n/).length}catch(n){return y.io(`Failed to read file: ${e}`,n instanceof Error?n:void 0)}}(e);return h(r)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:r}:{lines:r,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}function ce(e,n,t,o,s,r,l,c,a){return{directory:i.dirname(e),name:i.basename(e),extension:t,size:n,lines:o,comment_lines:s,code_lines:r,blank_lines:a,full_line_comments:l,inline_comments:c}}function ae(e){try{return{metadata:o.statSync(e),error:null}}catch(e){return{metadata:null,error:e instanceof Error?e:new Error(String(e))}}}function de(e,n,t){return i.relative(n,e).split(i.sep).length-1>t}var me=class{constructor(e){f(this,"total"),f(this,"current",0),f(this,"startTime"),f(this,"width",40),f(this,"errors",0),this.total=e,this.startTime=Date.now()}update(e,n=0){this.current=e,this.errors=n,this.render()}increment(e=0){this.current++,e>0&&(this.errors=e),this.render()}formatTime(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;return`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3)}s`}calculateETA(){if(0===this.current)return"calculating...";const e=Date.now()-this.startTime,n=this.current/e,t=(this.total-this.current)/n;return t<0||!isFinite(t)?"calculating...":this.formatTime(t)}render(){const e=this.total>0?this.current/this.total*100:0,n=e.toFixed(1).padStart(5),t=String(this.current).padStart(String(this.total).length),o=this.errors>0?a.red(` (${this.errors} errors)`):"",s=Date.now()-this.startTime,i=this.formatTime(s),r=this.calculateETA();if(!process.stderr.isTTY)return void(this.current%100!=0&&this.current!==this.total||process.stderr.write(`\rProcessed: ${t}/${this.total} (${n}%) | ${i} elapsed | ETA: ${r}${o}`));const l=Math.round(e/100*this.width),c=this.width-l,d=`\r${a.green("β".repeat(l))+a.gray("β".repeat(c))} ${n}% | ${t}/${this.total} files | ${i} elapsed | ETA: ${r}${o}`;process.stderr.write("[K"+d)}finish(){const e=Date.now()-this.startTime,n=this.formatTime(e),t=this.errors>0?a.red(` (${this.errors} errors)`):"";if(process.stderr.isTTY){const e=100,o=a.green("β".repeat(this.width)),s=String(this.current).padStart(String(this.total).length);process.stderr.write(`\r${o} ${e.toFixed(1).padStart(5)}% | ${s}/${this.total} files | ${n}${t}\n`)}else process.stderr.write(`\rProcessed: ${this.current}/${this.total} files in ${n}${t}\n`)}};function ue(e){const n=Date.now(),t={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},s=te(e);if(h(s))return s;const r=i.resolve(e.directory),l=i.dirname(r),{processed:c,errors:a}=function(e,n,t,s,r){let l=0,c=0;if(void 0!==n.max_depth&&de(e,r,n.max_depth))return{processed:l,errors:c};try{if(!o.statSync(e).isFile())return{processed:l,errors:c}}catch{return{processed:l,errors:c}}if(oe(e,n,s))return{processed:l,errors:c};const a=ae(e);if(a.error)return n.quiet||console.error(`Warning: Could not read metadata for ${e}: ${a.error}`),c+=1,{processed:l,errors:c};const d=a.metadata.size,m=se(e);if(n.rm_comments){const t=m.toLowerCase().replace(/^\./,"");if(ne.map(e=>e.toLowerCase()).includes(t))return{processed:l,errors:c};if((()=>{if(!0===n.rm_comments)return!0;if("string"==typeof n.rm_comments){const e=x(n.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return e.includes(t)||e.includes(`.${t}`)}return!1})()){const t=M(e);if(t.success){if(t.commentsFound){if(!n.quiet){const n=i.relative(r,e);console.log(`β Removed comments from ${n}`)}l+=1}}else{if(!n.quiet){const n=i.relative(r,e);console.error(`β Failed to remove comments from ${n}`)}c+=1}}return{processed:l,errors:c}}l+=1;let u=null,f=null,p=null,_=null,y=null,h=null,g=null;if(!n.files_only){const t=le(e,n);t.error?(n.quiet||console.error(`Warning: Could not count lines in ${e}: ${t.error.message}`),c+=1):(u=t.lines,f=t.commentLines,p=t.codeLines,_=t.fullLineComments,y=t.inlineComments,h=t.blankLines,g=ie(t))}return re(t,m,d,u,g),t.details.push(ce(e,d,m,u,f,p,_,y,h)),{processed:l,errors:c}}(r,e,t,s,l);return fe(e,n,c,a),e.rm_comments?{...t,_commentsRemoved:c}:t}function fe(e,n,t,o){if(e.show_progress&&!e.quiet){const e=`${Date.now()-n}ms`;process.stderr.write(`\rProcessed: ${t} files (${o} errors) in ${e}\n`)}}function pe(e){const n=Date.now(),t={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},s=te(e);if(h(s))return s;const r=function(e){const n=m();return n.add(".git"),n.add(".gitignore"),n.add(".lcignore"),function e(t,s){const r=i.join(t,".gitignore");try{if(o.existsSync(r)&&o.statSync(r).isFile()){const e=o.readFileSync(r,"utf-8"),l=i.relative(s,t)||".",c=e.split("\n").map(e=>e.trim()).filter(e=>e&&!e.startsWith("#"));for(const e of c)"."===l?n.add(e):n.add(i.join(l,e))}}catch{}try{const n=o.readdirSync(t);for(const r of n){const n=i.join(t,r);try{o.statSync(n).isDirectory()&&".git"!==r&&e(n,s)}catch{}}}catch{}}(e,e),n}(e.directory),l={cwd:e.directory,absolute:!0,onlyFiles:!0,ignore:[],dot:!e.no_hidden,followSymbolicLinks:e.follow_links};let c=0,a=0,u=null,f=0;try{const n=d.sync("**/*",l).map(e=>"string"==typeof e?e:e.path||String(e));e.show_progress&&!e.quiet&&(u=new me(n.length));for(const l of n){if(f+=1,u&&u.update(f,a),void 0!==e.max_depth&&de(l,e.directory,e.max_depth))continue;const n=i.relative(e.directory,l);if(r.ignores(n))continue;try{if(!o.statSync(l).isFile())continue}catch{continue}if(oe(l,e,s))continue;const d=ae(l);if(d.error){e.quiet||console.error(`Warning: Could not read metadata for ${l}: ${d.error}`),a+=1;continue}const m=d.metadata.size,p=se(l);if(e.rm_comments){const n=p.toLowerCase().replace(/^\./,"");if(ne.map(e=>e.toLowerCase()).includes(n))continue;if((()=>{if(!0===e.rm_comments)return!0;if("string"==typeof e.rm_comments){const t=x(e.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return t.includes(n)||t.includes(`.${n}`)}return!1})()){const n=M(l);if(n.success){if(n.commentsFound){if(!e.quiet){const n=i.relative(e.directory,l);console.log(`β Removed comments from ${n}`)}c+=1}}else{if(!e.quiet){const n=i.relative(e.directory,l);console.error(`β Failed to remove comments from ${n}`)}a+=1}}continue}c+=1;let _=null,y=null,h=null,g=null,b=null,$=null,v=null;if(!e.files_only){const n=le(l,e);n.error?(e.quiet||console.error(`Warning: Could not count lines in ${l}: ${n.error.message}`),a+=1):(_=n.lines,y=n.commentLines,h=n.codeLines,g=n.fullLineComments,b=n.inlineComments,$=n.blankLines,v=ie(n))}re(t,p,m,_,v),t.details.push(ce(l,m,p,_,y,h,g,b,$))}}catch(e){return y.io(`Failed to scan directory: ${e instanceof Error?e.message:String(e)}`,e instanceof Error?e:void 0)}return fe(e,n,c,a),e.rm_comments?{...t,_commentsRemoved:c}:t}var _e=null,ye=!1,he=null;function ge(e){const n=$(e.directory);if(n.error)return n.error;const t=n.path;if(!o.statSync(t).isDirectory())return y.notADirectory(e.directory);e.directory=t;const s=pe(e);if(h(s))return s;Z(s,e)}function xe(e,n=500){_e&&clearTimeout(_e),_e=setTimeout(()=>{if(ye)return;ye=!0,e.quiet||(process.stdout.isTTY&&console.log("[2J[H"),console.log(a.cyan("π Changes detected. Rescanning...\n")));const n=ge(e);h(n)?e.quiet||(console.error(a.red(`\nβ Error: ${n.message}`)),n.suggestion&&console.error(a.yellow(`\nπ‘ Suggestion: ${n.suggestion}`))):e.quiet||(console.log(a.gray("\n"+"β".repeat(60))),console.log(a.gray(`π Watching for changes... (Press ${a.yellow("Ctrl+C")} to stop)`))),ye=!1},n)}function be(e){if(e.version)return void console.log(`LocIO ${_()}`);if(e.watch)return void function(e){const n=$(e.directory);n.error&&(console.error(`Error: ${n.error.message}`),process.exit(1));const t=n.path;o.statSync(t).isDirectory()||(console.error(`Error: Not a directory: ${e.directory}`),process.exit(1)),e.quiet||console.log(a.cyan("π Starting watch mode...\n"));const s=ge(e);h(s)&&(console.error(`Error: ${s.message}`),process.exit(1)),e.quiet||(console.log(a.gray("\n"+"β".repeat(60))),console.log(a.gray(`π Watching for changes... (Press ${a.yellow("Ctrl+C")} to stop)`)));try{(he=o.watch(t,{recursive:!0},(n,t)=>{t&&(e.export&&t.startsWith("LocIO-report.")||xe(e,500))})).on("error",n=>{e.quiet||console.error(a.red(`\nWatch error: ${n.message}`))})}catch(e){console.error(a.red(`Failed to start watch mode: ${e instanceof Error?e.message:String(e)}`)),console.error(a.yellow("Note: Recursive watching may not be supported on all systems.")),process.exit(1)}const i=()=>{_e&&clearTimeout(_e),he&&he.close(),e.quiet||console.log(a.gray("\n\nπ Watch mode stopped.")),process.exit(0)};process.on("SIGINT",i),process.on("SIGTERM",i)}(e);const n=$(e.directory);if(n.error)return n.error;const t=n.path,s=o.statSync(t);let i;if(s.isDirectory()&&!e.quiet){const e=D(t);"unknown"!==e&&console.log(`${a.cyan("Detected project type:")} ${a.blue.bold(V(e))}\n`)}if(e.directory=t,e.rm_comments){if(e.quiet||console.log(a.cyan("Removing comments from files...\n")),i=s.isFile()?ue(e):pe(e),h(i))return i;const n=i._commentsRemoved||0;return void(e.quiet||(n>0?console.log(a.green(`\nβ Comments removed successfully from ${n} file(s)!\n`)):console.log(a.yellow("\nβΉ No comments found in any files.\n"))))}if(i=s.isFile()?ue(e):pe(e),h(i))return i;Z(i,e)}(async function(){if(2===e.argv.length&&e.stdin.isTTY){if(!await new Promise((t,o)=>{const s=_();console.log("===================================="),console.log(` LocIO CLI v${s}`),console.log("===================================="),console.log("A fast, flexible line and file counter for your projects.\n"),console.log("Select an option:"),console.log(" 1) Quick scan of current directory (default settings)"),console.log(" 2) Show common command examples"),console.log(" 3) View full help (same as --help)"),console.log(" q) Quit\n"),e.nextTick(()=>{const s=n.createInterface({input:e.stdin,output:e.stdout}),i=()=>{s.question("Enter choice (1/2/3/q): ",e=>{switch(e.trim()){case"1":console.log('\nRunning quick scan on current directory (".") with default settings...\n'),s.close(),t(!0);break;case"2":console.log("\nCommon commands:"),console.log(" locio . # Quick scan"),console.log(" locio . --files-only # Show only file counts"),console.log(" locio . --lines-only # Show only line counts"),console.log(' locio . --exclude "target" # Ignore patterns'),console.log(" locio . --include-ext ts,js # Filter by extension"),console.log(" locio . --export json # Export to JSON\n"),s.close(),t(!1);break;case"3":console.log(),k().outputHelp(),console.log("\n"),s.close(),t(!1);break;case"q":case"Q":console.log("\nThank you for using LocIO."),s.close(),t(!1);break;default:console.log("Invalid choice. Please enter 1, 2, 3, or q.\n"),i()}})};s.on("error",e=>{console.error("\nFailed to read input. Exiting."),s.close(),o(e)}),i()})}))return}!function(e){const n=be(e);h(n)&&(console.error(function(e){let n=`\nβ Error: ${e.message}\n`;return e.suggestion&&(n+=`\nπ‘ Suggestion:\n${e.suggestion}\n`),e.cause&&(n+=`\nπ Details: ${e.cause.message}\n`),n}(n)),process.exit(1)),e.watch||process.exit(0)}(function(){const e=k();e.parse();const n=e.opts(),t=e.args,o=n.excludeExt?x(n.excludeExt):[],s=n.includeExt?x(n.includeExt):[];return{directory:t[0]||".",files_only:n.filesOnly||!1,lines_only:n.linesOnly||!1,exclude_patterns:n.exclude||[],exclude_extensions:o,include_extensions:s,exclude_dirs:n.excludeDir||[],include_dirs:n.includeDir||[],exclude_names:n.excludeName||[],include_names:n.includeName||[],max_size:n.maxSize,min_size:n.minSize,no_hidden:n.noHidden||!1,no_empty:n.noEmpty||!1,follow_links:n.followLinks||!1,max_depth:n.maxDepth,show_stats:n.stats||!1,show_progress:!0!==n.noProgress,no_binary:n.noBinary||!1,ignore_case:n.ignoreCase||!1,quiet:n.quiet||!1,export:b(n.export),export_path:n.exportPath,version:!1,watch:n.watch||!1,comments:!0!==n.noComments,code_vs_comments:n.codeVsComments||!1,rm_comments:!!n.rmComments&&(!0===n.rmComments||n.rmComments),top_files:n.topFiles,top_dirs:n.topDirs}}())})().catch(n=>{console.error("Unexpected error:",n),e.exit(1)});
|
|
2
|
+
import*as e from"fs";import{readFileSync as n}from"fs";import*as t from"os";import*as s from"path";import{dirname as o,join as i}from"path";import*as r from"@clack/prompts";import l from"chalk";import*as a from"process";import{Command as c}from"commander";import{fileURLToPath as d}from"url";import u from"fast-glob";import m from"ignore";import*as f from"crypto";var p,h,_=Object.defineProperty,g=Object.getOwnPropertyNames,y=(e=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(e,{get:(e,n)=>("undefined"!=typeof require?require:e)[n]}):e)(function(e){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),x={};function b(e){if(0===e)return"0 B";const n=Math.floor(Math.log(e)/Math.log(1024));return`${(e/Math.pow(1024,n)).toFixed(2)} ${["B","KB","MB","GB"][n]}`}function v(e){const n=((e.memoryEnd.heapUsed-e.memoryStart.heapUsed)/e.memoryStart.heapUsed*100).toFixed(1);return[`Duration: ${e.duration}ms`,`Files: ${e.filesProcessed}`,`Errors: ${e.errors}`,`Memory: ${b(e.memoryStart.heapUsed)} β ${b(e.memoryEnd.heapUsed)} (${n}%)`,`Peak Memory: ${b(e.memoryPeak.peakRss)} RSS, ${b(e.memoryPeak.peakHeapUsed)} Heap`].join(" | ")}((e,n)=>{for(var t in n)_(e,t,{get:n[t],enumerable:!0})})(x,{MemoryTracker:()=>p,UsageStatsTracker:()=>h,getPerformanceSummary:()=>v});var $,w,k=($={"src/utils/metrics.ts"(){p=class{startMemory;peakMemory;checkpoints=[];constructor(){this.startMemory=process.memoryUsage(),this.peakMemory={...this.startMemory}}checkpoint(){const e=process.memoryUsage();this.checkpoints.push({time:Date.now(),memory:e}),e.heapUsed>this.peakMemory.heapUsed&&(this.peakMemory.heapUsed=e.heapUsed),e.rss>this.peakMemory.rss&&(this.peakMemory.rss=e.rss),e.heapTotal>this.peakMemory.heapTotal&&(this.peakMemory.heapTotal=e.heapTotal),e.external>this.peakMemory.external&&(this.peakMemory.external=e.external)}getMetrics(){const e=process.memoryUsage();return{heapUsed:e.heapUsed,heapTotal:e.heapTotal,external:e.external,rss:e.rss,peakHeapUsed:this.peakMemory.heapUsed,peakRss:this.peakMemory.rss}}getStartMemory(){return this.startMemory}},h=class{statsPath;stats;constructor(){const n=t.homedir(),o=s.join(n,".locio");this.statsPath=s.join(o,"usage-stats.json");try{e.existsSync(o)||e.mkdirSync(o,{recursive:!0})}catch{}this.stats=this.loadStats()}loadStats(){try{if(e.existsSync(this.statsPath)){const n=e.readFileSync(this.statsPath,"utf-8");return JSON.parse(n)}}catch{}return{totalScans:0,totalFilesScanned:0,totalLinesScanned:0,averageCodebaseSize:0,optionUsage:{},featureUsage:{},exportFormatUsage:{},lastUpdated:(new Date).toISOString()}}saveStats(){try{this.stats.lastUpdated=(new Date).toISOString(),e.writeFileSync(this.statsPath,JSON.stringify(this.stats,null,2),"utf-8")}catch{}}trackScan(e,n){this.stats.totalScans++,this.stats.totalFilesScanned+=n.total_files,this.stats.totalLinesScanned+=n.total_lines,this.stats.totalScans>0&&(this.stats.averageCodebaseSize=Math.round(this.stats.totalFilesScanned/this.stats.totalScans));const t=["files_only","lines_only","stats","comments","code_vs_comments","watch","no_binary","no_hidden","no_empty","follow_links"];for(const n of t)e[n]&&(this.stats.optionUsage[n]=(this.stats.optionUsage[n]||0)+1);if(e.watch&&(this.stats.featureUsage.watch=(this.stats.featureUsage.watch||0)+1),(e.comments||e.code_vs_comments)&&(this.stats.featureUsage.comments=(this.stats.featureUsage.comments||0)+1),e.rm_comments&&(this.stats.featureUsage.rm_comments=(this.stats.featureUsage.rm_comments||0)+1),(e.top_files||e.top_dirs)&&(this.stats.featureUsage.top_files_dirs=(this.stats.featureUsage.top_files_dirs||0)+1),e.export){const n=Array.isArray(e.export)?e.export:[e.export];for(const e of n){const n=e||"human";this.stats.exportFormatUsage[n]=(this.stats.exportFormatUsage[n]||0)+1}}else this.stats.exportFormatUsage.human=(this.stats.exportFormatUsage.human||0)+1;this.saveStats()}getStats(){return{...this.stats}}getMostCommonOptions(e=5){return Object.entries(this.stats.optionUsage).map(([e,n])=>({option:e,count:n})).sort((e,n)=>n.count-e.count).slice(0,e)}getMostUsedExportFormats(e=5){return Object.entries(this.stats.exportFormatUsage).map(([e,n])=>({format:e,count:n})).sort((e,n)=>n.count-e.count).slice(0,e)}clearStats(){this.stats={totalScans:0,totalFilesScanned:0,totalLinesScanned:0,averageCodebaseSize:0,optionUsage:{},featureUsage:{},exportFormatUsage:{},lastUpdated:(new Date).toISOString()},this.saveStats()}}}},function(){return $&&(w=(0,$[g($)[0]])($=0)),w}),L=o(d(import.meta.url));function S(){try{const e=[i(L,"../package.json"),i(L,"../../package.json"),i(process.cwd(),"package.json")];for(const t of e)try{const e=JSON.parse(n(t,"utf-8"));if(e.version)return e.version}catch{continue}return"0.0.0"}catch(e){return"0.0.0"}}var C=class e extends Error{suggestion;code;filePath;lineNumber;constructor(e,n,t){super(e),this.name="LineCounterError",this.code=n,this.cause=t?.cause,this.suggestion=t?.suggestion,this.filePath=t?.filePath,this.lineNumber=t?.lineNumber}static io(n,t,s){return new e(`IO error: ${n}`,"IO_ERROR",{cause:t,suggestion:"Check if the file/directory exists, you have read permissions, and there's sufficient disk space.\n - Verify the path is correct\n - Check file system permissions\n - Ensure sufficient disk space is available\n - Try running with elevated permissions if needed",filePath:s})}static invalidSizeFormat(n){return new e(`Invalid size format: ${n}`,"INVALID_SIZE_FORMAT",{suggestion:"Size format should be a number followed by a unit (e.g., '5MB', '1KB', '500B').\nValid units: B, KB, MB, GB, TB (case-insensitive)."})}static invalidRegex(n,t){return new e(`Invalid regex pattern: ${n}${t?`: ${t.message}`:""}`,"INVALID_REGEX",{cause:t,suggestion:"Check your regex pattern syntax. Common issues:\n - Escape special characters with backslash (\\* for literal *)\n - Use proper grouping syntax (parentheses, brackets)\n - Verify quantifiers are properly placed\n - Test your pattern at https://regex101.com"})}static directoryNotFound(n){let t;try{t=s.resolve(n)}catch{t=n}const o=(()=>{try{return y("fs").existsSync(t)}catch{return!1}})(),i=n.includes("\\"),r=n.includes(" "),l=/['"]/.test(n),a=r&&!i&&n.includes(":");let c=`The path "${n}" does not exist.\n`;if(c+=` - Check if the path is correct (resolved: ${t})\n`,a&&(c+=" - β οΈ WARNING: Path appears to be missing backslashes (\\). This usually means the path wasn't properly quoted.\n",c+=' - On Windows, use double quotes: "D:\\path\\with spaces"\n',c+=" - Or use forward slashes: D:/path/with spaces\n",c+=" - Or escape backslashes: D:\\\\path\\\\with spaces\n"),!o){const e=s.dirname(t);c+=(()=>{try{return y("fs").existsSync(e)}catch{return!1}})()?` - Parent directory exists, but "${s.basename(t)}" is missing\n`:` - Parent directory "${e}" also does not exist\n`}return c+=" - Use relative paths like '.' for current directory\n",c+=" - Verify you have read permissions\n",c+=" - Check if it's a file instead of a directory (use the file path directly)\n",(l||r)&&(c+=" - Ensure paths with spaces or special characters are properly quoted in your shell\n"),new e(`Directory not found: ${n}`,"DIRECTORY_NOT_FOUND",{suggestion:c,filePath:n})}static notADirectory(n){return new e(`Not a directory: ${n}`,"NOT_A_DIRECTORY",{suggestion:`"${n}" exists but is not a directory.\n - If it's a file, you can scan it directly: locio <file-path>\n - If you meant a directory, check the path spelling\n - Use 'locio .' to scan the current directory`,filePath:n})}static fileNotFound(n){return new e(`File not found: ${n}`,"FILE_NOT_FOUND",{suggestion:`The file "${n}" does not exist.\n - Check if the file path is correct\n - Verify the file extension\n - Ensure you have read permissions`,filePath:n})}static exportPathError(n,t){return new e(`Export path error: ${n}`,"EXPORT_PATH_ERROR",{suggestion:`Cannot write to export path "${n}": ${t}\n - Ensure the directory exists or can be created\n - Check write permissions\n - Verify there's sufficient disk space\n - Use an absolute path if relative paths aren't working`,filePath:n})}static fileProcessingError(n,t,s){return new e(`File processing error: ${t}`,"FILE_PROCESSING_ERROR",{cause:s,suggestion:`Error processing file "${n}": ${t}\n - Check if the file is readable\n - Verify file encoding (should be UTF-8)\n - Ensure file is not corrupted\n - Check available memory`,filePath:n})}static commentParsingError(n,t,s){return new e(`Comment parsing error: ${t}`,"COMMENT_PARSING_ERROR",{cause:s,suggestion:`Comment parsing failed for "${n}": ${t}\n - File will be processed with basic line counting\n - Comment statistics may be incomplete\n - Check file encoding and syntax`,filePath:n})}};function z(e){return e instanceof C}function E(e,n){return n&&Array.isArray(n)?[...n,e]:[e]}function j(e){return e.split(",").map(e=>e.trim()).filter(Boolean)}function F(e){if(void 0===e)return;if(!0===e)return"human";const n={json:"json",csv:"csv",tsv:"tsv",markdown:"markdown",md:"markdown",html:"html",human:"human",txt:"human"},t=j(e).map(e=>n[e.toLowerCase()]).filter(e=>void 0!==e);return t.length>0?1===t.length?t[0]:t:void 0}function M(n){if(!n||0===n.trim().length)return{path:null,error:C.directoryNotFound("")};let t;try{t=s.resolve(n.trim())}catch(e){return{path:null,error:C.directoryNotFound(n)}}if(!e.existsSync(t))return{path:null,error:C.directoryNotFound(n)};const o=e.statSync(t);return o.isDirectory()||o.isFile()?{path:t,error:null}:{path:null,error:C.notADirectory(n)}}function D(e,n){const t=e.length>n.length?e:n;if(0===t.length)return 1;const s=function(e,n){const t=[];for(let e=0;e<=n.length;e++)t[e]=[e];for(let n=0;n<=e.length;n++){const e=t[0];e&&(e[n]=n)}for(let s=1;s<=n.length;s++){const o=t[s];if(o)for(let i=1;i<=e.length;i++){const r=t[s-1];r&&(n.charAt(s-1)===e.charAt(i-1)?o[i]=r[i-1]??0:o[i]=Math.min((r[i-1]??0)+1,(o[i-1]??0)+1,(r[i]??0)+1))}}const s=t[n.length];return s?.[e.length]??0}(e,n);return(t.length-s)/t.length}function T(){const e=new c,n=["files-only","lines-only","exclude","exclude-ext","include-ext","exclude-dir","include-dir","exclude-name","include-name","max-size","min-size","no-hidden","no-empty","follow-links","max-depth","stats","no-progress","no-binary","ignore-case","quiet","export","export-path","watch","no-comments","code-vs-comments","rm-comments","top-files","top-dirs","version"];return e.configureOutput({writeErr:e=>{if(e.includes("unknown option")){const t=e.match(/unknown option ['"]--?([^'"]+)['"]/);if(t){const e=t[1],s=function(e,n,t=3){return n.map(n=>({option:n,score:D(e,n)})).sort((e,n)=>n.score-e.score).filter(e=>e.score>.3).slice(0,t).map(e=>e.option)}(e,n);if(s.length>0){const n=1===s.length?"Did you mean this?":"Did you mean one of these?";process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ ${n}\n`+s.map(e=>` β’ --${e}`).join("\n")+"\n\nRun 'locio --help' to see all available options.\n\n"),process.exit(1)}process.stderr.write(`\nβ Unknown option: '--${e}'\n\nπ‘ This option doesn't exist. Run 'locio --help' to see all available options.\n\n`),process.exit(1)}}process.stderr.write(e)}}),e.name("LocIO").description("A powerful CLI tool to count lines and files in directories").version(S(),"-v, --version","Show version number").argument("[directory]","Directory to scan",".").option("-f, --files-only","Count only files").option("-l, --lines-only","Count only lines").option("-e, --exclude <pattern>","Exclude files matching pattern",E).option("--exclude-ext <extensions>","Exclude file extensions (comma-separated)").option("--include-ext <extensions>","Include only file extensions (comma-separated)").option("--exclude-dir <pattern>","Exclude directories matching pattern",E).option("--include-dir <pattern>","Include only directories matching pattern",E).option("--exclude-name <pattern>","Exclude files by name pattern",E).option("--include-name <pattern>","Include only files by name pattern",E).option("--max-size <size>","Maximum file size (e.g., 5MB)").option("--min-size <size>","Minimum file size (e.g., 1KB)").option("--no-hidden","Exclude hidden files").option("--no-empty","Exclude empty files").option("--follow-links","Follow symbolic links").option("--max-depth <depth>","Maximum directory depth",parseInt).option("--stats","Show detailed statistics").option("--no-progress","Disable progress indicator (enabled by default)").option("--no-binary","Exclude binary files").option("-i, --ignore-case","Case-insensitive pattern matching").option("-q, --quiet","Quiet mode (minimal output)").option("--export [format]","Write report to LocIO-report.{ext} in the given format (human, json, csv, tsv, markdown, html). Multiple formats can be specified comma-separated (e.g., json,html,markdown)").option("--export-path <dir>","Specify output directory for exported reports. Files will use default naming (LocIO-report.{ext}). Directories will be created automatically if they don't exist").option("-w, --watch","Watch directory for changes and auto-rescan").option("--watch-debounce <ms>","Debounce delay for watch mode in milliseconds (default: 500, min: 100, max: 5000)",parseInt).option("--no-comments","Disable comment counting (enabled by default)").option("--code-vs-comments","Show code vs comments ratio (automatically enables --comments)").option("--rm-comments [extensions]","Remove comments from files (modifies files in place). Optionally specify file extensions (comma-separated, e.g., js,ts,py). If no extensions specified, all files are processed.").option("--top-files <n>","Show top N largest files by size",parseInt).option("--top-dirs <n>","Show top N directories with most files",parseInt),e}var U=[{type:"nextjs",files:["next.config.js","next.config.ts","next.config.mjs","next.config.cjs"],packageJsonDeps:["next"],packageJsonDevDeps:["next"],priority:100},{type:"angular",files:["angular.json","angular-cli.json"],packageJsonDeps:["@angular/core"],packageJsonDevDeps:["@angular/cli","@angular/core"],priority:90},{type:"vue",files:["vue.config.js","vue.config.ts","vite.config.js","vite.config.ts"],packageJsonDeps:["vue"],packageJsonDevDeps:["vue","@vitejs/plugin-vue","vite"],dirs:[".nuxt"],priority:85},{type:"react",files:["react-scripts"],packageJsonDeps:["react"],packageJsonDevDeps:["react","react-scripts","@vitejs/plugin-react","vite"],dirs:["node_modules/react"],priority:80},{type:"typescript",files:["tsconfig.json","tsconfig.app.json","tsconfig.base.json"],priority:70},{type:"nodejs",files:["package.json"],priority:75},{type:"rust",files:["Cargo.toml","Cargo.lock"],priority:100},{type:"python",files:["requirements.txt","setup.py","pyproject.toml","Pipfile","poetry.lock","manage.py","setup.cfg","Pipfile.lock"],dirs:["__pycache__"],priority:100},{type:"go",files:["go.mod","go.sum","Gopkg.toml","Gopkg.lock"],priority:100},{type:"java",files:["pom.xml","build.gradle","build.gradle.kts","settings.gradle"],dirs:[".gradle"],priority:100},{type:"csharp",files:["*.csproj","*.sln","project.json","*.fsproj","*.vbproj"],dirs:[".vs"],priority:100},{type:"ruby",files:["Gemfile","Rakefile","Gemfile.lock"],dirs:[".bundle"],priority:100},{type:"php",files:["composer.json","composer.lock","artisan"],dirs:["vendor"],priority:100},{type:"swift",files:["Package.swift","*.xcodeproj","*.xcworkspace"],dirs:[".build"],priority:100},{type:"kotlin",files:["build.gradle.kts","settings.gradle.kts"],dirs:[".gradle"],priority:100},{type:"dart",files:["pubspec.yaml","pubspec.yml","pubspec.lock"],dirs:[".dart_tool"],priority:100}],O={nodejs:{exclude_dirs:["node_modules",".next",".nuxt",".cache","dist","build",".turbo",".vercel",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},nextjs:{exclude_dirs:["node_modules",".next",".vercel","out","dist","build",".turbo"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},react:{exclude_dirs:["node_modules","build","dist",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},vue:{exclude_dirs:["node_modules","dist",".nuxt",".cache","coverage",".output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},angular:{exclude_dirs:["node_modules","dist",".angular","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},typescript:{exclude_dirs:["node_modules","dist","build",".cache","coverage",".nyc_output"],exclude_extensions:[],exclude_names:["package-lock.json","yarn.lock","pnpm-lock.yaml"]},rust:{exclude_dirs:["target",".cargo"],exclude_extensions:[],exclude_names:["Cargo.lock"]},python:{exclude_dirs:["__pycache__",".pytest_cache",".mypy_cache",".ruff_cache",".venv","venv","env",".env","build","dist",".*\\.egg-info",".tox",".coverage","htmlcov",".hypothesis"],exclude_extensions:["pyc","pyo","pyd","so"],exclude_names:[".python-version","pip-log.txt","pip-delete-this-directory.txt"]},go:{exclude_dirs:["vendor",".cache"],exclude_extensions:[],exclude_names:["go.sum"]},java:{exclude_dirs:["target","build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar","war","ear"],exclude_names:[".project",".*\\.iml"]},csharp:{exclude_dirs:["bin","obj",".vs","packages","TestResults","[Bb]in","[Oo]bj"],exclude_extensions:["dll","exe","pdb"],exclude_names:[]},ruby:{exclude_dirs:["vendor",".bundle","tmp","log"],exclude_extensions:[],exclude_names:["Gemfile.lock"]},php:{exclude_dirs:["vendor","node_modules"],exclude_extensions:[],exclude_names:["composer.lock"]},swift:{exclude_dirs:[".build",".swiftpm","DerivedData"],exclude_extensions:[],exclude_names:["Package.resolved"]},kotlin:{exclude_dirs:["build",".gradle","out",".idea",".classpath",".settings"],exclude_extensions:["class","jar"],exclude_names:[".project",".*\\.iml"]},dart:{exclude_dirs:[".dart_tool","build"],exclude_extensions:[],exclude_names:["pubspec.lock"]},unknown:{exclude_dirs:[],exclude_extensions:[],exclude_names:[]}};function P(e,n,t){if(!e||!n&&!t)return!1;const s={...e.dependencies||{},...e.devDependencies||{}};if(n)for(const e of n)if(s[e])return!0;if(t)for(const e of t)if(s[e])return!0;return!1}function R(e,n){if(!e||!n||!e.scripts)return!1;for(const t of n)if(e.scripts[t])return!0;return!1}function I(n,t){if(t.includes("*"))try{const o=e.readdirSync(n),i=t.replace(/\*/g,".*"),r=new RegExp(`^${i}$`);return o.some(t=>{const o=s.join(n,t);try{const n=e.statSync(o);return(n.isFile()||n.isDirectory())&&r.test(t)}catch{return!1}})}catch{return!1}else{const o=s.join(n,t);try{if(e.existsSync(o)){return e.statSync(o).isFile()}}catch{}}return!1}function B(n,t){const o=s.join(n,t);try{if(e.existsSync(o)){return e.statSync(o).isDirectory()}}catch{}return!1}function N(n,t=2){try{const o=e.readdirSync(n);for(const i of o){const o=s.join(n,i);try{const n=e.statSync(o);if(n.isFile()&&(i.endsWith(".ts")||i.endsWith(".tsx")))return!0;if(n.isDirectory()&&t>0&&!i.startsWith(".")&&"node_modules"!==i&&N(o,t-1))return!0}catch{}}}catch{}return!1}function A(n){const t=s.resolve(n);let o=t;try{e.statSync(t).isFile()&&(o=s.dirname(t))}catch{}const i=new Map,r=function(n){const t=s.join(n,"package.json");try{if(e.existsSync(t)){const n=e.readFileSync(t,"utf-8");return JSON.parse(n)}}catch{}return null}(o);for(const n of U){let t=0;const l=[];for(const e of n.files)I(o,e)&&(t+=30,l.push(`file:${e}`));if(n.dirs)for(const e of n.dirs)B(o,e)&&(t+=20,l.push(`dir:${e}`));if((n.packageJsonDeps||n.packageJsonDevDeps)&&P(r,n.packageJsonDeps,n.packageJsonDevDeps)){t+=50;const e=[...n.packageJsonDeps||[],...n.packageJsonDevDeps||[]];l.push(`dep:${e.join(",")}`)}if(n.packageJsonScripts&&R(r,n.packageJsonScripts)&&(t+=15,l.push(`script:${n.packageJsonScripts.join(",")}`)),"typescript"===n.type&&(I(o,"tsconfig.json")&&(t+=30,l.push("file:tsconfig.json")),N(o)&&(t+=20,l.push("typescript-files")),r&&I(o,"package.json"))){P(r,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(t=Math.floor(.5*t),l.push("nodejs-backend-penalty"))}if("nodejs"===n.type&&I(o,"package.json")&&(I(o,"tsconfig.json")||N(o))&&(t+=40,l.push("nodejs-with-typescript")),"react"===n.type)try{const n=e.readdirSync(o);n.some(n=>{const t=s.join(o,n);try{return e.statSync(t).isFile()&&(n.endsWith(".jsx")||n.endsWith(".tsx"))}catch{return!1}})&&(t+=15,l.push("jsx-files"))}catch{}t=Math.floor(t*(1+n.priority/100)),t>0&&i.set(n.type,{type:n.type,score:t,indicators:l})}if(r){if(!Array.from(i.keys()).some(e=>"react"===e||"vue"===e||"angular"===e||"nextjs"===e)){const e=I(o,"tsconfig.json")||N(o);if(e&&I(o,"package.json")){P(r,["express","koa","fastify","nest","@nestjs/core"],["ts-node","ts-node-dev"])&&(i.has("nodejs")||i.set("nodejs",{type:"nodejs",score:55,indicators:["package.json","nodejs-backend-with-typescript"]})),i.has("typescript")||i.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]})}else e?i.has("typescript")||i.set("typescript",{type:"typescript",score:40,indicators:["tsconfig-or-ts-files"]}):i.has("nodejs")||i.set("nodejs",{type:"nodejs",score:30,indicators:["package.json"]})}}return Array.from(i.values()).sort((e,n)=>n.score-e.score)}function W(e){const n=A(e);return 0===n.length?"unknown":n[0].type}var q=8192,G=1048576,J=10485760,V=1e3,H=104857600,K=8,Q=100,Y=500,Z=100,X=5e3,ee="**/*",ne=new Set(["/","/bin","/sbin","/usr/bin","/usr/sbin","/etc","/var","/sys","/proc","/dev","C:\\Windows","C:\\Windows\\System32","C:\\Program Files","C:\\Program Files (x86)",t.homedir()]);function te(e,n){try{if(e.includes("\0"))return!1;const t=e.replace(/\\/g,"/"),o=n.replace(/\\/g,"/"),i=s.resolve(t),r=s.resolve(o),l=s.relative(r,i);if(l.includes("..")||s.isAbsolute(l))return!1;const a=i.replace(/\\/g,"/"),c=r.replace(/\\/g,"/");return!(!a.startsWith(c+"/")&&a!==c)}catch{return!1}}function se(e,n){if(e.includes("\0"))throw C.exportPathError(e,"Path contains null bytes");let t;t=s.isAbsolute(e)?s.resolve(e):s.resolve(n,e);const o=s.resolve(n),i=s.relative(o,s.dirname(t));if(i.startsWith("..")||s.isAbsolute(i))throw C.exportPathError(e,"Path traversal detected in export path");const r=s.basename(t),l=r.replace(/[<>:"|?*\x00-\x1f]/g,"_");return l!==r&&(t=s.join(s.dirname(t),l)),t}function oe(n,t=H){try{return e.statSync(n).size<=t}catch{return!1}}function ie(n,t=H){const s=function(n){try{return e.statSync(n).size}catch{return null}}(n);return null===s||s>t}var re=class{events=[];maxEvents;timeWindow;constructor(e=100,n=1e3){this.maxEvents=e,this.timeWindow=n}shouldAllow(){const e=Date.now();return this.events=this.events.filter(n=>e-n<this.timeWindow),!(this.events.length>=this.maxEvents)&&(this.events.push(e),!0)}reset(){this.events=[]}},le=new Map;function ae(e){const n=e.toLowerCase().replace(/^\./,"");if(le.has(n))return le.get(n);const t=[];let s="",o="",i=!1;switch(n){case"js":case"jsx":case"ts":case"tsx":case"c":case"cpp":case"cc":case"cxx":case"h":case"hpp":case"java":case"cs":case"php":case"swift":case"go":case"rust":case"rs":case"dart":case"kt":case"scala":case"sc":t.push("//"),s="/*",o="*/",i=!0;break;case"sh":case"bash":case"zsh":case"fish":case"py":case"python":case"rb":case"ruby":case"r":case"pl":case"perl":case"yaml":case"yml":case"toml":case"conf":case"ini":case"cfg":case"dockerfile":case"makefile":case"make":case"cmake":case"ps1":case"psm1":case"ex":case"exs":t.push("#");break;case"html":case"htm":case"xml":case"xhtml":case"svg":t.push("\x3c!--"),s="\x3c!--",o="--\x3e",i=!0;break;case"css":case"scss":case"sass":case"less":case"styl":s="/*",o="*/",i=!0;break;case"sql":t.push("--"),s="/*",o="*/",i=!0;break;case"lua":t.push("--"),s="--[[",o="]]",i=!0;break;case"pas":case"p":case"pp":case"fs":case"fsi":case"fsx":t.push("//"),s="(*",o="*)",i=!0;break;case"hs":case"lhs":t.push("--"),s="{-",o="-}",i=!0;break;case"erl":case"hrl":case"m":case"matlab":t.push("%");break;case"vhd":case"vhdl":t.push("--");break;case"bat":case"cmd":t.push("::");break;case"vbs":t.push("'");break;case"clj":case"cljs":case"cljc":case"lisp":case"lsp":case"el":case"rkt":case"rktl":t.push(";");break;case"ml":case"mli":s="(*",o="*)",i=!0;break;default:t.push("//","#","--")}const r={singleLine:t,multiLineStart:s,multiLineEnd:o,supportsMultiLine:i};return le.set(n,r),r}function ce(e,n,t,s=0){let o=s,i=!1,r=0,l=-1;const a=[];let c=-1,d=-1;for(;r<e.length;){const s=e[r];if(i)i=!1,r++;else if("\\"!==s||0===o){if(3===o&&"$"===s&&r+1<e.length&&"{"===e[r+1]){let n=1;for(r+=2;r<e.length&&n>0;)"{"===e[r]?n++:"}"===e[r]&&n--,r++;continue}if(0===o){if('"'===s)o=2;else if("'"===s)o=1;else if("`"===s)o=3;else if("/"===s&&r+1<e.length){const t=e[r+1];if("/"===t||"*"===t){for(const t of n.singleLine)if(e.substring(r).startsWith(t)){a.push({pos:r,marker:t});break}n.supportsMultiLine&&-1===c&&e.substring(r).startsWith(n.multiLineStart)&&(c=r),r++;continue}{const n=r>0?e[r-1]:" ";/[\s,;=([{!&|?:]/.test(n)&&(o=4,l=r)}}}else if(2===o&&'"'===s)o=0;else if(1===o&&"'"===s)o=0;else if(3===o&&"`"===s)o=0;else if(4===o){if("\\"===s){r+1<e.length?r+=2:r++;continue}if("/"===s)if(r+1<e.length){const n=e[r+1];if(/[gimsuvy]/.test(n)){let n=r+1;for(;n<e.length&&/[gimsuvy]/.test(e[n]);)n++;(n>=e.length||!/[a-zA-Z0-9_]/.test(e[n]))&&(o=0,l=-1,r=n-1)}else/[a-zA-Z0-9_]/.test(n)||(o=0,l=-1)}else o=0,l=-1;else if(" "===s||"\t"===s){const n=r-l-1;let t=!0;for(let n=l+1;n<r;n++)if(" "!==e[n]&&"\t"!==e[n]){t=!1;break}if(t&&n<=2){let n=r+1;for(;n<e.length&&(" "===e[n]||"\t"===e[n]);)n++;n<e.length&&/[0-9;,)}\]\]]/.test(e[n])&&(o=0,l=-1)}}else/[;,)}\]\]]/.test(s)&&(o=0,l=-1)}if(0===o){const s=a.length;for(const t of n.singleLine)if(e.substring(r).startsWith(t)){a.push({pos:r,marker:t});break}if(a.length>s)break;if(n.supportsMultiLine&&-1===c&&e.substring(r).startsWith(n.multiLineStart)){c=r;break}if(n.supportsMultiLine&&t&&e.substring(r).startsWith(n.multiLineEnd)){d=r;break}}r++}else i=!0,r++}if(t){if(-1!==d){const t=e.substring(0,d).trim(),s=e.substring(d+n.multiLineEnd.length).trim();return{commentStart:0,commentEnd:d+n.multiLineEnd.length,isMultiLine:!0,endsMultiLine:!0,commentMarker:n.multiLineEnd,hasCodeBefore:t.length>0,hasCodeAfter:s.length>0,stringState:0}}return{commentStart:0,commentEnd:e.length,isMultiLine:!0,endsMultiLine:!1,commentMarker:n.multiLineEnd,hasCodeBefore:!1,hasCodeAfter:!1,stringState:0}}if(n.supportsMultiLine&&-1!==c){const t=e.substring(0,c).trim(),s=e.indexOf(n.multiLineEnd,c),o=-1!==s,i=o?e.substring(s+n.multiLineEnd.length).trim():"";return{commentStart:c,commentEnd:o?s+n.multiLineEnd.length:e.length,isMultiLine:!0,endsMultiLine:o,commentMarker:n.multiLineStart,hasCodeBefore:t.length>0,hasCodeAfter:i.length>0,stringState:0}}if(a.length>0){const n=a[0],t=e.substring(0,n.pos).trim();return{commentStart:n.pos,commentEnd:e.length,isMultiLine:!1,endsMultiLine:!1,commentMarker:n.marker,hasCodeBefore:t.length>0,hasCodeAfter:!1,stringState:0}}return{commentStart:0,commentEnd:0,isMultiLine:!1,endsMultiLine:!1,commentMarker:"",hasCodeBefore:!1,hasCodeAfter:!1,stringState:o}}function de(n,t){try{const o=(t||e.readFileSync(n,"utf-8")).split(/\r?\n/),i=ae(s.extname(n));let r=o.length,l=0,a=0,c=0,d=0,u=0,m=!1,f=0;for(const e of o){if(0===e.trim().length){m?(a++,c++):u++;continue}const n=ce(e,i,m,f);if(n&&(f=n.stringState),n&&n.commentMarker){n.isMultiLine&&(m=!n.endsMultiLine);!n.hasCodeBefore?(c++,n.hasCodeAfter&&l++):(d++,l++),a++}else m?(a++,c++):l++}return{totalLines:r,codeLines:l,commentLines:a,fullLineComments:c,inlineComments:d,blankLines:u}}catch{return null}}function ue(n){try{const t=e.readFileSync(n,"utf-8"),o=t.split(/\r?\n/),i=ae(s.extname(n));let r=!1;const l=[];let a=!1;for(const e of o){const n=e,t=fe(e,i,r);t.line!==n&&(a=!0),!t.line.trim()&&t.isEmpty||l.push(t.line),r=t.inMultiLineComment}const c=l.join("\n");return a||c!==t?(e.writeFileSync(n,c,"utf-8"),{success:!0,commentsFound:!0}):{success:!0,commentsFound:!1}}catch{return{success:!1,commentsFound:!1}}}function me(e){const n=e.replace(/^\/\//,"").replace(/^\/\*/,"").replace(/\*\/$/,"").trim().toLowerCase();return n.startsWith("eslint")||n.startsWith("@eslint")||n.includes("eslint-disable")||n.includes("eslint-enable")}function fe(e,n,t){if(t){const t=e.indexOf(n.multiLineEnd);if(-1!==t){const s=e.substring(0,t+n.multiLineEnd.length),o=e.substring(t+n.multiLineEnd.length);return me(s)?{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length}:{line:o.trimEnd(),inMultiLineComment:!1,isEmpty:0===o.trim().length}}return me(e)?{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length}:{line:"",inMultiLineComment:!0,isEmpty:!0}}let s=0,o=!1,i=0,r=-1;const l=[];let a=-1;for(;i<e.length;){const t=e[i];if(o)o=!1,i++;else if("\\"!==t||0===s){if(3===s&&"$"===t&&i+1<e.length&&"{"===e[i+1]){let n=1;for(i+=2;i<e.length&&n>0;)"{"===e[i]?n++:"}"===e[i]&&n--,i++;continue}if(0===s){if('"'===t)s=2;else if("'"===t)s=1;else if("`"===t)s=3;else if("/"===t&&i+1<e.length){const t=e[i+1];if("/"===t||"*"===t){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){l.push(i);break}n.supportsMultiLine&&-1===a&&e.substring(i).startsWith(n.multiLineStart)&&(a=i),i++;continue}{const n=i>0?e[i-1]:" ";/[\s,;=([{!&|?:]/.test(n)&&(s=4,r=i)}}}else if(2===s&&'"'===t)s=0;else if(1===s&&"'"===t)s=0;else if(3===s&&"`"===t)s=0;else if(4===s){if("\\"===t){i+1<e.length?i+=2:i++;continue}if("/"===t)if(i+1<e.length){const n=e[i+1];if(/[gimsuvy]/.test(n)){let n=i+1;for(;n<e.length&&/[gimsuvy]/.test(e[n]);)n++;(n>=e.length||!/[a-zA-Z0-9_]/.test(e[n]))&&(s=0,r=-1,i=n-1)}else/[a-zA-Z0-9_]/.test(n)||(s=0,r=-1)}else s=0,r=-1;else if(" "===t||"\t"===t){const n=i-r-1;let t=!0;for(let n=r+1;n<i;n++)if(" "!==e[n]&&"\t"!==e[n]){t=!1;break}if(t&&n<=2){let n=i+1;for(;n<e.length&&(" "===e[n]||"\t"===e[n]);)n++;n<e.length&&/[0-9;,)}\]\]]/.test(e[n])&&(s=0,r=-1)}}else/[;,)}\]\]]/.test(t)&&(s=0,r=-1)}if(0===s){for(const t of n.singleLine)if(e.substring(i).startsWith(t)){l.push(i);break}n.supportsMultiLine&&-1===a&&e.substring(i).startsWith(n.multiLineStart)&&(a=i)}i++}else o=!0,i++}if(-1!==a){const t=e.substring(0,a),s=e.indexOf(n.multiLineEnd,a+n.multiLineStart.length);if(-1!==s){const o=e.substring(a,s+n.multiLineEnd.length),i=e.substring(s+n.multiLineEnd.length);if(me(o))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};const r=(t+i).trimEnd();return{line:r,inMultiLineComment:!1,isEmpty:0===r.length}}{if(me(e.substring(a)))return{line:e.trimEnd(),inMultiLineComment:!0,isEmpty:0===e.trim().length};const n=t.trimEnd();return{line:n,inMultiLineComment:!0,isEmpty:0===n.length}}}if(l.length>0){const t=l[0];for(const s of n.singleLine)if(e.substring(t).startsWith(s)){if(me(e.substring(t+s.length)))return{line:e.trimEnd(),inMultiLineComment:!1,isEmpty:0===e.trim().length};break}const s=e.substring(0,t).trimEnd();return{line:s,inMultiLineComment:!1,isEmpty:0===s.length}}return{line:e,inMultiLineComment:!1,isEmpty:!1}}function pe(e){const n=["B","KB","MB","GB","TB"];let t=e,s=0;for(;t>=1024&&s<n.length-1;)t/=1024,s+=1;return 0===s?`${Math.floor(t)} ${n[s]}`:`${t.toFixed(2)} ${n[s]}`}function he(){return a.stdout.columns||80}var _e={success:l.green,info:l.cyan,warning:l.yellow,error:l.red,highlight:l.white.bold,muted:l.gray};function ge(e){return{codeLines:e.code_lines||0,commentLines:e.comment_lines||0,fullLineComments:e.full_line_comments||0,inlineComments:e.inline_comments||0}}function ye(e,n,t,s,o){let i=` (${e} code, ${n} comments`;return void 0!==o&&o>0&&(i+=`, ${o} blank`),(t>0||s>0)&&(i+=`: ${t} full-line, ${s} inline`),i+=")",i}function xe(e,n,t,s,o){let i=` ${l.gray(`(${l.blue(e)} code, ${l.cyan(n)} comments`)}`;return void 0!==o&&o>0&&(i+=l.gray(`, ${l.gray(o)} blank`)),(t>0||s>0)&&(i+=l.gray(`: ${l.yellow(t)} full-line, ${l.magenta(s)} inline`)),i+=l.gray(")"),i}function be(e,n){return(e.comments||e.show_stats)&&!e.files_only&&n}function ve(e,n,t){return{sizeStr:pe(e),linesStr:null===n||t.files_only?"":` | ${n} lines`}}function $e(e){const n={};for(const t of e)n[t.directory]||(n[t.directory]=[]),n[t.directory].push(t);return n}function we(n){try{return e.statSync(n.directory).isFile()}catch{return!1}}function ke(n){const t=n.directory;try{if(e.statSync(t).isFile())return s.basename(t)}catch{}return"."===t?"current":t}function Le(e){return{nodejs:"Node.js",rust:"Rust",python:"Python",go:"Go",java:"Java",csharp:"C#",ruby:"Ruby",php:"PHP",swift:"Swift",kotlin:"Kotlin",dart:"Dart",typescript:"TypeScript",vue:"Vue.js",react:"React",angular:"Angular",nextjs:"Next.js",unknown:"Unknown"}[e]||e}function Se(e,n){return[...e.details].sort((e,n)=>n.size-e.size).slice(0,n)}function Ce(e,n){const t={};for(const n of e.details)t[n.directory]||(t[n.directory]={fileCount:0,totalSize:0,totalLines:0}),t[n.directory].fileCount+=1,t[n.directory].totalSize+=n.size,null!==n.lines&&(t[n.directory].totalLines+=n.lines);return Object.entries(t).map(([e,n])=>({directory:e,...n})).sort((e,n)=>n.fileCount-e.fileCount).slice(0,n)}function ze(e){return e.files_by_extension?Object.keys(e.files_by_extension).sort():[]}function Ee(e,n,t){switch(e){case"human":return function(e,n){let t="";if(n.quiet)return t+=`${e.total_files} ${e.total_lines}\n`,t;const s=he(),o=Math.min(60,s-2),i="=".repeat(o);t+=i+"\n",t+="LocIO RESULTS".padStart(Math.floor(o/2)+6).padEnd(o)+"\n",t+=i+"\n\n",t+=`Directory: ${ke(n)}\n`,n.lines_only||(we(n)?t+=`\nSize: ${pe(e.total_size)}\n`:(t+=`\nTotal Files: ${e.total_files}\n`,t+=`\nTotal Files Size: ${pe(e.total_size)}\n`)),!n.files_only&&(t+=`\nTotal Lines: ${e.total_lines}\n`,(n.comments||n.show_stats)&&void 0!==e.total_comment_lines&&(t+=`Total Comment Lines: ${e.total_comment_lines}\n`,void 0!==e.total_full_line_comments&&(t+=` - Full Line Comments: ${e.total_full_line_comments}\n`),void 0!==e.total_inline_comments&&(t+=` - Inline Comments: ${e.total_inline_comments}\n`),void 0!==e.total_code_lines&&(t+=`Total Code Lines: ${e.total_code_lines}\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(t+=`Total Blank Lines: ${e.total_blank_lines}\n`),n.code_vs_comments&&void 0!==e.total_code_lines))&&(t+=`Code vs Comments Ratio: ${e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00"}:1 (${e.total_comment_lines} comments per ${e.total_code_lines} code lines)\n`);const r=ze(e);if(r.length>0&&(t+=`\nExtensions: ${r.join(", ")}\n`),n.show_stats&&r.length>0){t+="\nStatistics by Extension:\n",t+="-".repeat(60)+"\n";for(const s of r){const o=e.files_by_extension[s],i=e.size_by_extension[s]||0,r=e.lines_by_extension[s]||0;if(t+=` ${s}: ${o} files`,n.lines_only||(t+=`, ${pe(i)}`),!n.files_only&&(t+=`, ${r} lines`,be(n,void 0!==e.comment_lines_by_extension?.[s]))){const o=ge({comment_lines:e.comment_lines_by_extension?.[s]||0,code_lines:e.code_lines_by_extension?.[s]||0,full_line_comments:e.full_line_comments_by_extension?.[s]||0,inline_comments:e.inline_comments_by_extension?.[s]||0}),i=e.blank_lines_by_extension?.[s]||0;t+=ye(o.codeLines,o.commentLines,o.fullLineComments,o.inlineComments,i),n.code_vs_comments&&o.codeLines>0&&(t+=` [${(o.commentLines/o.codeLines).toFixed(2)}:1]`)}t+="\n"}}if(n.show_stats&&e.details&&e.details.length>0){t+="\nFiles by Directory:\n",t+="-".repeat(60)+"\n";const s=$e(e.details),o=Object.keys(s).sort();for(const e of o){const o=s[e];t+=`Directory: ${e}\n`;for(const e of o){const s=pe(e.size),o=null===e.lines||n.files_only?"":` | ${e.lines} lines`;let i="";if(be(n,void 0!==e.comment_lines&&null!==e.comment_lines)){const n=ge(e);i=ye(n.codeLines,n.commentLines,n.fullLineComments,n.inlineComments,e.blank_lines||void 0)}t+=` - ${e.name} (${e.extension}, ${s}${o}${i})\n`}t+="\n"}}if(n.top_files&&n.top_files>0){const s=Se(e,n.top_files);t+=`\nTop ${n.top_files} Largest Files:\n`,t+="-".repeat(60)+"\n";for(const e of s){const{sizeStr:s,linesStr:o}=ve(e.size,e.lines,n);t+=` ${s.padEnd(10)} ${e.name} (${e.extension})${o}\n`}}if(n.top_dirs&&n.top_dirs>0){const s=Ce(e,n.top_dirs);t+=`\nTop ${n.top_dirs} Directories (by file count):\n`,t+="-".repeat(60)+"\n";for(const e of s){const s=pe(e.totalSize),o=n.files_only?"":` | ${e.totalLines} lines`;t+=` ${e.fileCount.toString().padEnd(5)} files ${e.directory} (${s}${o})\n`}}return t+="\n",t}(n,t);case"json":return function(e,n){const t=W(n.directory),s={directory:ke(n)};if("unknown"!==t&&(s.project_type=t,s.project_type_display=Le(t)),we(n)||(s.files=e.total_files,s.size=e.total_size,s.size_formatted=pe(e.total_size)),n.files_only||(s.lines=e.total_lines,n.comments&&(s.comment_lines=e.total_comment_lines||0,s.code_lines=e.total_code_lines||0,s.blank_lines=e.total_blank_lines||0,s.full_line_comments=e.total_full_line_comments||0,s.inline_comments=e.total_inline_comments||0,n.code_vs_comments&&void 0!==e.total_code_lines&&(s.code_vs_comments_ratio=e.total_code_lines>0?parseFloat((e.total_comment_lines/e.total_code_lines).toFixed(2)):0))),n.show_stats){const t={},o=ze(e);if(o.length>0)for(const s of o)t[s]={files:e.files_by_extension[s],lines:e.lines_by_extension[s]||0,size:e.size_by_extension[s]||0},n.comments&&(t[s].comment_lines=e.comment_lines_by_extension?.[s]||0,t[s].code_lines=e.code_lines_by_extension?.[s]||0,t[s].blank_lines=e.blank_lines_by_extension?.[s]||0,t[s].full_line_comments=e.full_line_comments_by_extension?.[s]||0,t[s].inline_comments=e.inline_comments_by_extension?.[s]||0,n.code_vs_comments&&e.code_lines_by_extension?.[s]&&e.code_lines_by_extension[s]>0&&(t[s].code_vs_comments_ratio=parseFloat(((e.comment_lines_by_extension[s]||0)/e.code_lines_by_extension[s]).toFixed(2))));s.stats=t,s.by_extension=t}if(n.top_files&&n.top_files>0){const t=Se(e,n.top_files);s.top_files=t.map(e=>({name:e.name,directory:e.directory,extension:e.extension,size:e.size,size_formatted:pe(e.size),lines:e.lines}))}if(n.top_dirs&&n.top_dirs>0){const t=Ce(e,n.top_dirs);s.top_directories=t.map(e=>({directory:e.directory,file_count:e.fileCount,total_size:e.totalSize,total_size_formatted:pe(e.totalSize),total_lines:e.totalLines}))}return JSON.stringify(s,null,2)}(n,t);case"csv":return function(e,n){const t=W(n.directory);let s=`# Directory,${ke(n)}\n`;if("unknown"!==t&&(s+=`# Project Type,${Le(t)}\n`),n.comments){s+="Extension,Files,Lines,Code Lines,Comment Lines,Blank Lines,Size",n.code_vs_comments&&(s+=",Code vs Comments Ratio"),s+="\n";const t=ze(e);for(const o of t){const t=e.files_by_extension[o],i=e.lines_by_extension[o]||0,r=e.code_lines_by_extension?.[o]||0,l=e.comment_lines_by_extension?.[o]||0;s+=`${o},${t},${i},${r},${l},${e.blank_lines_by_extension?.[o]||0},${e.size_by_extension[o]||0}`,n.code_vs_comments&&r>0&&(s+=`,${((l||0)/r).toFixed(2)}`),s+="\n"}}else{s+="Extension,Files,Lines,Size\n";const n=ze(e);for(const t of n)s+=`${t},${e.files_by_extension[t]},${e.lines_by_extension[t]||0},${e.size_by_extension[t]||0}\n`}return s}(n,t);case"tsv":return function(e,n){const t=W(n.directory);let s=`# Directory\t${ke(n)}\n`;if("unknown"!==t&&(s+=`# Project Type\t${Le(t)}\n`),n.comments){s+="Extension\tFiles\tLines\tCode Lines\tComment Lines\tBlank Lines\tSize",n.code_vs_comments&&(s+="\tCode vs Comments Ratio"),s+="\n";const t=ze(e);for(const o of t){const t=e.files_by_extension[o],i=e.lines_by_extension[o]||0,r=e.code_lines_by_extension?.[o]||0,l=e.comment_lines_by_extension?.[o]||0;s+=`${o}\t${t}\t${i}\t${r}\t${l}\t${e.blank_lines_by_extension?.[o]||0}\t${e.size_by_extension[o]||0}`,n.code_vs_comments&&r>0&&(s+=`\t${((l||0)/r).toFixed(2)}`),s+="\n"}}else{s+="Extension\tFiles\tLines\tSize\n";const n=ze(e);for(const t of n)s+=`${t}\t${e.files_by_extension[t]}\t${e.lines_by_extension[t]||0}\t${e.size_by_extension[t]||0}\n`}return s}(n,t);case"markdown":return function(e,n){const t=W(n.directory);let s="# LocIO Report\n\n";s+=`**Directory:** ${ke(n)}\n`,"unknown"!==t&&(s+=`**Project Type:** ${Le(t)}\n`),s+="\n",s+="## Summary\n\n",s+="| Metric | Value |\n",s+="|--------|-------|\n",s+=`| Total Files | ${e.total_files} |\n`,s+=`| Total Size | ${pe(e.total_size)} |\n`,!n.files_only&&(s+=`| Total Lines | ${e.total_lines} |\n`,n.comments&&void 0!==e.total_comment_lines&&(s+=`| Comment Lines | ${e.total_comment_lines} |\n`,void 0!==e.total_code_lines&&(s+=`| Code Lines | ${e.total_code_lines} |\n`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&(s+=`| Blank Lines | ${e.total_blank_lines} |\n`),n.code_vs_comments&&void 0!==e.total_code_lines&&e.total_code_lines>0))&&(s+=`| Code vs Comments Ratio | ${(e.total_comment_lines/e.total_code_lines).toFixed(2)}:1 |\n`);const o=ze(e);if(o.length>0){s+="\n## Statistics by Extension\n\n",s+="| Extension | Files |",n.lines_only||(s+=" Size |"),n.files_only||(s+=" Lines |",n.comments&&(s+=" Code | Comments |",n.code_vs_comments&&(s+=" Ratio |"))),s+="\n",s+="|----------|-------|",n.lines_only||(s+="------|"),n.files_only||(s+="-------|",n.comments&&(s+="------|-----------|",n.code_vs_comments&&(s+="-------|"))),s+="\n";for(const t of o){const o=e.files_by_extension[t],i=e.size_by_extension[t]||0,r=e.lines_by_extension[t]||0,l=e.code_lines_by_extension?.[t]||0,a=e.comment_lines_by_extension?.[t]||0;s+=`| \`${t}\` | ${o} |`,n.lines_only||(s+=` ${pe(i)} |`),!n.files_only&&(s+=` ${r} |`,n.comments)&&(s+=` ${l} | ${a} |`,n.code_vs_comments&&l>0?s+=` ${((a||0)/l).toFixed(2)}:1 |`:n.code_vs_comments&&(s+=" - |")),s+="\n"}}if(n.show_stats&&e.details&&e.details.length>0){s+="\n## Files by Directory\n\n";const t=$e(e.details),o=Object.keys(t).sort();for(const e of o){const o=t[e];s+=`### ${e}\n\n`,s+="| File | Extension | Size |",n.files_only||(s+=" Lines |",(n.comments||n.show_stats)&&(s+=" Code | Comments | Blank | Full-Line | Inline |")),s+="\n",s+="|------|-----------|------|",n.files_only||(s+="-------|",(n.comments||n.show_stats)&&(s+="------|----------|-------|----------|--------|")),s+="\n";for(const e of o)s+=`| ${e.name} | \`${e.extension}\` | ${pe(e.size)} |`,!n.files_only&&null!==e.lines&&(s+=` ${e.lines} |`,n.comments||n.show_stats)&&(s+=` ${e.code_lines||0} | ${e.comment_lines||0} | ${e.blank_lines||0} | ${e.full_line_comments||0} | ${e.inline_comments||0} |`),s+="\n";s+="\n"}}if(n.top_files&&n.top_files>0){const t=Se(e,n.top_files);s+=`\n## Top ${n.top_files} Largest Files\n\n`,s+="| Size | File | Extension |",n.files_only||(s+=" Lines |"),s+="\n",s+="|------|------|-----------|",n.files_only||(s+="-------|"),s+="\n";for(const e of t)s+=`| ${pe(e.size)} | ${e.name} | \`${e.extension}\` |`,n.files_only||null===e.lines||(s+=` ${e.lines} |`),s+="\n";s+="\n"}if(n.top_dirs&&n.top_dirs>0){const t=Ce(e,n.top_dirs);s+=`\n## Top ${n.top_dirs} Directories (by file count)\n\n`,s+="| Files | Directory | Size |",n.files_only||(s+=" Lines |"),s+="\n",s+="|-------|-----------|------|",n.files_only||(s+="-------|"),s+="\n";for(const e of t)s+=`| ${e.fileCount} | ${e.directory} | ${pe(e.totalSize)} |`,n.files_only||(s+=` ${e.totalLines} |`),s+="\n";s+="\n"}return s+="\n---\n\n",s+="*Generated by [LocIO](https://locio.js.org)*\n",s}(n,t);case"html":return function(e,n){const t=W(n.directory),o=ze(e),i=o.map(n=>({ext:n,files:e.files_by_extension?.[n]||0,lines:e.lines_by_extension?.[n]||0,size:e.size_by_extension?.[n]||0,codeLines:e.code_lines_by_extension?.[n]||0,commentLines:e.comment_lines_by_extension?.[n]||0,blankLines:e.blank_lines_by_extension?.[n]||0}));return`<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>LocIO Report - ${ke(n)}</title>\n <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"><\/script>\n <script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"><\/script>\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh;\n padding: 20px;\n }\n .container {\n max-width: 1200px;\n margin: 0 auto;\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n overflow: hidden;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 40px;\n text-align: center;\n }\n .header h1 {\n font-size: 2.5em;\n margin-bottom: 10px;\n }\n .header p {\n opacity: 0.9;\n font-size: 1.1em;\n }\n .content {\n padding: 40px;\n }\n .summary-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 20px;\n margin-bottom: 40px;\n }\n .card {\n background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n padding: 25px;\n border-radius: 10px;\n text-align: center;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n }\n .card h3 {\n color: #667eea;\n font-size: 0.9em;\n text-transform: uppercase;\n letter-spacing: 1px;\n margin-bottom: 10px;\n }\n .card .value {\n font-size: 2.5em;\n font-weight: bold;\n color: #2d3748;\n }\n .section {\n margin-bottom: 40px;\n }\n .section h2 {\n color: #2d3748;\n margin-bottom: 20px;\n padding-bottom: 10px;\n border-bottom: 3px solid #667eea;\n }\n .chart-container {\n position: relative;\n height: 400px;\n margin: 20px 0;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n margin-top: 20px;\n background: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n th {\n background: #667eea;\n color: white;\n padding: 15px;\n text-align: left;\n font-weight: 600;\n }\n td {\n padding: 12px 15px;\n border-bottom: 1px solid #e2e8f0;\n }\n tr:hover {\n background: #f7fafc;\n }\n .footer {\n text-align: center;\n padding: 20px;\n color: #718096;\n border-top: 1px solid #e2e8f0;\n }\n .footer a {\n color: #667eea;\n text-decoration: none;\n }\n #dependencyGraph {\n width: 100%;\n height: 600px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: #f7fafc;\n margin-top: 20px;\n }\n .graph-legend {\n margin-top: 15px;\n padding: 15px;\n background: #f7fafc;\n border-radius: 8px;\n border: 1px solid #e2e8f0;\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n }\n .legend-item {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .legend-color {\n width: 20px;\n height: 20px;\n border-radius: 4px;\n border: 2px solid #3e3e3e;\n }\n .legend-dir { background: #667eea; }\n .legend-file { background: #4ec9b0; }\n .legend-edge { background: #848484; }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="header">\n <h1>LocIO Report</h1>\n <p>Directory: ${ke(n)}</p>\n ${"unknown"!==t?`<p>Project Type: <strong>${Le(t)}</strong></p>`:""}\n </div>\n <div class="content">\n <div class="summary-cards">\n <div class="card">\n <h3>Total Files</h3>\n <div class="value">${e.total_files}</div>\n </div>\n <div class="card">\n <h3>Total Size</h3>\n <div class="value">${pe(e.total_size)}</div>\n </div>\n ${n.files_only?"":`<div class="card">\n <h3>Total Lines</h3>\n <div class="value">${e.total_lines}</div>\n </div>`}\n ${n.comments&&void 0!==e.total_comment_lines?`<div class="card">\n <h3>Comment Lines</h3>\n <div class="value">${e.total_comment_lines}</div>\n </div>\n <div class="card">\n <h3>Code Lines</h3>\n <div class="value">${e.total_code_lines||0}</div>\n </div>\n ${void 0!==e.total_blank_lines&&e.total_blank_lines>0?`<div class="card">\n <h3>Blank Lines</h3>\n <div class="value">${e.total_blank_lines}</div>\n </div>`:""}`:""}\n </div>\n\n ${o.length>0?`<div class="section">\n <h2>π Statistics by Extension</h2>\n <div class="chart-container">\n <canvas id="extensionChart"></canvas>\n </div>\n <table>\n <thead>\n <tr>\n <th>Extension</th>\n <th>Files</th>\n ${n.lines_only?"":"<th>Size</th>"}\n ${n.files_only?"":"<th>Lines</th>"}\n ${n.comments?"<th>Code</th><th>Comments</th><th>Blank</th>":""}\n </tr>\n </thead>\n <tbody>\n ${i.map(e=>`<tr>\n <td><strong>${e.ext}</strong></td>\n <td>${e.files}</td>\n ${n.lines_only?"":`<td>${pe(e.size)}</td>`}\n ${n.files_only?"":`<td>${e.lines}</td>`}\n ${n.comments?`<td>${e.codeLines}</td><td>${e.commentLines}</td><td>${e.blankLines}</td>`:""}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`:""}\n\n ${n.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?'<div class="section">\n <h2>π¬ Code vs Comments</h2>\n <div class="chart-container">\n <canvas id="commentChart"></canvas>\n </div>\n </div>':""}\n\n ${n.top_files&&n.top_files>0?(()=>{const t=Se(e,n.top_files);return`<div class="section">\n <h2>π Top ${n.top_files} Largest Files</h2>\n <table>\n <thead>\n <tr>\n <th>Size</th>\n <th>File</th>\n <th>Extension</th>\n ${n.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${t.map(e=>`<tr>\n <td><strong>${pe(e.size)}</strong></td>\n <td>${e.name}</td>\n <td><code>${e.extension}</code></td>\n ${n.files_only||null===e.lines?"":`<td>${e.lines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${n.top_dirs&&n.top_dirs>0?(()=>{const t=Ce(e,n.top_dirs);return`<div class="section">\n <h2>π Top ${n.top_dirs} Directories (by file count)</h2>\n <table>\n <thead>\n <tr>\n <th>Files</th>\n <th>Directory</th>\n <th>Size</th>\n ${n.files_only?"":"<th>Lines</th>"}\n </tr>\n </thead>\n <tbody>\n ${t.map(e=>`<tr>\n <td><strong>${e.fileCount}</strong></td>\n <td>${e.directory}</td>\n <td>${pe(e.totalSize)}</td>\n ${n.files_only?"":`<td>${e.totalLines}</td>`}\n </tr>`).join("")}\n </tbody>\n </table>\n </div>`})():""}\n\n ${"html"===n.export&&e.details&&e.details.length>0?(()=>{const t={},o=new Set,i=new Map,r=new Map;for(const n of e.details){const e=n.directory.replace(/\\/g,"/");t[e]||(t[e]={fileCount:0,totalSize:0,totalLines:0},i.set(e,n.directory)),t[e].fileCount+=1,t[e].totalSize+=n.size,null!==n.lines&&(t[e].totalLines+=n.lines);const l=e.split("/").filter(e=>e);for(let e=0;e<l.length;e++){const n=l.slice(0,e+1).join("/");o.add(n),i.has(n)||i.set(n,n)}const a=s.join(n.directory,n.name);r.set(a,e)}const l=[],a=[],c={};for(const e of o)c[e]=t[e]?{...t[e]}:{fileCount:0,totalSize:0,totalLines:0};const d=Array.from(o).sort((e,n)=>{const t=e.split("/").filter(e=>e).length;return n.split("/").filter(e=>e).length-t});for(const e of d){const n=""===e?"":e+"/";for(const t of d){if(t===e)continue;const s=t.split("/").filter(e=>e),o=e.split("/").filter(e=>e);if(s.length===o.length+1&&(""===e||t.startsWith(n))){const n=c[t];n&&(c[e].fileCount+=n.fileCount,c[e].totalSize+=n.totalSize,c[e].totalLines+=n.totalLines)}}}const u=new Map,m=new Map;let f=0;const p=Array.from(o).sort();for(const e of p){const t="dir_"+f++;u.set(e,t);const s=c[e]||{fileCount:0,totalSize:0,totalLines:0},o=e.split("/").pop()||e;l.push({id:t,label:o,group:0,title:`${e}\nFiles: ${s.fileCount}\nSize: ${pe(s.totalSize)}${n.files_only?"":`\nLines: ${s.totalLines}`}`,value:Math.max(s.fileCount,1)});const i=e.split("/").filter(e=>e);if(i.length>1){const e=i.slice(0,-1).join("/"),n=u.get(e);n&&a.push({from:n,to:t,arrows:"to",color:{color:"#667eea"},title:"contains"})}}const h=e.details.sort((e,n)=>n.size-e.size).slice(0,100);for(const e of h){const t=e.directory.replace(/\\/g,"/"),o=s.join(e.directory,e.name),i="file_"+f++;m.set(o,i),l.push({id:i,label:e.name,group:1,title:`${o}\nSize: ${pe(e.size)}${n.files_only||null===e.lines?"":`\nLines: ${e.lines}`}\nExtension: ${e.extension}`,value:Math.max(Math.floor(e.size/100),1)});const r=u.get(t);r&&a.push({from:r,to:i,arrows:"to",color:{color:"#848484"},title:"contains"})}const _=Object.entries(t),g=Math.max(..._.map(([,e])=>e.fileCount),1),y=Math.max(..._.map(([,e])=>e.totalSize),1);return`<div class="section">\n <h2>πΊοΈ Directory Structure Graph</h2>\n <div id="dependencyGraph"></div>\n <div class="graph-legend">\n <div class="legend-item">\n <span class="legend-color legend-dir"></span>\n <span>Directories</span>\n </div>\n <div class="legend-item">\n <span class="legend-color legend-file"></span>\n <span>Files</span>\n </div>\n <div class="legend-item">\n <span class="legend-color legend-edge"></span>\n <span>Contains</span>\n </div>\n </div>\n <script type="text/javascript">\n const nodes = new vis.DataSet(${JSON.stringify(l)});\n const edges = new vis.DataSet(${JSON.stringify(a)});\n\n const data = {\n nodes: nodes,\n edges: edges\n };\n\n const options = {\n nodes: {\n shape: 'dot',\n size: 16,\n font: {\n size: 14,\n color: '#2d3748'\n },\n borderWidth: 2,\n shadow: true\n },\n edges: {\n width: 2,\n shadow: true,\n smooth: {\n type: 'continuous',\n roundness: 0.5\n }\n },\n groups: {\n 0: {\n color: {\n background: '#667eea',\n border: '#4a5568',\n highlight: {\n border: '#4a5568',\n background: '#764ba2'\n }\n },\n shape: 'box',\n size: 25\n },\n 1: {\n color: {\n background: '#4ec9b0',\n border: '#2d3748',\n highlight: {\n border: '#2d3748',\n background: '#6ec9b0'\n }\n },\n shape: 'dot',\n size: 15\n }\n },\n physics: {\n enabled: true,\n stabilization: {\n enabled: true,\n iterations: 200\n },\n barnesHut: {\n gravitationalConstant: -2000,\n centralGravity: 0.1,\n springLength: 200,\n springConstant: 0.04,\n damping: 0.09\n }\n },\n interaction: {\n hover: true,\n tooltipDelay: 100,\n zoomView: true,\n dragView: true\n }\n };\n\n const container = document.getElementById('dependencyGraph');\n const network = new vis.Network(container, data, options);\n\n network.on('click', function(params) {\n if (params.nodes.length > 0) {\n const nodeId = params.nodes[0];\n const node = nodes.get(nodeId);\n if (node) {\n console.log('Selected:', node.title);\n }\n }\n });\n <\/script>\n </div>\n <div class="section">\n <h2>π Directory Heatmap</h2>\n <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; margin-top: 20px;">\n ${_.map(([e,t])=>{const s=(t.fileCount/g*100+t.totalSize/y*100)/2,o=240-1.2*s;return`<div style="\n background: linear-gradient(135deg, hsl(${o}, 70%, ${85-.3*s}%), hsl(${o}, 70%, ${75-.3*s}%));\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n color: ${s>50?"white":"#2d3748"};\n ">\n <div style="font-weight: bold; margin-bottom: 8px; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="${e}">${e.split("/").pop()||e}</div>\n <div style="font-size: 0.8em; opacity: 0.9;">\n <div>π ${t.fileCount} files</div>\n <div>πΎ ${pe(t.totalSize)}</div>\n ${n.files_only?"":`<div>π ${t.totalLines} lines</div>`}\n </div>\n </div>`}).join("")}\n </div>\n </div>`})():""}\n </div>\n <div class="footer">\n Generated by <a href="https://locio.js.org">LocIO</a>\n </div>\n </div>\n\n <script>\n ${o.length>0?`const extensionCtx = document.getElementById('extensionChart');\n new Chart(extensionCtx, {\n type: 'bar',\n data: {\n labels: ${JSON.stringify(o)},\n datasets: [\n ${n.files_only?"":`{\n label: 'Lines',\n data: ${JSON.stringify(o.map(n=>e.lines_by_extension[n]||0))},\n backgroundColor: 'rgba(102, 126, 234, 0.8)',\n borderColor: 'rgba(102, 126, 234, 1)',\n borderWidth: 2\n },`}\n {\n label: 'Files',\n data: ${JSON.stringify(o.map(n=>e.files_by_extension?.[n]||0))},\n backgroundColor: 'rgba(118, 75, 162, 0.8)',\n borderColor: 'rgba(118, 75, 162, 1)',\n borderWidth: 2\n }\n ]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'top',\n },\n title: {\n display: true,\n text: 'Files and Lines by Extension'\n }\n }\n }\n });`:""}\n\n ${n.comments&&void 0!==e.total_code_lines&&e.total_code_lines>0?`const commentCtx = document.getElementById('commentChart');\n new Chart(commentCtx, {\n type: 'doughnut',\n data: {\n labels: ['Code Lines', 'Comment Lines'],\n datasets: [{\n data: [${e.total_code_lines}, ${e.total_comment_lines||0}],\n backgroundColor: [\n 'rgba(102, 126, 234, 0.8)',\n 'rgba(118, 75, 162, 0.8)'\n ],\n borderColor: [\n 'rgba(102, 126, 234, 1)',\n 'rgba(118, 75, 162, 1)'\n ],\n borderWidth: 2\n }]\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: 'bottom',\n },\n title: {\n display: true,\n text: 'Code vs Comments Distribution'\n }\n }\n }\n });`:""}\n <\/script>\n</body>\n</html>`}(n,t)}}function je(e){const n=function(e){switch(e){case"human":return"txt";case"json":return"json";case"csv":return"csv";case"tsv":return"tsv";case"markdown":return"md";case"html":return"html"}}(e);return`LocIO-report.${n}`}function Fe(n,t){void 0===t.export?function(e,n){if(n.quiet)return void console.log(`${e.total_files} ${e.total_lines}`);const t=he(),s=Math.min(60,t-2),o="=".repeat(s),i=Math.floor(s/2)+6;if(console.log("\n"+_e.info(o)),console.log(_e.info.bold("LocIO RESULTS".padStart(i).padEnd(s))),console.log(_e.info(o)),console.log(`\n${l.green.bold("Directory:")} ${ke(n)}`),n.lines_only||(we(n)?console.log(`\n${l.green.bold("Size:")} ${l.white(pe(e.total_size))}`):(console.log(`\n${l.green.bold("Total Files:")} ${l.yellow(e.total_files)}`),console.log(`\n${l.green.bold("Total Files Size:")} ${l.white(pe(e.total_size))}`))),!n.files_only&&(console.log(`\n${l.green.bold("Total Lines:")} ${l.yellow(e.total_lines)}`),(n.comments||n.show_stats)&&void 0!==e.total_comment_lines&&(console.log(`\n${l.green.bold("Total Comment Lines:")} ${l.cyan(e.total_comment_lines)}`),void 0!==e.total_full_line_comments&&console.log(` ${l.gray("β")} ${l.green("Full Line Comments:")} ${l.cyan(e.total_full_line_comments)}`),void 0!==e.total_inline_comments&&console.log(` ${l.gray("β")} ${l.green("Inline Comments:")} ${l.cyan(e.total_inline_comments)}`),void 0!==e.total_code_lines&&console.log(`\n${l.green.bold("Total Code Lines:")} ${l.blue(e.total_code_lines)}`),void 0!==e.total_blank_lines&&e.total_blank_lines>0&&console.log(`\n${l.green.bold("Total Blank Lines:")} ${l.gray(e.total_blank_lines)}`),n.code_vs_comments&&void 0!==e.total_code_lines))){const n=e.total_code_lines>0?(e.total_comment_lines/e.total_code_lines).toFixed(2):"0.00";console.log(`\n${l.green.bold("Code vs Comments Ratio:")} ${l.magenta(n)}:1 ${l.gray(`(${e.total_comment_lines} comments per ${e.total_code_lines} code lines)`)}`)}const r=ze(e);if(r.length>0&&console.log(`\n${l.green.bold("Extensions:")} ${l.white(r.join(", "))}`),n.show_stats&&r.length>0){const t=he(),s=Math.min(60,t-2);console.log(`\n${_e.info.bold("Statistics by Extension:")}`),console.log(_e.muted("-".repeat(s)));for(const t of r){const s=e.files_by_extension[t],o=e.size_by_extension[t]||0,i=e.lines_by_extension[t]||0;let r=` ${l.white(t)}: ${l.yellow(s)} files`;if(n.lines_only||(r+=`, ${l.white(pe(o))}`),!n.files_only&&(r+=`, ${l.yellow(i)} lines`,be(n,void 0!==e.comment_lines_by_extension?.[t]))){const s=ge({comment_lines:e.comment_lines_by_extension?.[t]||0,code_lines:e.code_lines_by_extension?.[t]||0,full_line_comments:e.full_line_comments_by_extension?.[t]||0,inline_comments:e.inline_comments_by_extension?.[t]||0}),o=e.blank_lines_by_extension?.[t]||0;if(r+=xe(s.codeLines,s.commentLines,s.fullLineComments,s.inlineComments,o),n.code_vs_comments&&s.codeLines>0){const e=(s.commentLines/s.codeLines).toFixed(2);r+=` ${l.magenta(`[${e}:1]`)}`}}console.log(r)}}if(n.show_stats&&e.details&&e.details.length>0){console.log(`\n${l.cyan.bold("Files by Directory:")}`),console.log(l.gray("-".repeat(60)));const t=$e(e.details),s=Object.keys(t).sort();for(const e of s){const s=t[e];console.log(l.green.bold(`Directory: ${e}`));for(const e of s){const t=pe(e.size),s=null===e.lines||n.files_only?"":` | ${e.lines} lines`;let o="";if(be(n,void 0!==e.comment_lines&&null!==e.comment_lines)){const n=ge(e);o=xe(n.codeLines,n.commentLines,n.fullLineComments,n.inlineComments,e.blank_lines||void 0)}console.log(` - ${l.white(e.name)} (${l.blue(e.extension)}, ${l.white(t)}${s}${o})`)}console.log()}}if(n.top_files&&n.top_files>0){const t=Se(e,n.top_files);console.log(`\n${l.cyan.bold(`Top ${n.top_files} Largest Files:`)}`),console.log(l.gray("-".repeat(60)));for(const e of t){const{sizeStr:t,linesStr:s}=ve(e.size,e.lines,n);console.log(` ${l.yellow(t.padEnd(10))} ${l.white(e.name)} ${l.blue(`(${e.extension})`)}${s}`)}}if(n.top_dirs&&n.top_dirs>0){const t=Ce(e,n.top_dirs);console.log(`\n${l.cyan.bold(`Top ${n.top_dirs} Directories (by file count):`)}`),console.log(l.gray("-".repeat(60)));for(const e of t){const t=pe(e.totalSize),s=n.files_only?"":` | ${e.totalLines} lines`;console.log(` ${l.yellow(e.fileCount.toString().padEnd(5))} files ${l.white(e.directory)} ${l.gray(`(${t}${s})`)}`)}}console.log()}(n,t):function(n,t){const o=Array.isArray(t.export)?t.export:[t.export||"human"];for(let i=0;i<o.length;i++){const r=o[i],l=Ee(r,n,t),a=je(r);let c=a;try{let n;if(t.export_path)try{const e=se(t.export_path,t.directory);n=e,c=s.join(e,a)}catch(e){const n=e instanceof Error?e:new Error(String(e));console.error(`\nβ Invalid export path: ${t.export_path}`),console.error(`π Error: ${n.message}`);continue}else n=s.join(t.directory,"reports"),c=s.join(n,a);n&&"."!==n&&n!==a&&e.mkdirSync(n,{recursive:!0}),e.writeFileSync(c,l,"utf-8"),t.quiet||console.log(`Report written to ${c}`)}catch(e){const n=(e instanceof Error?e:new Error(String(e))).message||String(e);let t="";t=n.includes("ENOENT")?`The directory for "${a}" does not exist.\n - Ensure the parent directory exists\n - Check if the path is correct`:n.includes("EACCES")||n.includes("permission")?`Permission denied when writing to "${a}".\n - Check write permissions for the directory\n - Try running with appropriate permissions\n - Use a different output directory`:n.includes("ENOSPC")?"Insufficient disk space.\n - Free up disk space\n - Choose a different location":"Check if the path is valid and you have write permissions.",console.error(`\nβ Failed to create report file ${c||a}`),console.error(`π Error: ${n}`),t&&console.error(`\nπ‘ Suggestion:\n${t}`)}}}(n,t)}var Me=new Set(["exe","dll","so","dylib","bin","o","a","lib","jpg","jpeg","png","gif","bmp","ico","svg","pdf","zip","tar","gz","bz2","xz","7z","rar","mp3","mp4","avi","mov","wmv","flv","woff","woff2","ttf","otf","eot"]);function De(e){const n=e.trim().toUpperCase();let t,s;n.endsWith("KB")?(t=n.slice(0,-2),s=1024):n.endsWith("MB")?(t=n.slice(0,-2),s=1048576):n.endsWith("GB")?(t=n.slice(0,-2),s=1073741824):n.endsWith("B")&&n.length>1?(t=n.slice(0,-1),s=1):(t=n,s=1);const o=parseFloat(t);return isNaN(o)?C.invalidSizeFormat(e):Math.floor(o*s)}function Te(n,t){const o=s.extname(n).replace(/^\./,"").toLowerCase();if(Me.has(o))return!0;try{const t=q,s=Buffer.alloc(t),o=e.openSync(n,"r"),i=e.readSync(o,s,0,t,0);if(e.closeSync(o),0===i)return!1;for(let e=0;e<i;e++)if(0===s[e])return!0;return!1}catch{return!1}}var Ue=G,Oe=J;function Pe(n,t){try{if(!oe(n,H))return C.io(`File too large to process: exceeds maximum safe size (${H/1048576}MB)`,void 0,n);const t=e.statSync(n);if(t.size<Ue){return Re(e.readFileSync(n,"utf-8"))}if(t.size>=Oe)try{return Re(e.readFileSync(n,"utf-8"))}catch(e){return C.io(`Failed to read large file: ${n}`,e instanceof Error?e:void 0)}return Re(e.readFileSync(n,"utf-8"))}catch(e){return C.io(`Failed to read file: ${n}`,e instanceof Error?e:void 0)}}function Re(e){if(e.length>H)throw new Error(`Content too large: exceeds maximum safe size (${H/1048576}MB)`);return e.split(/\r?\n/).length}function Ie(e){if(e.length>H)throw new Error(`Content too large: exceeds maximum safe size (${H/1048576}MB)`);const n=e.split(/\r?\n/);let t=0,s=0;for(const e of n)0===e.trim().length?t++:s++;return{total:n.length,blank:t,code:s}}function Be(n,t){try{if(!oe(n,H))return C.io(`File too large to process: exceeds maximum safe size (${H/1048576}MB)`,void 0,n);if(e.statSync(n).size<Ue){return Ie(e.readFileSync(n,"utf-8"))}return Ie(e.readFileSync(n,"utf-8"))}catch(e){return C.io(`Failed to read file: ${n}`,e instanceof Error?e:void 0)}}var Ne=["jpg","jpeg","png","gif","bmp","svg","ico","webp","tiff","tif","psd","raw","heic","heif","avif","mp3","wav","flac","aac","ogg","wma","m4a","opus","aiff","au","mp4","avi","mkv","mov","wmv","flv","webm","m4v","mpg","mpeg","3gp","ogv","zip","rar","7z","tar","gz","bz2","xz","z","cab","iso","dmg","pkg","deb","rpm","pdf","doc","docx","xls","xlsx","ppt","pptx","odt","ods","odp","exe","dll","so","dylib","app","msi","bin","run","ttf","otf","woff","woff2","eot","db","sqlite","sqlite3","mdb","accdb","ps","eps","ai","sketch","fig","xd"],Ae=["md","markdown","txt","rst","adoc","asciidoc","org","wiki","json","yaml","yml","toml","ini","cfg","conf","config","properties","env","dotenv","csv","tsv","xml","html","htm","xhtml","log","lock","lockfile"];function We(e){try{if(e.max_size){const n=De(e.max_size);if(n instanceof C)return n}if(e.min_size){const n=De(e.min_size);if(n instanceof C)return n}const n=W(e.directory),t=O[n]||O.unknown,s=e.exclude_patterns.map(n=>{try{return new RegExp(n,e.ignore_case?"i":void 0)}catch(e){throw C.invalidRegex(n,e instanceof Error?e:void 0)}}),o=[...e.exclude_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),...t.exclude_extensions.map(e=>e.toLowerCase()),...Ne.map(e=>e.toLowerCase())],i=Array.from(new Set(o)).sort(),r=new Set(i),l=e.include_extensions.map(e=>e.replace(/^\./,"").toLowerCase()),a=new Set(l),c=[...e.exclude_dirs,...t.exclude_dirs].map(n=>new RegExp(n,e.ignore_case?"i":void 0)),d=e.include_dirs.map(n=>new RegExp(n,e.ignore_case?"i":void 0)),u=[...e.exclude_names,...t.exclude_names].map(n=>new RegExp(n,e.ignore_case?"i":void 0)),m=e.include_names.map(n=>new RegExp(n,e.ignore_case?"i":void 0)),f=s.length>0?new RegExp(s.map(e=>`(?:${e.source})`).join("|"),e.ignore_case?"i":void 0):null,p=c.length>0?new RegExp(c.map(e=>`(?:${e.source})`).join("|"),e.ignore_case?"i":void 0):null,h=u.length>0?new RegExp(u.map(e=>`(?:${e.source})`).join("|"),e.ignore_case?"i":void 0):null;return{exclude_patterns:s,exclude_extensions:i,include_extensions:l,exclude_dirs:c,include_dirs:d,exclude_names:u,include_names:m,detected_project_type:n,exclude_extensions_set:r,include_extensions_set:a,combined_exclude_patterns:f,combined_exclude_dirs:p,combined_exclude_names:h}}catch(e){return e instanceof C?e:C.io(`Failed to create filter patterns: ${e instanceof Error?e.message:String(e)}`)}}var qe=new Map([[".ts","ts"],[".js","js"],[".tsx","tsx"],[".jsx","jsx"],[".json","json"],[".md","md"],[".css","css"],[".html","html"],[".xml","xml"],[".yaml","yaml"],[".yml","yml"],[".py","py"],[".java","java"],[".cpp","cpp"],[".c","c"],[".h","h"],[".hpp","hpp"],[".cs","cs"],[".php","php"],[".rb","rb"],[".go","go"],[".rs","rs"],[".swift","swift"],[".kt","kt"],[".scala","scala"],[".sh","sh"],[".bash","bash"],[".zsh","zsh"],[".fish","fish"],[".ps1","ps1"],[".bat","bat"],[".cmd","cmd"]]),Ge=new class{cache=new Map;normalize(e){if(this.cache.has(e))return this.cache.get(e);const n=s.extname(e).toLowerCase(),t=qe.get(n);if(t)return this.cache.set(e,t),t;const o=n.replace(/^\./,"")||"no-ext";return this.cache.set(e,o),o}normalizeFast(e){const n=s.extname(e).toLowerCase(),t=qe.get(n);return t||this.normalize(e)}clear(){this.cache.clear()}};function Je(e){return Ge.normalize(e)}function Ve(e){const n=null!==e.commentLines,t=null!==e.codeLines&&null!==e.blankLines;return n||t?{totalLines:e.lines||0,commentLines:e.commentLines||0,codeLines:e.codeLines||0,fullLineComments:e.fullLineComments||0,inlineComments:e.inlineComments||0,blankLines:e.blankLines||0}:null}function He(e,n,t,s,o){if(e.total_files+=1,e.total_size+=t,e.files_by_extension[n]=(e.files_by_extension[n]||0)+1,e.size_by_extension[n]=(e.size_by_extension[n]||0)+t,null!==s&&(e.total_lines+=s,e.lines_by_extension[n]=(e.lines_by_extension[n]||0)+s),o){const t=o.codeLines+o.commentLines+o.blankLines;o.totalLines!==t&&(o.totalLines=t),e.total_comment_lines=(e.total_comment_lines||0)+o.commentLines,e.total_code_lines=(e.total_code_lines||0)+o.codeLines,e.total_blank_lines=(e.total_blank_lines||0)+o.blankLines,e.total_full_line_comments=(e.total_full_line_comments||0)+o.fullLineComments,e.total_inline_comments=(e.total_inline_comments||0)+o.inlineComments,e.comment_lines_by_extension[n]=(e.comment_lines_by_extension[n]||0)+o.commentLines,e.code_lines_by_extension[n]=(e.code_lines_by_extension[n]||0)+o.codeLines,e.blank_lines_by_extension||(e.blank_lines_by_extension={}),e.blank_lines_by_extension[n]=(e.blank_lines_by_extension[n]||0)+o.blankLines,e.full_line_comments_by_extension[n]=(e.full_line_comments_by_extension[n]||0)+o.fullLineComments,e.inline_comments_by_extension[n]=(e.inline_comments_by_extension[n]||0)+o.inlineComments}}function Ke(e,n){if(!n.comments&&!n.code_vs_comments){const n=Pe(e);return z(n)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:n}:{lines:n,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}const t=Je(e),s=Ae.map(e=>e.toLowerCase()).includes(t);if(n.comments||n.code_vs_comments){if(!s)try{const n=de(e);if(n)return{lines:n.totalLines,commentLines:n.commentLines,codeLines:n.codeLines,fullLineComments:n.fullLineComments,inlineComments:n.inlineComments,blankLines:n.blankLines,error:null}}catch(n){const t=Be(e);return z(t)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:t}:{lines:t.total,commentLines:0,codeLines:t.code,fullLineComments:0,inlineComments:0,blankLines:t.blank,error:n instanceof Error?C.commentParsingError(e,n.message,n):null}}const n=Be(e);return z(n)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:n}:{lines:n.total,commentLines:0,codeLines:n.code,fullLineComments:0,inlineComments:0,blankLines:n.blank,error:null}}const o=Pe(e);return z(o)?{lines:null,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:o}:{lines:o,commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}function Qe(e,n,t,o,i,r,l,a,c){return{directory:s.dirname(e),name:s.basename(e),extension:t,size:n,lines:o,comment_lines:i,code_lines:r,blank_lines:c,full_line_comments:l,inline_comments:a}}var Ye=class{progressBar;updateQueue=[];lastUpdate=0;throttleMs=100;pendingUpdate=null;constructor(e){this.progressBar=e}update(e,n,t){this.updateQueue.push({files:e,errors:n,currentFile:t}),this.scheduleUpdate()}scheduleUpdate(){if(this.pendingUpdate)return;const e=Date.now()-this.lastUpdate;if(e>=this.throttleMs)this.flushUpdate();else{const n=this.throttleMs-e;this.pendingUpdate=setTimeout(()=>{this.flushUpdate()},n)}}flushUpdate(){if(0===this.updateQueue.length)return void(this.pendingUpdate=null);const e=this.updateQueue[this.updateQueue.length-1];this.progressBar.update(e.files,e.errors,e.currentFile),this.updateQueue=[],this.lastUpdate=Date.now(),this.pendingUpdate=null}finish(){this.pendingUpdate&&(clearTimeout(this.pendingUpdate),this.pendingUpdate=null),this.flushUpdate(),this.progressBar.finish()}},Ze=class{total;current=0;startTime;width=40;errors=0;currentFile="";lastUpdateTime;filesPerSecond=0;constructor(e){this.total=e,this.startTime=Date.now(),this.lastUpdateTime=this.startTime}update(e,n=0,t){this.current=e,this.errors=n,t&&(this.currentFile=t);const s=Date.now(),o=s-this.lastUpdateTime;if(o>0){const n=e-(this.current-1);this.filesPerSecond=n/o*1e3}this.lastUpdateTime=s,this.render()}increment(e=0){this.current++,e>0&&(this.errors=e),this.render()}formatTime(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;return`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3)}s`}calculateETA(){if(0===this.current)return"calculating...";const e=Date.now()-this.startTime,n=this.current/e,t=(this.total-this.current)/n;return t<0||!isFinite(t)?"calculating...":this.formatTime(t)}formatSpeed(){return 0!==this.filesPerSecond&&isFinite(this.filesPerSecond)?this.filesPerSecond>=1e3?`${(this.filesPerSecond/1e3).toFixed(1)}k files/s`:`${Math.round(this.filesPerSecond)} files/s`:"calculating..."}formatCurrentFile(){if(!this.currentFile)return"";return this.currentFile.length>40?" | "+("..."+this.currentFile.slice(-37)):` | ${this.currentFile}`}render(){const e=this.total>0?this.current/this.total*100:0,n=e.toFixed(1).padStart(5),t=String(this.current).padStart(String(this.total).length),s=this.errors>0?l.red(` (${this.errors} errors)`):"",o=Date.now()-this.startTime,i=this.formatTime(o),r=this.calculateETA(),a=this.formatSpeed(),c=this.formatCurrentFile();if(!process.stderr.isTTY){if(this.current%100==0||this.current===this.total){const e=this.currentFile?` | Current: ${this.currentFile}`:"";process.stderr.write(`\rProcessed: ${t}/${this.total} (${n}%) | ${i} elapsed | ETA: ${r} | ${a}${e}${s}`)}return}const d=process.stderr.columns||80;this.width=Math.min(40,Math.max(20,Math.floor(d/4)));const u=Math.round(e/100*this.width),m=this.width-u,f=`\r${l.green("β".repeat(u))+l.gray("β".repeat(m))} ${n}% | ${t}/${this.total} files | ${i} elapsed | ETA: ${r} | ${l.cyan(a)}${c}${s}`;process.stderr.write("[K"+f)}finish(){const e=Date.now()-this.startTime,n=this.formatTime(e),t=this.errors>0?l.red(` (${this.errors} errors)`):"";if(process.stderr.isTTY){const e=100,s=l.green("β".repeat(this.width)),o=String(this.current).padStart(String(this.total).length);process.stderr.write(`\r${s} ${e.toFixed(1).padStart(5)}% | ${o}/${this.total} files | ${n}${t}\n`)}else process.stderr.write(`\rProcessed: ${this.current}/${this.total} files in ${n}${t}\n`)}};var Xe=class{cache=new Map;get(n){if(this.cache.has(n))return this.cache.get(n);try{const t=e.statSync(n);return this.cache.set(n,t),t}catch{return null}}async getAsync(n){if(this.cache.has(n))return this.cache.get(n);try{const t=await e.promises.stat(n);return this.cache.set(n,t),t}catch{return null}}clear(){this.cache.clear()}},en=class{cache=new Map;maxCacheSize=V;async get(n){if(this.cache.has(n))return this.cache.get(n);try{const t=await e.promises.stat(n),s={content:await e.promises.readFile(n,"utf-8"),stats:t};if(this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;void 0!==e&&this.cache.delete(e)}return this.cache.set(n,s),s}catch{return null}}clear(){this.cache.clear()}},nn=new class{cache=new Map;getGitignorePaths(n,t){const o=[];return function n(t,i){const r=s.join(t,".gitignore");try{if(e.existsSync(r)&&e.statSync(r).isFile()){const n=e.statSync(r);o.push({path:r,mtime:n.mtimeMs})}}catch{}try{const o=e.readdirSync(t);for(const i of o){const o=s.join(t,i);try{e.statSync(o).isDirectory()&&".git"!==i&&n(o)}catch{}}}catch{}}(n),o}isCacheValid(e,n){const t=this.getGitignorePaths(e,e);if(t.length!==n.gitignorePaths.length)return!1;for(const e of t){const t=n.gitignorePaths.find(n=>n.path===e.path);if(!t)return!1;if(e.mtime!==t.mtime)return!1}return!0}buildIgnoreInstance(n){const t=this.cache.get(n);if(t&&this.isCacheValid(n,t))return t.instance;const o=m();o.add(".git"),o.add(".gitignore"),o.add(".lcignore");const i=[];return function n(t,r){const l=s.join(t,".gitignore");try{if(e.existsSync(l)&&e.statSync(l).isFile()){const n=e.statSync(l);i.push({path:l,mtime:n.mtimeMs});!function(e,n,t){const i=s.relative(n,e)||".",r="."===i?"":i.replace(/\\/g,"/")+"/",l=t.split("\n");for(const e of l){const n=e.trim();if(!n||n.startsWith("#"))continue;const t=n.replace(/\\/g,"/");if("."===i)o.add(t);else if(t.startsWith("!")){const e=t.slice(1);e.startsWith("/")?o.add("!"+(r+e.slice(1)).replace(/\/+/g,"/")):o.add("!"+(r+e).replace(/\/+/g,"/"))}else if(t.startsWith("/")){const e=t.slice(1);o.add((r+e).replace(/\/+/g,"/"))}else if(t.includes("**"))o.add(t),r&&o.add((r+t).replace(/\/+/g,"/"));else{const e=(r+t).replace(/\/+/g,"/");o.add(e)}}}(t,r,e.readFileSync(l,"utf-8"))}}catch{}try{const o=e.readdirSync(t);for(const i of o){const o=s.join(t,i);try{e.statSync(o).isDirectory()&&".git"!==i&&n(o,r)}catch{}}}catch{}}(n,n),this.cache.set(n,{instance:o,gitignorePaths:i}),o}clearCache(){this.cache.clear()}};function tn(n,t,o,i,r,l=!1){if(!l&&void 0!==t.max_depth&&function(e,n,t){return s.relative(n,e).split(s.sep).length-1>t}(n,i,t.max_depth))return{shouldSkip:!0};if(!te(n,i))return{shouldSkip:!0};const a=r.get(n);if(!a||!a.isFile())return{shouldSkip:!0};if(ie(n,H))return{shouldSkip:!0};const c=a.size,d=Je(n);if(l){if(t.no_empty&&0===c)return{shouldSkip:!0};if(t.no_binary&&Te(n))return{shouldSkip:!0};const e=d.toLowerCase().replace(/^\./,"");if(o.exclude_extensions.length>0&&o.exclude_extensions.includes(e))return{shouldSkip:!0};if(o.include_extensions.length>0&&!o.include_extensions.includes(e))return{shouldSkip:!0};if(t.max_size){const e=De(t.max_size);if(!(e instanceof C)&&c>e)return{shouldSkip:!0}}if(t.min_size){const e=De(t.min_size);if(!(e instanceof C)&&c<e)return{shouldSkip:!0}}for(const e of o.exclude_patterns)if(e.test(n))return{shouldSkip:!0};const i=s.basename(n);for(const e of o.exclude_names)if(e.test(i))return{shouldSkip:!0};if(o.include_names.length>0){let e=!1;for(const n of o.include_names)if(n.test(i)){e=!0;break}if(!e)return{shouldSkip:!0}}if(t.no_hidden&&i.startsWith("."))return{shouldSkip:!0}}else if(function(n,t,o){const i=n,r=s.basename(n);if(o.combined_exclude_patterns){if(o.combined_exclude_patterns.test(i))return!0}else for(const e of o.exclude_patterns)if(e.test(i))return!0;const l=s.extname(n).replace(/^\./,"").toLowerCase();if(l){if(o.exclude_extensions_set){if(o.exclude_extensions_set.has(l))return!0}else for(const e of o.exclude_extensions)if(l===e.toLowerCase())return!0;if(o.include_extensions_set&&o.include_extensions_set.size>0){if(!o.include_extensions_set.has(l))return!0}else if(o.include_extensions.length>0){let e=!1;for(const n of o.include_extensions)if(l===n.toLowerCase()){e=!0;break}if(!e)return!0}}else if(o.include_extensions_set&&o.include_extensions_set.size>0||o.include_extensions.length>0)return!0;const a=s.dirname(n);if(o.combined_exclude_dirs){if(o.combined_exclude_dirs.test(a))return!0}else for(const e of o.exclude_dirs)if(e.test(a))return!0;if(o.include_dirs.length>0){let e=!1;for(const n of o.include_dirs)if(n.test(a)){e=!0;break}if(!e)return!0}if(o.combined_exclude_names){if(o.combined_exclude_names.test(r))return!0}else for(const e of o.exclude_names)if(e.test(r))return!0;if(o.include_names.length>0){let e=!1;for(const n of o.include_names)if(n.test(r)){e=!0;break}if(!e)return!0}if(t.no_hidden&&r.startsWith("."))return!0;try{const s=e.statSync(n).size;if(t.max_size){const e=De(t.max_size);if(!(e instanceof C)&&s>e)return!0}if(t.min_size){const e=De(t.min_size);if(!(e instanceof C)&&s<e)return!0}if(t.no_empty&&0===s)return!0}catch{}return!(!t.no_binary||!Te(n))}(n,t,o))return{shouldSkip:!0};return{shouldSkip:!1,stats:a,size:c,ext:d}}async function sn(e,n,t,s,o,i,r){try{return await on(e,n,t,s,o,i,r)}catch(n){return n instanceof Error&&(n instanceof C||C.fileProcessingError(e,n.message,n)),{processed:0,errors:1}}}async function on(e,n,t,o,i,r,l){let a=0,c=0;const d=tn(e,n,o,i,r,!0);if(d.shouldSkip)return{processed:a,errors:c};const{stats:u,size:m,ext:f}=d;if(!u||void 0===m||void 0===f)return{processed:a,errors:c};if(n.rm_comments){const t=f.toLowerCase().replace(/^\./,"");if(Ae.map(e=>e.toLowerCase()).includes(t))return{processed:a,errors:c};if((()=>{if(!0===n.rm_comments)return!0;if("string"==typeof n.rm_comments){const e=j(n.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return e.includes(t)||e.includes(`.${t}`)}return!1})()){const t=ue(e);if(t.success){if(t.commentsFound){if(!n.quiet){const n=s.relative(i,e);console.log(`β Removed comments from ${n}`)}a+=1}}else{if(!n.quiet){const n=s.relative(i,e);console.error(`β Failed to remove comments from ${n}`)}c+=1}}return{processed:a,errors:c}}a+=1;let p=null,h=null,_=null,g=null,y=null,x=null,b=null;if(!n.files_only){const t=await l.get(e);let s;if(s=t?await async function(e,n,t){if(!n.comments&&!n.code_vs_comments)return{lines:Re(t),commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null};const s=Je(e),o=Ae.map(e=>e.toLowerCase()).includes(s);if(n.comments||n.code_vs_comments){if(!o)try{const n=de(e,t);if(n)return{lines:n.totalLines,commentLines:n.commentLines,codeLines:n.codeLines,fullLineComments:n.fullLineComments,inlineComments:n.inlineComments,blankLines:n.blankLines,error:null}}catch(n){const s=Ie(t);return{lines:s.total,commentLines:0,codeLines:s.code,fullLineComments:0,inlineComments:0,blankLines:s.blank,error:n instanceof Error?C.commentParsingError(e,n.message,n):null}}const n=Ie(t);return{lines:n.total,commentLines:0,codeLines:n.code,fullLineComments:0,inlineComments:0,blankLines:n.blank,error:null}}return{lines:Re(t),commentLines:null,codeLines:null,fullLineComments:null,inlineComments:null,blankLines:null,error:null}}(e,n,t.content):Ke(e,n),s.error){if("COMMENT_PARSING_ERROR"!==s.error.code||null===s.lines)return n.quiet||console.error(`Warning: Could not count lines in ${e}: ${s.error.message}`),c+=1,{processed:a,errors:c};n.quiet,p=s.lines,h=null,_=null,g=null,y=null,x=null,b=null}else p=s.lines,h=s.commentLines,_=s.codeLines,g=s.fullLineComments,y=s.inlineComments,x=s.blankLines,b=Ve(s)}He(t,f,m,p,b);return!1!==n.collect_details&&(!n.max_details||t.details.length<n.max_details)&&t.details.push(Qe(e,m,f,p,h,_,g,y,x)),{processed:a,errors:c}}function rn(e,n,t,s){if(e.show_progress&&!e.quiet){const e=`${Date.now()-n}ms`;process.stderr.write(`\rProcessed: ${t} files (${s} errors) in ${e}\n`)}}function ln(e){return!1}async function an(n){const t=Date.now(),o={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},i=We(n);if(z(i))return i;const r=s.resolve(n.directory),l=s.dirname(r);if(!te(r,l))return C.io("Path traversal detected: file path is not safe",void 0,r);try{if(!e.statSync(r).isFile())return C.notADirectory(r);if(ie(r,H))return C.io(`File too large: exceeds maximum safe size (${H/1048576}MB)`,void 0,r)}catch(e){return C.fileNotFound(r)}const a=new Xe,c=new en;a.get(r);const{processed:d,errors:u}=await on(r,n,o,i,l,a,c);if(rn(n,t,d,u),0===d&&0===o.total_files){if(!tn(r,n,i,l,a,!0).shouldSkip)try{const t=e.statSync(r);if(t.isFile()){const e=Je(r),s=t.size;if(n.files_only)He(o,e,s,null,null),!1!==n.collect_details&&o.details.push(Qe(r,s,e,null,null,null,null,null,null));else{const t=Ke(r,n);if(!t.error){const i=Ve(t);He(o,e,s,t.lines,i),!1!==n.collect_details&&o.details.push(Qe(r,s,e,t.lines,t.commentLines,t.codeLines,t.fullLineComments,t.inlineComments,t.blankLines))}}}}catch(e){}}return n.rm_comments?{...o,_commentsRemoved:d}:o}async function cn(e){const n=Date.now(),{MemoryTracker:o}=await Promise.resolve().then(()=>(k(),x)),i=new o;i.checkpoint();const r={total_files:0,total_lines:0,total_size:0,total_comment_lines:0,total_code_lines:0,total_blank_lines:0,total_full_line_comments:0,total_inline_comments:0,files_by_extension:{},lines_by_extension:{},comment_lines_by_extension:{},code_lines_by_extension:{},blank_lines_by_extension:{},full_line_comments_by_extension:{},inline_comments_by_extension:{},size_by_extension:{},details:[]},l=We(e);if(z(l))return l;const a=(c=e.directory,nn.buildIgnoreInstance(c));var c;const d=new Xe,m=new en,f=ee,p={cwd:e.directory,absolute:!0,onlyFiles:!0,ignore:[],dot:!e.no_hidden,followSymbolicLinks:e.follow_links};let h=0,_=0,g=null,y=null,b=0;try{const n=function(e){return e.map(e=>"string"==typeof e?e:String("object"==typeof e&&null!==e&&"path"in e?e.path:e))}(await u(f,p));e.show_progress&&!e.quiet&&(g=new Ze(n.length),y=new Ye(g));const o=function(e,n,t,o,i,r){const l=[];for(const a of e){const e=s.relative(o,a);if(r.ignores(e))continue;const c=tn(a,n,t,o,i);if(c.shouldSkip)continue;const{stats:d,ext:u}=c;if(d&&void 0!==u&&(!(t.include_extensions.length>0)||t.include_extensions.includes(u))){if(n.max_size){const e=De(n.max_size);if(!(e instanceof C)&&d.size>e)continue}if(n.min_size){const e=De(n.min_size);if(!(e instanceof C)&&d.size<e)continue}n.no_empty&&0===d.size||l.push(a)}}return l}(n,e,l,e.directory,d,a),c=function(e,n){const t=[];for(let s=0;s<e.length;s+=n)t.push(e.slice(s,s+n));return t}(o,Math.min(t.cpus().length,K));for(const n of c){const t=await Promise.allSettled(n.map(n=>sn(n,e,r,l,e.directory,d,m)));i.checkpoint();for(let i=0;i<t.length;i++){const r=t[i],l=n[i];b++;const a=s.relative(e.directory,l);if(y?y.update(b,_,a):g&&(b%Q!==0&&b!==o.length||g.update(b,_,a)),"fulfilled"===r.status){const e=r.value;h+=e.processed,_+=e.errors}else _++,!e.quiet&&ln()&&console.error(`Failed to process ${l}: ${r.reason}`)}}if(e.rm_comments){const n=function(e,n,t){let o=0,i=0;for(const r of e){const e=Je(r).toLowerCase().replace(/^\./,"");if(!Ae.map(e=>e.toLowerCase()).includes(e)&&(()=>{if(!0===n.rm_comments)return!0;if("string"==typeof n.rm_comments){const t=j(n.rm_comments).map(e=>e.toLowerCase().replace(/^\./,""));return t.includes(e)||t.includes(`.${e}`)}return!1})()){const e=ue(r);if(e.success){if(e.commentsFound){if(!n.quiet){const e=s.relative(t,r);console.log(`β Removed comments from ${e}`)}o+=1}}else{if(!n.quiet){const e=s.relative(t,r);console.error(`β Failed to remove comments from ${e}`)}i+=1}}}return{processed:o,errors:i}}(o,e,e.directory);h+=n.processed,_+=n.errors}y?y.finish():g&&g.finish(),d.clear(),m.clear(),Ge.clear(),nn.clearCache()}catch(n){return y?y.finish():g&&g.finish(),C.io(`Failed to scan directory: ${n instanceof Error?n.message:String(n)}`,n instanceof Error?n:void 0,e.directory)}i.checkpoint();const v=i.getMetrics();return r._memoryMetrics=v,rn(e,n,h,_),e.rm_comments?{...r,_commentsRemoved:h}:r}var dn=class{quiet;verboseMode;constructor(e){this.quiet=e.quiet||!1,this.verboseMode=!1}info(e){this.quiet||console.log(e)}success(e){this.quiet||console.log(l.green(e))}warn(e){this.quiet||console.warn(l.yellow(e))}error(e){console.error(l.red(e))}debug(e){this.verboseMode&&!this.quiet&&console.log(l.gray(`[DEBUG] ${e}`))}verbose(e){this.verboseMode&&!this.quiet&&console.log(l.gray(e))}};function un(e){return new dn(e)}k();var mn=null,fn=!1,pn=null,hn=new Set,_n=null,gn=class{cache=new Map;getFileHash(n){try{const t=e.readFileSync(n,"utf-8");return f.createHash("sha256").update(t).digest("hex")}catch{return""}}isFileChanged(n){try{const t=e.statSync(n),s=this.cache.get(n);if(!s)return!0;if(t.mtimeMs!==s.mtime)return!0;return this.getFileHash(n)!==s.hash}catch{return!0}}updateFile(n){try{const t=e.statSync(n),s=this.getFileHash(n);this.cache.set(n,{path:n,hash:s,mtime:t.mtimeMs})}catch{}}removeFile(e){this.cache.delete(e)}clear(){this.cache.clear()}},yn=null;async function xn(n,t=!1,s){const o=M(n.directory);if(o.error)return o.error;const i=o.path;if(!e.statSync(i).isDirectory())return C.notADirectory(n.directory);if(n.directory=i,yn||(yn=new gn),t&&hn.size>0){const e=Array.from(hn).slice(0,10);s.info(l.cyan("π Changed files: "+(hn.size>10?`${hn.size} files`:e.length+" file(s)"))),e.length>0&&(e.forEach(e=>{s.verbose(` ${l.gray("β’")} ${e}`)}),hn.size>10&&s.verbose(l.gray(` ... and ${hn.size-10} more`))),s.info("")}const r=await cn(n);if(z(r))return r;hn.clear(),Fe(r,n)}function bn(e){return void 0!==e.watch_debounce?Math.max(Z,Math.min(X,e.watch_debounce)):Y}async function vn(n){const t=un(n),o=M(n.directory);o.error&&(t.error(`Error: ${o.error.message}`),process.exit(1));const i=o.path;e.statSync(i).isDirectory()||(t.error(`Error: Not a directory: ${n.directory}`),process.exit(1)),function(e){try{const n=s.resolve(e);for(const e of ne){const t=s.resolve(e);if(n===t||n.startsWith(t+s.sep))return!1}return n!==s.parse(n).root}catch{return!1}}(i)||(t.error(`Error: Cannot watch sensitive directory: ${i}\n - System directories and root directories are not allowed\n - Please specify a project directory instead`),process.exit(1)),t.info(l.cyan("π Starting watch mode...\n"));const r=bn(n);void 0!==n.watch_debounce&&t.verbose(l.gray(`β±οΈ Watch debounce: ${r}ms\n`)),yn=new gn,hn.clear(),_n=new re(100,1e3);const a=await xn(n,!1,t);z(a)&&(t.error(`Error: ${a.message}`),process.exit(1)),t.info(l.gray("\n"+"β".repeat(60))),t.info(l.gray(`π Watching for changes... (Press ${l.yellow("Ctrl+C")} to stop)`));try{pn=e.watch(i,{recursive:!0},(e,s)=>{s&&(_n&&!_n.shouldAllow()||n.export&&s.startsWith("LocIO-report.")||function(e,n,t){mn&&clearTimeout(mn),n&&hn.add(n);const s=bn(e);mn=setTimeout(async()=>{if(fn)return;fn=!0,t.info(l.cyan("π Changes detected. Rescanning...\n"));const n=await xn(e,!0,t);z(n)?(t.error(`\nβ Error: ${n.message}`),n.suggestion&&t.warn(`\nπ‘ Suggestion: ${n.suggestion}`)):(t.info(l.gray("\n"+"β".repeat(60))),t.info(l.gray(`π Watching for changes... (Press ${l.yellow("Ctrl+C")} to stop)`))),fn=!1},s)}(n,s,t))}),pn.on("error",e=>{t.error(`\nWatch error: ${e.message}`),t.warn("Note: Recursive watching may not be supported on all systems.")})}catch(e){t.error(`Failed to start watch mode: ${e instanceof Error?e.message:String(e)}`),t.warn("Note: Recursive watching may not be supported on all systems."),process.exit(1)}const c=()=>{mn&&clearTimeout(mn),pn&&pn.close(),yn&&(yn.clear(),yn=null),hn.clear(),t.info(l.gray("\n\nπ Watch mode stopped.")),process.exit(0)};process.on("SIGINT",c),process.on("SIGTERM",c)}async function $n(n){const t=await async function(n){const t=un(n);if(n.version)return void t.info(`LocIO ${S()}`);if(n.watch)return void await vn(n);const s=M(n.directory);if(s.error)return s.error;const o=s.path,i=e.statSync(o);let r;if(i.isDirectory()){const e=W(o);"unknown"!==e&&t.info(`${l.cyan("Detected project type:")} ${l.blue.bold(Le(e))}\n`)}n.directory=o;const a=n.quiet?null:new h;if(n.rm_comments){if(t.info(l.cyan("Removing comments from files...\n")),r=i.isFile()?await an(n):await cn(n),z(r))return r;const e=r._commentsRemoved||0;return void(e>0?t.success(`\nβ Comments removed successfully from ${e} file(s)!\n`):t.warn("\nβΉ No comments found in any files.\n"))}if(r=i.isFile()?await an(n):await cn(n),z(r))return r;a&&!z(r)&&a.trackScan(n,r),Fe(r,n)}(n);z(t)&&(console.error(function(e){let n=`\n${l.red.bold("β Error:")} ${l.white(e.message)}\n`;e.filePath&&(n+=`${l.gray("π File:")} ${l.white(e.filePath)}\n`),e.suggestion&&(n+=`\n${l.yellow.bold("π‘ Suggestion:")}\n${l.yellow(e.suggestion)}\n`);const t=(s=e.code,{DIRECTORY_NOT_FOUND:["locio . # Scan current directory","locio ./src # Scan specific directory","locio /path/to/directory # Scan absolute path"],FILE_NOT_FOUND:["locio ./file.ts # Scan a specific file","locio src/index.ts # Scan file with relative path"],NOT_A_DIRECTORY:["locio ./file.ts # Use file path directly","locio . # Use current directory instead"],INVALID_SIZE_FORMAT:["locio . --max-size 5MB # Valid: number + unit","locio . --min-size 1KB # Valid: KB, MB, GB, TB"],INVALID_REGEX:["locio . --exclude 'node_modules' # Simple pattern","locio . --exclude '.*\\.log$' # Escaped regex"],EXPORT_PATH_ERROR:["locio . --export json # Export to default location","locio . --export json --export-path ./reports # Custom path"]}[s]||[]);var s;return t.length>0&&(n+=`\n${l.cyan.bold("π Example Commands:")}\n`,t.forEach(e=>{n+=` ${l.gray("$")} ${l.white(e)}\n`})),n+=`\n${l.blue("π Documentation:")} ${l.underline("https://locio.js.org")}\n`,e.cause&&"object"==typeof e.cause&&"message"in e.cause&&(n+=`\n${l.gray("π Details:")} ${l.gray(String(e.cause.message))}\n`),n}(t)),process.exit(1)),n.watch||process.exit(0)}(async function(){if(2===a.argv.length&&a.stdin.isTTY){if(!await async function(){const e=S();r.intro(l.cyan.bold(`LocIO CLI v${e}`)),r.note("A fast, flexible line and file counter for your projects.","About");const n=await r.select({message:"Select an option:",options:[{value:"1",label:"Quick scan of current directory (default settings)"},{value:"2",label:"Show common command examples"},{value:"3",label:"View full help (same as --help)"},{value:"q",label:"Quit"}]});if(r.isCancel(n))return r.outro(l.green("Thank you for using LocIO.")),!1;switch(n){case"1":return r.note('Running quick scan on current directory (".") with default settings...',"Starting scan"),!0;case"2":return r.note(["locio . # Quick scan","locio . --files-only # Show only file counts","locio . --lines-only # Show only line counts",'locio . --exclude "target" # Ignore patterns',"locio . --include-ext ts,js # Filter by extension","locio . --export json # Export to JSON"].join("\n"),"Common Commands"),r.note("Use --help for more options","Tip"),!1;case"3":return console.log(),T().outputHelp(),console.log(),!1;case"q":return r.outro(l.green("Thank you for using LocIO.")),!1;default:return!1}}())return}const e=function(){const e=T();e.parse();const n=e.opts(),t=e.args,s=n.excludeExt?j(n.excludeExt):[],o=n.includeExt?j(n.includeExt):[];return{directory:t[0]||".",files_only:n.filesOnly||!1,lines_only:n.linesOnly||!1,exclude_patterns:n.exclude||[],exclude_extensions:s,include_extensions:o,exclude_dirs:n.excludeDir||[],include_dirs:n.includeDir||[],exclude_names:n.excludeName||[],include_names:n.includeName||[],max_size:n.maxSize,min_size:n.minSize,no_hidden:n.noHidden||!1,no_empty:n.noEmpty||!1,follow_links:n.followLinks||!1,max_depth:n.maxDepth,show_stats:n.stats||!1,show_progress:!0!==n.noProgress,no_binary:n.noBinary||!1,ignore_case:n.ignoreCase||!1,quiet:n.quiet||!1,export:F(n.export),export_path:n.exportPath,version:!1,watch:n.watch||!1,watch_debounce:n.watchDebounce,comments:!0!==n.noComments,code_vs_comments:n.codeVsComments||!1,rm_comments:(()=>{const e=n.rmComments;return!!e&&(!0===e||e)})(),top_files:n.topFiles,top_dirs:n.topDirs}}();await $n(e)})().catch(e=>{console.error("Unexpected error:",e),a.exit(1)});
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "locio",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A powerful CLI tool to count lines and files in directories with extensive filtering options",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
6
|
"bin": {
|
|
8
7
|
"locio": "./dist/index.js"
|
|
9
8
|
},
|
|
10
9
|
"scripts": {
|
|
11
10
|
"start": "node dist/index.js",
|
|
12
|
-
"build": "
|
|
11
|
+
"build": "tsup",
|
|
13
12
|
"build:watch": "tsup --watch",
|
|
14
|
-
"format": "prettier --write \"**/*.{js,json,ts,md}\""
|
|
13
|
+
"format": "prettier --write \"**/*.{js,json,ts,md}\"",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"benchmark": "vitest run tests/benchmarks"
|
|
15
16
|
},
|
|
16
17
|
"keywords": [
|
|
17
18
|
"cli",
|
|
@@ -34,7 +35,11 @@
|
|
|
34
35
|
"url": "https://github.com/kiron0/locio.git"
|
|
35
36
|
},
|
|
36
37
|
"homepage": "https://locio.js.org",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/kiron0/locio/issues"
|
|
40
|
+
},
|
|
37
41
|
"dependencies": {
|
|
42
|
+
"@clack/prompts": "^0.11.0",
|
|
38
43
|
"commander": "^14.0.2",
|
|
39
44
|
"chalk": "^5.6.2",
|
|
40
45
|
"ignore": "^7.0.5",
|
|
@@ -45,6 +50,10 @@
|
|
|
45
50
|
"prettier": "^3.7.4",
|
|
46
51
|
"terser": "^5.44.1",
|
|
47
52
|
"tsup": "^8.5.1",
|
|
48
|
-
"typescript": "^5.9.3"
|
|
53
|
+
"typescript": "^5.9.3",
|
|
54
|
+
"vitest": "^4.0.16"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=18.0.0"
|
|
49
58
|
}
|
|
50
59
|
}
|