var io = use('cellfs') Object.defineProperty(Function.prototype, "hashify", { value: function () { var hash = {} var fn = this function hashified(...args) { var key = args[0] if (hash[key] == null) hash[key] = fn(...args) return hash[key] } return hashified }, }) // Merge of the old resources.js and packer.js functionalities var Resources = {} // Recognized resource extensions Resources.scripts = ["js"] Resources.images = ["qoi", "png", "gif", "jpg", "jpeg", "ase", "aseprite"] Resources.sounds = ["wav", "flac", "mp3", "qoa"] Resources.fonts = ["ttf"] // Helper function: get extension from path in lowercase (e.g., "image.png" -> "png") function getExtension(path) { var idx = path.lastIndexOf('.') if (idx < 0) return '' return path.substring(idx + 1).toLowerCase() } // Return true if ext is in at least one of the recognized lists function isRecognizedExtension(ext) { if (!ext) return false if (Resources.scripts.includes(ext)) return true if (Resources.images.includes(ext)) return true if (Resources.sounds.includes(ext)) return true if (Resources.fonts.includes(ext)) return true if (Resources.lib.includes('.' + ext)) return true // for .so or .dll return false } function find_in_path(filename, exts = []) { if (typeof filename != 'string') return null if (filename.includes('.')) { var candidate = filename // possibly need "/" ? if (io.exists(candidate) && !io.is_directory(candidate)) return candidate return null } // Only check extensions if exts is provided and not empty if (exts.length > 0) { for (var ext of exts) { var candidate = filename + '.' + ext if (io.exists(candidate) && !io.is_directory(candidate)) return candidate } } else { // Fallback to extensionless file only if no extensions are specified var candidate = filename if (io.exists(candidate) && !io.is_directory(candidate)) return candidate } return null } // Return a canonical path (the real directory plus the path) Resources.canonical = function(file) { return io.realdir(file) + file } // The resource finders Resources.find_image = function(file) { return find_in_path(file, Resources.images) }.hashify() Resources.find_sound = function(file) { return find_in_path(file, Resources.sounds) }.hashify() Resources.find_script = function(file) { return find_in_path(file, Resources.scripts) }.hashify() Resources.find_font = function(file) { return find_in_path(file, Resources.fonts) }.hashify() // .prosperonignore reading helper function read_ignore(dir) { var path = dir + '/.prosperonignore' var patterns = [] if (io.exists(path)) { var lines = io.slurp(path).split('\n') for (var line of lines) { line = line.trim() if (!line || line.startsWith('#')) continue patterns.push(line) } } return patterns } // Return a list of recognized files in the directory (and subdirectories), // skipping those matched by .prosperonignore. Directory paths are skipped. Resources.getAllFiles = function(dir = "") { var patterns = read_ignore(dir) var all = io.globfs(patterns, dir) var results = [] for (var f of all) { var fullPath = dir + '/' + f try { var st = io.stat(fullPath) // skip directories (filesize=0) or unrecognized extension if (!st.filesize) continue var ext = getExtension(f) if (!isRecognizedExtension(ext)) continue results.push(fullPath) } catch(e) {} } return results } Resources.getAllFiles[cell.DOC] = ` Return a list of recognized files in the given directory that are not matched by .prosperonignore, skipping directories. Recognized extensions include scripts, images, sounds, fonts, and libs. :param dir: The directory to search. :return: An array of recognized file paths. ` // Categorize files by resource type Resources.gatherStats = function(filePaths) { var stats = { scripts:0, images:0, sounds:0, fonts:0, lib:0, other:0, total:filePaths.length } for (var path of filePaths) { var ext = getExtension(path) if (Resources.scripts.includes(ext)) { stats.scripts++ continue } if (Resources.images.includes(ext)) { stats.images++ continue } if (Resources.sounds.includes(ext)) { stats.sounds++ continue } if (Resources.fonts.includes(ext)) { stats.fonts++ continue } stats.other++ } return stats } Resources.gatherStats[cell.DOC] = ` Analyze a list of recognized files and categorize them by scripts, images, sounds, fonts, libs, or other. Return a stats object with these counts and the total. :param filePaths: An array of file paths to analyze. :return: { scripts, images, sounds, fonts, lib, other, total } ` return Resources