diff --git a/.gitignore b/.gitignore index dbdea3ac1..bb20362d9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ Tests/Manual/**/*.xcodeproj *.sublime-workspace *.tm_properties *.idea -node_modules \ No newline at end of file +node_modules +*.vscode \ No newline at end of file diff --git a/dist/cappuccino/bin/capp b/dist/cappuccino/bin/capp new file mode 100755 index 000000000..a93d6d49b --- /dev/null +++ b/dist/cappuccino/bin/capp @@ -0,0 +1,9 @@ +#!/usr/bin/env node + +const path = require("path"); + +var commandName = path.basename(process.argv[1]); +var mainPath = path.resolve(__dirname, "..", "lib", commandName, "main.j"); +var args = ["objj", mainPath].concat(process.argv.slice(2)); + +require("@objj/runtime").run(args); diff --git a/dist/cappuccino/bin/cib-dump b/dist/cappuccino/bin/cib-dump new file mode 100755 index 000000000..98470ee6c --- /dev/null +++ b/dist/cappuccino/bin/cib-dump @@ -0,0 +1,19 @@ +#!/usr/bin/env objj + +@import + +@import "../lib/cappuccino/cib-analysis-tools.j" + +var FILE = require("file"); + +CPLogRegister(CPLogPrint); + +function main(args) +{ + args.slice(1).forEach(function(path) { + var classes = findCibClassDependencies(FILE.absolute(path)); + + print(path+":"); + classes.sort().forEach(function(className) { print(" + " + className) }); + }); +} diff --git a/dist/cappuccino/bin/flatten b/dist/cappuccino/bin/flatten new file mode 100755 index 000000000..1df033252 --- /dev/null +++ b/dist/cappuccino/bin/flatten @@ -0,0 +1,368 @@ +#!/usr/bin/env objj + +require("narwhal").ensureEngine("rhino"); + +@import + +@import "../lib/cappuccino/objj-analysis-tools.j" + +var FILE = require("file"); +var OS = require("os"); +var UTIL = require("narwhal/util"); + +var CACHEMANIFEST = require("objective-j/cache-manifest"); + +var stream = require("narwhal/term").stream; +var parser = new (require("narwhal/args").Parser)(); + +parser.usage("INPUT_PROJECT OUTPUT_PROJECT"); +parser.help("Combine a Cappuccino application into a single JavaScript file."); + +parser.option("-m", "--main", "main") + .def("main.j") + .set() + .help("The relative path (from INPUT_PROJECT) to the main file (default: 'main.j')"); + +parser.option("-F", "--framework", "frameworks") + .push() + .help("Add a frameworks directory, relative to INPUT_PROJECT (default: ['Frameworks'])"); + +parser.option("-P", "--path", "paths") + .push() + .help("Add a path (relative to the application root) to inline."); + +parser.option("-f", "--force", "force") + .def(false) + .set(true) + .help("Force overwriting OUTPUT_PROJECT if it exists"); + +parser.option("--index", "index") + .def("index.html") + .set() + .help("The root HTML file to modify (default: index.html)"); + +parser.option("-s", "--split", "number", "split") + .natural() + .def(0) + .help("Split into multiple files"); + +parser.option("-c", "--compressor", "compressor") + .def("shrinksafe") + .set() + .help("Select a compressor to use (closure-compiler, yuicompressor, shrinksafe), or \"none\" (default: shrinksafe)"); + +parser.option("--manifest", "manifest") + .set(true) + .help("Generate HTML5 cache manifest."); + +parser.option("-v", "--verbose", "verbose") + .def(false) + .set(true) + .help("Verbose logging"); + +parser.helpful(); + +function main(args) +{ + var options = parser.parse(args); + + if (options.args.length < 2) { + parser.printUsage(options); + return; + } + + var rootPath = FILE.path(options.args[0]).join("").absolute(); + var outputPath = FILE.path(options.args[1]).join("").absolute(); + + if (outputPath.exists()) { + if (options.force) { + // FIXME: why doesn't this work?! + //outputPath.rmtree(); + OS.system(["rm", "-rf", outputPath]); + } else { + stream.print("\0red(OUTPUT_PROJECT " + outputPath + " exists. Use -f to overwrite.\0)"); + OS.exit(1); + } + } + + options.frameworks.push("Frameworks"); + + var mainPath = String(rootPath.join(options.main)); + var frameworks = options.frameworks.map(function(framework) { return rootPath.join(framework); }); + var environment = "Browser"; + + stream.print("\0yellow("+Array(81).join("=")+"\0)"); + stream.print("Application root: \0green(" + rootPath + "\0)"); + stream.print("Output directory: \0green(" + outputPath + "\0)"); + + stream.print("\0yellow("+Array(81).join("=")+"\0)"); + stream.print("Main file: \0green(" + mainPath + "\0)"); + stream.print("Frameworks: \0green(" + frameworks + "\0)"); + stream.print("Environment: \0green(" + environment + "\0)"); + + var flattener = new ObjectiveJFlattener(rootPath); + + flattener.options = options; + + flattener.setIncludePaths(frameworks); + flattener.setEnvironments([environment, "ObjJ"]); + + print("Loading application."); + flattener.load(mainPath); + + print("Loading default theme."); + flattener.require("objective-j").objj_eval("("+(function() { + + var defaultThemeName = [CPApplication defaultThemeName], + bundle = nil; + + if (defaultThemeName === @"Aristo" || defaultThemeName === @"Aristo2") + bundle = [CPBundle bundleForClass:[CPApplication class]]; + else + bundle = [CPBundle mainBundle]; + + var blend = [[CPThemeBlend alloc] initWithContentsOfURL:[bundle pathForResource:defaultThemeName + @".blend"]]; + [blend loadWithDelegate:nil]; + + })+")")(); + + var applicationJSs = flattener.buildApplicationJS(); + + FILE.copyTree(rootPath, outputPath); + + applicationJSs.forEach(function(applicationJS, n) { + var name = "Application"+(n||"")+".js"; + if (options.compressor === "none") { + print("skipping compression: " + name); + } else { + print("compressing: " + name); + applicationJS = require("minify/"+options.compressor).compress(applicationJS, { charset : "UTF-8", useServer : true }); + } + outputPath.join(name).write(applicationJS, { charset : "UTF-8" }); + }); + + rewriteMainHTML(outputPath.join(options.index)); + + if (options.manifest) { + CACHEMANIFEST.generateManifest(outputPath, { + index : outputPath.join(options.index), + exclude : Object.keys(flattener.filesToCache).map(function(path) { return outputPath.join(path).toString(); }) + }); + } +} + +// ObjectiveJFlattener inherits from ObjectiveJRuntimeAnalyzer +function ObjectiveJFlattener(rootPath) { + ObjectiveJRuntimeAnalyzer.apply(this, arguments); + + this.filesToCache = {}; + this.fileCacheBuffer = []; + this.functionsBuffer = []; +} + +ObjectiveJFlattener.prototype = Object.create(ObjectiveJRuntimeAnalyzer.prototype); + +ObjectiveJFlattener.prototype.buildApplicationJS = function() { + + this.setupFileCache(); + this.serializeFunctions(); + this.serializeFileCache(); + + var additions = FILE.read(FILE.join(FILE.dirname(module.path), "..", "..", "cappuccino", "lib", "cappuccino", "objj-flatten-additions.js"), { charset:"UTF-8" }); + + var applicationJSs = []; + + if (this.options.split === 0) { + var buffer = []; + buffer.push("var baseURL = new CFURL(\".\", ObjectiveJ.pageURL);"); + buffer.push(additions); + buffer.push(this.fileCacheBuffer.join("\n")); + buffer.push(this.functionsBuffer.join("\n")); + buffer.push("ObjectiveJ.bootstrap();"); + applicationJSs.push(buffer.join("\n")); + } else { + var appFilesCount = this.options.split; + + var buffers = []; + for (var i = 0; i <= appFilesCount; i++) + buffers.push([]); + + var chunks = this.fileCacheBuffer.concat(this.functionsBuffer).sort(function(chunkA, chunkB) { + return chunkA.length - chunkB.length; + }); + + // try to equally distribute the chunks. could be better but good enough for now. + var n = 0; + while (chunks.length) { + buffers[(n++ % appFilesCount) + 1].push(chunks.pop()); + } + + buffers[0].push("var baseURL = new CFURL(\".\", ObjectiveJ.pageURL);"); + buffers[0].push(additions); + + buffers[0].push("var appFilesCount = " + appFilesCount +";"); + buffers[0].push("for (var i = 1; i <= appFilesCount; i++) {"); + buffers[0].push(" var script = document.createElement(\"script\");"); + buffers[0].push(" script.src = \"Application\"+i+\".js\";"); + buffers[0].push(" script.charset = \"UTF-8\";"); + buffers[0].push(" script.onload = function() { if (--appFilesCount === 0) ObjectiveJ.bootstrap(); };"); + buffers[0].push(" document.getElementsByTagName(\"head\")[0].appendChild(script);"); + buffers[0].push("}"); + + buffers.forEach(function(buffer) { + applicationJSs.push(buffer.join("\n")); + }); + } + + return applicationJSs; +} + +ObjectiveJFlattener.prototype.serializeFunctions = function() { + var inlineFunctions = true;//this.options.inlineFunctions; + + var outputFiles = {}; + + var _cachedExecutableFunctions = {}; + + this.require("objective-j").FileExecutable.allFileExecutables().forEach(function(executable) { + var path = executable.path(); + + if (inlineFunctions) + { + // stringify the function, replacing arguments + var functionString = executable._function.toString().replace(", require, exports, module, system, print, window", ""); // HACK + + var relative = this.rootPath.relative(path).toString(); + this.functionsBuffer.push("ObjectiveJ.StaticResource._cacheFunction(new CFURL("+JSON.stringify(relative)+", baseURL),\n"+functionString+");"); + } + + var bundle = this.context.global.CFBundle.bundleContainingURL(path); + if (bundle && bundle.infoDictionary()) + { + var executablePath = bundle.executablePath(), + relativeToBundle = FILE.relative(FILE.join(bundle.path(), ""), path); + + if (executablePath) + { + if (inlineFunctions) + { + // remove the code since we're inlining the functions + executable._code = "alert("+JSON.stringify(relativeToBundle)+");"; + } + + if (!outputFiles[executablePath]) + { + outputFiles[executablePath] = []; + outputFiles[executablePath].push("@STATIC;1.0;"); + } + + var fileContents = executable.toMarkedString(); + + outputFiles[executablePath].push("p;" + relativeToBundle.length + ";" + relativeToBundle); + outputFiles[executablePath].push("t;" + fileContents.length + ";" + fileContents); + + // stream.print("Adding \0green(" + this.rootPath.relative(path) + "\0) to \0cyan(" + this.rootPath.relative(executablePath) + "\0)"); + } + } + else + CPLog.warn("No bundle (or info dictionary for) " + rootPath.relative(path)); + }, this); + + for (var executablePath in outputFiles) + { + var relative = this.rootPath.relative(executablePath).toString(); + var contents = outputFiles[executablePath].join(""); + this.filesToCache[relative] = contents; + } +} + +ObjectiveJFlattener.prototype.serializeFileCache = function() { + for (var relative in this.filesToCache) { + var contents = this.filesToCache[relative]; + print("caching: " + relative + " => " + (contents == null ? 404 : 200)); + if (contents == null) + this.fileCacheBuffer.push("CFHTTPRequest._cacheRequest(new CFURL("+JSON.stringify(relative)+", baseURL), 404);"); + else + this.fileCacheBuffer.push("CFHTTPRequest._cacheRequest(new CFURL("+JSON.stringify(relative)+", baseURL), 200, {}, "+JSON.stringify(contents)+");"); + } +} + +ObjectiveJFlattener.prototype.setupFileCache = function() { + var paths = {}; + + UTIL.update(paths, this.requestedURLs); + + this.options.paths.forEach(function(relativePath) { + paths[this.rootPath.join(relativePath)] = true; + }, this); + + Object.keys(paths).forEach(function(absolute) { + var relative = this.rootPath.relative(absolute).toString(); + if (relative.indexOf("..") === 0) + { + print("skipping (parent of app root): " + absolute); + return; + } + + if (FILE.isFile(absolute)) + { + // if (this.options.maxCachedSize && FILE.size(absolute) > this.options.maxCachedSize) + // { + // print("skipping (larger than "+this.options.maxCachedSize+" bytes): " + absolute); + // return; + // } + + var contents = FILE.read(absolute, { charset : "UTF-8" }); + this.filesToCache[relative] = contents; + } else { + this.filesToCache[relative] = null; + } + }, this); +} + +// "$1" is the matching indentation +var scriptTagsBefore = + '$1'; + +var scriptTagsAfter = + '$1'; + +// enable CPLog: +// scriptTagsAfter = '$1\n' + scriptTagsAfter; + +function rewriteMainHTML(indexHTMLPath) { + if (indexHTMLPath.isFile()) { + var indexHTML = indexHTMLPath.read({ charset : "UTF-8" }); + + // inline the Application.js if it's smallish + var applicationJSPath = indexHTMLPath.dirname().join("Application.js"); + if (applicationJSPath.size() < 10*1024) { + // escape any dollar signs by replacing them with two + // then indent by splitting/joining on newlines + scriptTagsAfter = + '$1'; + } + + // attempt to find Objective-J script tag and add ours + var newIndexHTML = indexHTML.replace(/([ \t]+)]+Objective-J\.js[^>]+>(?:\s*<\/script>)?/, + scriptTagsBefore+'\n$&\n'+scriptTagsAfter); + + if (newIndexHTML !== indexHTML) { + stream.print("\0green(Modified: "+indexHTMLPath+".\0)"); + indexHTMLPath.write(newIndexHTML, { charset : "UTF-8" }); + return; + } + } else { + stream.print("\0yellow(Warning: "+indexHTMLPath+" does not exist. Specify an alternate index HTML file with the --index option.\0)"); + } + + stream.print("\0yellow(Warning: Unable to automatically modify "+indexHTMLPath + ".\0)"); + stream.print("\nAdd the following before the Objective-J script tag:"); + stream.print(scriptTagsBefore.replace(/\$1/g, " ")); + stream.print("\nAdd the following after the Objective-J script tag:"); + stream.print(scriptTagsAfter.replace(/\$1/g, " ")); +} diff --git a/dist/cappuccino/bin/fontinfo b/dist/cappuccino/bin/fontinfo new file mode 100755 index 000000000..fb6412d32 Binary files /dev/null and b/dist/cappuccino/bin/fontinfo differ diff --git a/dist/cappuccino/bin/imagesize b/dist/cappuccino/bin/imagesize new file mode 100755 index 000000000..99a6a1724 Binary files /dev/null and b/dist/cappuccino/bin/imagesize differ diff --git a/dist/cappuccino/bin/jake b/dist/cappuccino/bin/jake new file mode 100755 index 000000000..5d38ac07e --- /dev/null +++ b/dist/cappuccino/bin/jake @@ -0,0 +1,7 @@ +#!/usr/bin/env node + +JAKE = require("@objj/jake"); +ObjectiveJ = require("@objj/runtime"); +CAPPUCCINO = require("@objj/cappuccino"); + +JAKE.application().run({ args : process.argv }); diff --git a/dist/cappuccino/bin/nib2cib b/dist/cappuccino/bin/nib2cib new file mode 100755 index 000000000..a93d6d49b --- /dev/null +++ b/dist/cappuccino/bin/nib2cib @@ -0,0 +1,9 @@ +#!/usr/bin/env node + +const path = require("path"); + +var commandName = path.basename(process.argv[1]); +var mainPath = path.resolve(__dirname, "..", "lib", commandName, "main.j"); +var args = ["objj", mainPath].concat(process.argv.slice(2)); + +require("@objj/runtime").run(args); diff --git a/dist/cappuccino/bin/objj b/dist/cappuccino/bin/objj new file mode 100755 index 000000000..ae534b165 --- /dev/null +++ b/dist/cappuccino/bin/objj @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require("@objj/runtime").run(process.argv); diff --git a/dist/cappuccino/bin/ojdepcheck b/dist/cappuccino/bin/ojdepcheck new file mode 100755 index 000000000..c373f6927 --- /dev/null +++ b/dist/cappuccino/bin/ojdepcheck @@ -0,0 +1,59 @@ +#!/usr/bin/env objj + +require("narwhal").ensureEngine("rhino"); + +@import + +@import "../lib/cappuccino/objj-analysis-tools.j" + +var FILE = require("file"); + +var stream = require("narwhal/term").stream +var parser = new (require("narwhal/args").Parser)(); + +parser.usage("INPUT_PROJECT"); +parser.help("Checks a project for missing imports."); + +parser.helpful(); + +function main(args) +{ + var options = parser.parse(args); + + if (options.args.length < 1) { + parser.printUsage(options); + return; + } + + var rootPath = FILE.path(options.args[0]).join("").absolute(); + var mainPath = rootPath.join("main.j"); + + var analyzer = new ObjectiveJRuntimeAnalyzer(rootPath); + + analyzer.setIncludePaths([rootPath.join("Frameworks")]); + analyzer.setEnvironments(["Browser", "ObjJ"]); + + analyzer.initializeGlobalRecorder(); + + analyzer.load(mainPath); + analyzer.finishLoading(); + + var mainExecutable = analyzer.executableForImport(mainPath); + + var context = analyzer.traverseDependencies(mainExecutable, { + progressCallback : function(path) { stream.print("Analyzing \0purple(" + path + "\0)..."); } + }); + + for (var path in context.referencedFiles) { + var referencedFiles = context.referencedFiles[path]; + + for (var referenced in referencedFiles) { + if (!context.importedFiles[path] || !context.importedFiles[path][referenced]) { + stream.print("\0purple(" + rootPath.relative(path) + "\0) references but doesn't import \0purple(" + rootPath.relative(referenced) + "\0):") + Object.keys(referencedFiles[referenced]).forEach(function(token) { + stream.print(" \0cyan(" + token + "\0)"); + }); + } + } + } +} \ No newline at end of file diff --git a/dist/cappuccino/bin/press b/dist/cappuccino/bin/press new file mode 100755 index 000000000..b89bb49d4 --- /dev/null +++ b/dist/cappuccino/bin/press @@ -0,0 +1,411 @@ +#!/usr/bin/env objj + +require("narwhal").ensureEngine("rhino"); + +@import + +@import "../lib/cappuccino/objj-analysis-tools.j" +@import "../lib/cappuccino/cib-analysis-tools.j" + +var FILE = require("file"); +var OS = require("os"); + +var CACHEMANIFEST = require("objective-j/cache-manifest"); + +var stream = require("narwhal/term").stream; +var parser = new (require("narwhal/args").Parser)(); + +parser.usage("INPUT_PROJECT OUTPUT_PROJECT"); +parser.help("Analyze and strip unused files from a Cappuccino project's .sj bundles."); + +parser.option("-m", "--main", "main") + .def("main.j") + .set() + .help("The relative path (from INPUT_PROJECT) to the main file (default: 'main.j')"); + +parser.option("-F", "--framework", "frameworks") + .def(["Frameworks"]) + .push() + .help("Add a frameworks directory, relative to INPUT_PROJECT (default: ['Frameworks'])"); + +parser.option("-f", "--force", "force") + .def(false) + .set(true) + .help("Force overwriting OUTPUT_PROJECT if it exists"); + +parser.option("--index", "index") + .def("index.html") + .set() + .help("The root HTML file to modify (default: index.html) (NOTE: currently only used by '--manifest' option)"); + +parser.option("-p", "--pngcrush", "png") + .def(false) + .set(true) + .help("Run pngcrush on all PNGs (pngcrush must be installed!)"); + +parser.option("--manifest", "manifest") + .set(true) + .help("Generate HTML5 cache manifest."); + +parser.option("-v", "--verbose", "verbose") + .def(false) + .set(true) + .help("Verbose logging"); + +parser.helpful(); + +function main(args) +{ + var options = parser.parse(args); + + if (options.args.length < 2) { + parser.printUsage(options); + return; + } + + CPLogRegister(CPLogPrint); + + // HACK: ensure trailing slashes for "relative" to work correctly + var rootPath = FILE.path(options.args[0]).absolute().join(""); + var outputPath = FILE.path(options.args[1]).absolute().join(""); + + if (outputPath.exists()) { + if (options.force) { + // FIXME: why doesn't this work?! + //outputPath.rmtree(); + OS.system(["rm", "-rf", outputPath]); + } else { + stream.print("\0red(OUTPUT_PROJECT " + outputPath + " exists. Use -f to overwrite.\0)"); + OS.exit(1); + } + } + + press(rootPath, outputPath, options); +} + +function press(rootPath, outputPath, options) { + stream.print("\0yellow("+Array(81).join("=")+"\0)"); + stream.print("Application root: \0green(" + rootPath + "\0)"); + stream.print("Output directory: \0green(" + outputPath + "\0)"); + + var outputFiles = {}, + totalBytes = {executable:0, data:0, mhtml:0}; + + var environment = "Browser"; + // analyze and gather files for each environment: + var returnedBytes = pressEnvironment(rootPath, outputFiles, environment, options); + + for (var i in returnedBytes) + totalBytes[i] += returnedBytes[i]; + + // phase 4: copy everything and write out the new files + stream.print("\0red(PHASE 4:\0) copy to output \0green(" + rootPath + "\0) => \0green(" + outputPath + "\0)"); + + FILE.copyTree(rootPath, outputPath); + + for (var path in outputFiles) { + var file = outputPath.join(rootPath.relative(path)); + + var parent = file.dirname(); + if (!parent.exists()) { + CPLog.warn(parent + " doesn't exist, creating directories."); + parent.mkdirs(); + } + + if (typeof outputFiles[path] !== "string") + outputFiles[path] = outputFiles[path].join(""); + + stream.print((file.exists() ? "\0red(Overwriting:\0) " : "\0green(Writing:\0) ") + file); + + FILE.write(file, outputFiles[path], { charset : "UTF-8" }); + } + + // phase 4a: update the info.plist to contain meta information about the app + stream.print("\0red(PHASE 4a:\0) Add application size data to Info.plist"); + + var outputInfoPlistPath = FILE.join(outputPath, "Info.plist"), + outputInfoPlistContents = FILE.read(outputInfoPlistPath, { charset:"UTF-8" }), + format = CFPropertyList.sniffedFormatOfString(outputInfoPlistContents), + outputInfoPlist = CFPropertyList.propertyListFromString(outputInfoPlistContents); + + // read in the default theme name, and attempt to get its size + var themeName = outputInfoPlist.valueForKey("CPDefaultTheme") || "Aristo2", + themePath = nil; + + if (themeName === "Aristo" || themeName === "Aristo2") + themePath = FILE.join(outputPath, options.frameworks, "AppKit", "Resources", themeName+".blend"); + else + themePath = FILE.join(outputPath, "Resources", themeName + ".blend"); + + if (FILE.exists(themePath)) + { + var themeEnvPath = FILE.join(themePath, environment + ".environment"), + themeExecutablePath = FILE.join(themeEnvPath, themeName+".blend.sj"), + themeDataPath = FILE.join(themeEnvPath, "dataURLs.txt"), + themeMHTMLPath = FILE.join(themeEnvPath, "MHTMLPaths.txt"); + + totalBytes.executable += FILE.read(themeExecutablePath, {charset : "UTF-8"}).length; + totalBytes.data += FILE.read(themeDataPath, {charset : "UTF-8"}).length; + totalBytes.mhtml += FILE.read(themeMHTMLPath, {charset : "UTF-8"}).length; + } + + outputInfoPlist.setValueForKey("CPApplicationSize", [CPDictionary dictionaryWithJSObject:totalBytes]); + + FILE.write(outputInfoPlistPath, CFPropertyList.stringFromPropertyList(outputInfoPlist, format), { charset:"UTF-8" }); + + // strip known unnecessary files + // outputPath.glob("**/Frameworks/Debug").forEach(function(debugFramework) { + // outputPath.join(debugFramework).rmtree(); + // }); + // outputPath.join("index-debug.html").remove(); + + if (options.png) { + pngcrushDirectory(outputPath); + } + + if (options.manifest) { + CACHEMANIFEST.generateManifest(outputPath, { + index : outputPath.join(options.index) + }); + } +} + +function pressEnvironment(rootPath, outputFiles, environment, options) { + + var mainPath = String(rootPath.join(options.main)); + var frameworks = options.frameworks.map(function(framework) { return rootPath.join(framework); }); + + stream.print("\0yellow("+Array(81).join("=")+"\0)"); + stream.print("Main file: \0green(" + mainPath + "\0)"); + stream.print("Frameworks: \0green(" + frameworks + "\0)"); + stream.print("Environment: \0green(" + environment + "\0)"); + + var analyzer = new ObjectiveJRuntimeAnalyzer(rootPath); + + var _OBJJ = analyzer.require("objective-j"); + + analyzer.setIncludePaths(frameworks); + analyzer.setEnvironments([environment, "ObjJ"]); + + // build list of cibs to inspect for dependent classes + // FIXME: what's the best way to determine which cibs to look in? + var cibs = FILE.glob(rootPath.join("**", "*.cib")).filter(function(path) { return !(/Frameworks/).test(path); }); + + // phase 1: get global defines + stream.print("\0red(PHASE 1:\0) Loading application..."); + + analyzer.initializeGlobalRecorder(); + + analyzer.load(mainPath); + + analyzer.finishLoading(); + + // coalesce the results + var dependencies = analyzer.mapGlobalsToFiles(); + + // log identifer => files defining + stream.print("Global defines:"); + Object.keys(dependencies).sort().forEach(function(identifier) { + stream.print("\0blue(" + identifier + "\0) => \0cyan(" + dependencies[identifier].map(rootPath.relative.bind(rootPath)) + "\0)"); + }); + + // phase 2: walk the dependency tree (both imports and references) to determine exactly which files need to be included + stream.print("\0red(PHASE 2:\0) Traverse dependency graph..."); + + var requiredFiles = {}; + requiredFiles[mainPath] = true; + + var context = { + ignoreFrameworkImports : true, // ignores "XXX/XXX.j" imports + importCallback: function(importing, imported) { requiredFiles[imported] = true; }, + referenceCallback: function(referencing, referenced) { requiredFiles[referenced] = true; }, + progressCallback: function(relPath) { stream.print("Processing \0cyan("+relPath+"\0)"); }, + ignoreFrameworkImportsCallback : function(relPath) { stream.print("\0yellow(Ignoring imports in "+relPath+"\0)"); } + } + + mainExecutable = analyzer.executableForImport(mainPath); + + // check the code + analyzer.traverseDependencies(mainExecutable, context); + + // check the cibs + var globalsToFiles = analyzer.mapGlobalsToFiles(); + cibs.forEach(function(cibPath) { + var cibClasses = findCibClassDependencies(cibPath); + stream.print("Cib: \0green("+rootPath.relative(cibPath)+"\0) => \0cyan("+cibClasses+"\0)"); + + var referencedFiles = {}; + markFilesReferencedByTokens(cibClasses, globalsToFiles, referencedFiles); + analyzer.checkReferenced(context, null, referencedFiles); + }); + + var included = 0, total = 0; + var includedBytes = 0, totalBytes = 0, dataBytes = 0, mhtmlBytes = 0; + + _OBJJ.FileExecutable.allFileExecutables().forEach(function(aFileExecutable) { + var path = aFileExecutable.path(); + + // mark all ".keytheme"s as required + if (/\.keyedtheme$/.test(path)) + requiredFiles[path] = true; + + if (requiredFiles[path]) { + stream.print("Included: \0green(" + rootPath.relative(path) + "\0)"); + included++; + includedBytes += aFileExecutable.code().length + } + else { + stream.print("Excluded: \0red(" + rootPath.relative(path) + "\0)"); + } + total++; + totalBytes += aFileExecutable.code().length + }, this); + stream.print(_OBJJ.sprintf( + "Saved \0green(%f%%\0) (\0blue(%s\0)); Total required files: \0magenta(%d\0) (\0blue(%s\0)) of \0magenta(%d\0) (\0blue(%s\0));", + Math.round(((includedBytes - totalBytes) / totalBytes) * -100), + bytesToString(totalBytes - includedBytes), + included, bytesToString(includedBytes), + total, bytesToString(totalBytes) + )); + + // phase 3b: rebuild .sj files with correct imports, copy .j files + stream.print("\0red(PHASE 3b:\0) Rebuild .sj files"); + + var processedBundles = {}; + + for (var path in requiredFiles) + { + var executable = analyzer.executableForImport(path), + bundle = analyzer.context.global.CFBundle.bundleContainingURL(executable.path()), + relativePath = FILE.relative(FILE.join(bundle.path(), ""), executable.path()); + + if (executable.path() !== path) + CPLog.warn("Sanity check failed (file path): " + executable.path() + " vs. " + path); + + if (bundle && bundle.infoDictionary()) + { + var executablePath = bundle.executablePath(); + if (executablePath) + { + if (context.ignoredImports[path]) + { + stream.print("Stripping extra imports from \0blue(" + path + "\0)"); + + var code = executable.code(); + var dependencies = executable.fileDependencies(), + fileExecutableSearcher = executable.fileExecutableSearcher(); + for (var i = 0; i < dependencies.length; i++) { + var dependency = dependencies[i]; + var dependencyExecutable = nil; + + fileExecutableSearcher(dependency.URL(), dependency.isLocal(), function(aFileExecutable) + { + dependencyExecutable = aFileExecutable; + }); + + var dependencyPath = dependencyExecutable.path(); + if (!requiredFiles[dependencyPath]) { + stream.print(" -> \0red(" + dependencyPath + "\0)"); + // build up a regex to match objj_executeFile with optional whitespace + var regex = new RegExp([ + RegExp.escape("objj_executeFile"), + RegExp.escape("("), + "[\"']"+RegExp.escape(dependency.path())+"[\"']", + RegExp.escape(","), + dependency.isLocal() ? "(true|YES)" : "(false|NO)", + RegExp.escape(")") + ].join("\\s*"), "g"); + // replace instances of "objj_executeFile()" with "(undefined)" + newCode = code.replace(regex, "/* $& */ (undefined)"); + if (newCode === code) + stream.print("\0yellow(Warning:\0) Unable to strip import for \0cyan(" + dependency.path() + "\0) (" + dependency.isLocal() + ")"); + code = newCode; + // remove from dependencies list (decrement i since we're removing an item) + dependencies.splice(i--, 1); + } + } + if (code !== executable.code()) + executable.setCode(code); + } + + if (!outputFiles[executablePath]) + { + outputFiles[executablePath] = []; + outputFiles[executablePath].push("@STATIC;1.0;"); + } + + var fileContents = executable.toMarkedString(); + + outputFiles[executablePath].push("p;" + relativePath.length + ";" + relativePath); + outputFiles[executablePath].push("t;" + fileContents.length + ";" + fileContents); + + stream.print("Adding \0green(" + rootPath.relative(path) + "\0) to \0cyan(" + rootPath.relative(executablePath) + "\0)"); + } + else + { + stream.print("Passing .j through: \0green(" + rootPath.relative(path) + "\0)"); + } + + if (!processedBundles[bundle.path()] && bundle.hasSpritedImages()) + { + processedBundles[bundle.path()] = bundle; + stream.print("Sizing bundle's sprited resources \0green(" + bundle.path() + "\0)"); + + var bundlePath = FILE.join(bundle.path(), environment+".environment"), + bundleDataPath = FILE.join(bundlePath, "dataURLs.txt"), + bundleMHTMLPath = FILE.join(bundlePath, "MHTMLPaths.txt"); + + dataBytes += FILE.read(bundleDataPath, {charset : "UTF-8"}).length; + mhtmlBytes += FILE.read(bundleMHTMLPath, {charset : "UTF-8"}).length; + } + } + else + CPLog.warn("No bundle (or info dictionary for) " + rootPath.relative(path)); + } + + return {executable:includedBytes, data:dataBytes, mhtml:mhtmlBytes}; +} + +function pngcrushDirectory(directory) +{ + var directoryPath = FILE.path(directory), + pngs = directoryPath.glob("**/*.png"); + + system.stderr.print("Running pngcrush on " + pngs.length + " pngs:"); + pngs.forEach(function(dstPath) + { + var tmpPath = FILE.path(dstPath+".tmp"); + + try + { + var p = OS.popen(["pngcrush", "-rem", "alla", "-reduce", /*"-brute",*/ dstPath, tmpPath]); + + if (p.wait()) + { + CPLog.warn("pngcrush failed. Ensure it's installed and on your PATH."); + } + else + { + FILE.move(tmpPath, dstPath); + system.stderr.write(".").flush(); + } + } + finally + { + p.stdin.close(); + p.stdout.close(); + p.stderr.close(); + } + }); + + system.stderr.print(""); +} + +function bytesToString(bytes) { + var n = 0; + while (bytes > 1024) { + bytes /= 1024; + n++; + } + return Math.round(bytes*100)/100 + " " + ["", "K", "M"][n] + "B"; +} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 464a1610c..000000000 --- a/package-lock.json +++ /dev/null @@ -1,747 +0,0 @@ -{ - "name": "@objj/cappuccino", - "version": "1.0.1-16", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@objj/cappuccino", - "version": "1.0.1-16", - "dependencies": { - "@objj/jake": "latest", - "@objj/runtime": "latest" - }, - "bin": { - "capp": "dist/cappuccino/bin/capp", - "cib-dump": "dist/cappuccino/bin/cib-dump", - "flatten": "dist/cappuccino/bin/flatten", - "fontinfo": "dist/cappuccino/bin/fontinfo", - "imagesize": "dist/cappuccino/bin/imagesize", - "jake": "dist/cappuccino/bin/jake", - "nib2cib": "dist/cappuccino/bin/nib2cib", - "objj": "dist/cappuccino/bin/objj", - "ojdepcheck": "dist/cappuccino/bin/ojdepcheck", - "press": "dist/cappuccino/bin/press" - }, - "devDependencies": { - "@objj/cappuccino": "file:.", - "require-self": "0.2.3", - "terser": "^5.7.0" - } - }, - "node_modules/@objj/cappuccino": { - "resolved": "", - "link": true - }, - "node_modules/@objj/jake": { - "version": "1.0.3-12", - "resolved": "https://registry.npmjs.org/@objj/jake/-/jake-1.0.3-12.tgz", - "integrity": "sha512-4aBAe39lLjSBLkE3FLV5IAFsYSVBCz8a8EFaM6vD+nORQutpz9mHYspfvHja6oVkDqc+r7PzE1aJ5+6MuYNBoQ==", - "dependencies": { - "@objj/runtime": "latest", - "glob": "^7.1.7", - "minimatch": "^3.0.4" - }, - "bin": { - "jake": "bin/jake" - } - }, - "node_modules/@objj/runtime": { - "version": "0.4.7-11", - "resolved": "https://registry.npmjs.org/@objj/runtime/-/runtime-0.4.7-11.tgz", - "integrity": "sha512-ZCludZuRcY2oFQhNfrUuKteycxA0gtxjdYfCAcT3azF9Rx4kvRLcHojXMp6JY8Gx9NDsrHVqCJRo9v0geHM2aQ==", - "dependencies": { - "@objj/utils": "latest", - "objj-transpiler": "^0.5.0", - "readline-history": ">=1.2.0", - "uuid": "^8.3.2", - "xmldom": "^0.6.0", - "xmlhttprequest-ssl": ">=1.6.2" - }, - "bin": { - "objj": "bin/objj" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@objj/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@objj/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-HE/TM8nQCH0Vpqip4FIPXaxqVOJnI1+VHKR8EybW9gR2Fyj+DHzCnoYuZGT4bhuX/8Y6/EkauQmA4MYevNQOPw==", - "dependencies": { - "glob": "7.1.7", - "minimatch": "3.0.4" - } - }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "engines": { - "node": ">=0.4.2" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/objj-parser": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/objj-parser/-/objj-parser-0.4.0.tgz", - "integrity": "sha512-Kw6tbMp4K+lLm1jdKpcrgLu8MZg3JY1sSi4kzOncIO8nM5uzyLYY2xwwpsLdqxaipfB1n8Gr1EnscdKOcLJ80A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/objj-transpiler": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/objj-transpiler/-/objj-transpiler-0.5.1.tgz", - "integrity": "sha512-KSIjnKJZcQ3HExF5zUjRNNtm+zfmbzfEF8es2H2xBu7b2hPEdP+bpOuZCb65+f+To/Ei+E90b+UsdKcsjwyG+w==", - "dependencies": { - "objj-parser": ">=0.4.0", - "source-map": "0.4.x" - }, - "bin": { - "objjc": "bin/objjc" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/objj-transpiler/node_modules/source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readline-history": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/readline-history/-/readline-history-1.2.0.tgz", - "integrity": "sha1-9nBUOyzpASFH/pkD+D0cGJwX0zM=" - }, - "node_modules/require-self": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/require-self/-/require-self-0.2.3.tgz", - "integrity": "sha512-keGBWkK0PWJGFAd6IznpjM5zZzySbsrvzq0ElXpZ4G8hzymV9I+/OnC916MF5mRxHRWSZKGIyCFJ73BZFz3xaA==", - "dev": true, - "bin": { - "require-self": "bin/require-self" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", - "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", - "dev": true, - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", - "engines": { - "node": ">=0.4.0" - } - } - }, - "dependencies": { - "@objj/cappuccino": { - "version": "file:", - "requires": { - "@objj/cappuccino": "file:", - "@objj/jake": "latest", - "@objj/runtime": "latest", - "require-self": "0.2.3", - "terser": "^5.7.0" - }, - "dependencies": { - "@objj/jake": { - "version": "1.0.3-12", - "resolved": "https://registry.npmjs.org/@objj/jake/-/jake-1.0.3-12.tgz", - "integrity": "sha512-4aBAe39lLjSBLkE3FLV5IAFsYSVBCz8a8EFaM6vD+nORQutpz9mHYspfvHja6oVkDqc+r7PzE1aJ5+6MuYNBoQ==", - "requires": { - "@objj/runtime": "latest", - "glob": "^7.1.7", - "minimatch": "^3.0.4" - } - }, - "@objj/runtime": { - "version": "0.4.7-11", - "resolved": "https://registry.npmjs.org/@objj/runtime/-/runtime-0.4.7-11.tgz", - "integrity": "sha512-ZCludZuRcY2oFQhNfrUuKteycxA0gtxjdYfCAcT3azF9Rx4kvRLcHojXMp6JY8Gx9NDsrHVqCJRo9v0geHM2aQ==", - "requires": { - "@objj/utils": "latest", - "objj-transpiler": "^0.5.0", - "readline-history": ">=1.2.0", - "uuid": "^8.3.2", - "xmldom": "^0.6.0", - "xmlhttprequest-ssl": ">=1.6.2" - } - }, - "@objj/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@objj/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-HE/TM8nQCH0Vpqip4FIPXaxqVOJnI1+VHKR8EybW9gR2Fyj+DHzCnoYuZGT4bhuX/8Y6/EkauQmA4MYevNQOPw==", - "requires": { - "glob": "7.1.7", - "minimatch": "3.0.4" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "objj-parser": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/objj-parser/-/objj-parser-0.4.0.tgz", - "integrity": "sha512-Kw6tbMp4K+lLm1jdKpcrgLu8MZg3JY1sSi4kzOncIO8nM5uzyLYY2xwwpsLdqxaipfB1n8Gr1EnscdKOcLJ80A==" - }, - "objj-transpiler": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/objj-transpiler/-/objj-transpiler-0.5.1.tgz", - "integrity": "sha512-KSIjnKJZcQ3HExF5zUjRNNtm+zfmbzfEF8es2H2xBu7b2hPEdP+bpOuZCb65+f+To/Ei+E90b+UsdKcsjwyG+w==", - "requires": { - "objj-parser": ">=0.4.0", - "source-map": "0.4.x" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "readline-history": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/readline-history/-/readline-history-1.2.0.tgz", - "integrity": "sha1-9nBUOyzpASFH/pkD+D0cGJwX0zM=" - }, - "require-self": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/require-self/-/require-self-0.2.3.tgz", - "integrity": "sha512-keGBWkK0PWJGFAd6IznpjM5zZzySbsrvzq0ElXpZ4G8hzymV9I+/OnC916MF5mRxHRWSZKGIyCFJ73BZFz3xaA==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "terser": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", - "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==" - }, - "xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" - } - } - }, - "@objj/jake": { - "version": "1.0.3-12", - "resolved": "https://registry.npmjs.org/@objj/jake/-/jake-1.0.3-12.tgz", - "integrity": "sha512-4aBAe39lLjSBLkE3FLV5IAFsYSVBCz8a8EFaM6vD+nORQutpz9mHYspfvHja6oVkDqc+r7PzE1aJ5+6MuYNBoQ==", - "requires": { - "@objj/runtime": "latest", - "glob": "^7.1.7", - "minimatch": "^3.0.4" - } - }, - "@objj/runtime": { - "version": "0.4.7-11", - "resolved": "https://registry.npmjs.org/@objj/runtime/-/runtime-0.4.7-11.tgz", - "integrity": "sha512-ZCludZuRcY2oFQhNfrUuKteycxA0gtxjdYfCAcT3azF9Rx4kvRLcHojXMp6JY8Gx9NDsrHVqCJRo9v0geHM2aQ==", - "requires": { - "@objj/utils": "latest", - "objj-transpiler": "^0.5.0", - "readline-history": ">=1.2.0", - "uuid": "^8.3.2", - "xmldom": "^0.6.0", - "xmlhttprequest-ssl": ">=1.6.2" - } - }, - "@objj/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@objj/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-HE/TM8nQCH0Vpqip4FIPXaxqVOJnI1+VHKR8EybW9gR2Fyj+DHzCnoYuZGT4bhuX/8Y6/EkauQmA4MYevNQOPw==", - "requires": { - "glob": "7.1.7", - "minimatch": "3.0.4" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "objj-parser": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/objj-parser/-/objj-parser-0.4.0.tgz", - "integrity": "sha512-Kw6tbMp4K+lLm1jdKpcrgLu8MZg3JY1sSi4kzOncIO8nM5uzyLYY2xwwpsLdqxaipfB1n8Gr1EnscdKOcLJ80A==" - }, - "objj-transpiler": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/objj-transpiler/-/objj-transpiler-0.5.1.tgz", - "integrity": "sha512-KSIjnKJZcQ3HExF5zUjRNNtm+zfmbzfEF8es2H2xBu7b2hPEdP+bpOuZCb65+f+To/Ei+E90b+UsdKcsjwyG+w==", - "requires": { - "objj-parser": ">=0.4.0", - "source-map": "0.4.x" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "readline-history": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/readline-history/-/readline-history-1.2.0.tgz", - "integrity": "sha1-9nBUOyzpASFH/pkD+D0cGJwX0zM=" - }, - "require-self": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/require-self/-/require-self-0.2.3.tgz", - "integrity": "sha512-keGBWkK0PWJGFAd6IznpjM5zZzySbsrvzq0ElXpZ4G8hzymV9I+/OnC916MF5mRxHRWSZKGIyCFJ73BZFz3xaA==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "terser": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", - "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==" - }, - "xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" - } - } -}