UNPKG

remix-ide

Version:

Minimalistic browser-based Solidity IDE

1,300 lines (1,162 loc) 10.8 MB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); const index_1 = require("./parsers/index"); const index_2 = require("./resolvers/index"); __export(require("./resolverengine")); __export(require("./utils")); exports.resolvers = { UriResolver: index_2.UriResolver, }; exports.parsers = { UrlParser: index_1.UrlParser, }; },{"./parsers/index":2,"./resolverengine":4,"./resolvers/index":5,"./utils":7}],2:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./urlparser")); },{"./urlparser":3}],3:[function(require,module,exports){ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const request_1 = __importDefault(require("request")); const debug = debug_1.default("resolverengine:urlparser"); function UrlParser() { return (url) => new Promise((resolve, reject) => { try { new URL(url); } catch (err) { // Not an actual browser url, might be filesystem return resolve(null); } request_1.default(url, (err, response, body) => { if (err) { return reject(err); } if (response.statusCode >= 200 && response.statusCode <= 299) { return resolve(body); } else { debug(`Got error: ${response.statusCode} ${response.statusMessage}`); return resolve(null); } }); }); } exports.UrlParser = UrlParser; },{"debug":540,"request":1379}],4:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const utils_1 = require("./utils"); const debug = debug_1.default("resolverengine:main"); const UNKNOWN_RESOLVER = "unknown"; class ResolverEngine { constructor(options) { this.resolvers = []; this.parsers = []; const opts = Object.assign({}, options); if (opts.debug) { debug_1.default.enable("resolverengine:*"); } } // Takes a simplified name (URI) and converts into cannonical URL of the location resolve(uri, workingDir) { return __awaiter(this, void 0, void 0, function* () { debug(`Resolving "${uri}"`); const ctx = { cwd: workingDir, resolver: UNKNOWN_RESOLVER, }; const result = yield utils_1.firstResult(this.resolvers, resolver => resolver(uri, ctx)); if (result === null) { throw resolverError(uri); } debug(`Resolved "${uri}" into "${result}"`); return result.result; }); } require(uri, workingDir) { return __awaiter(this, void 0, void 0, function* () { debug(`Requiring "${uri}"`); const ctx = { resolver: UNKNOWN_RESOLVER, cwd: workingDir, }; const url = yield utils_1.firstResult(this.resolvers, resolver => resolver(uri, ctx)); if (url === null) { throw resolverError(uri); } // Through the context we extract information about execution details like the resolver that actually succeeded const resolver = this.resolvers[url.index]; const name = typeof resolver === "function" ? resolver.name : resolver.toString(); ctx.resolver = name; const result = yield utils_1.firstResult(this.parsers, parser => parser(url.result, ctx)); if (result === null) { throw parserError(uri); } return result.result; }); } addResolver(resolver) { this.resolvers.push(resolver); return this; } addParser(parser) { this.parsers.push(parser); return this; } } exports.ResolverEngine = ResolverEngine; const resolverError = (uri) => new Error(`None of the sub-resolvers resolved "${uri}" location.`); const parserError = (uri) => new Error(`None of the sub-parsers resolved "${uri}" into data. Please confirm your configuration.`); },{"./utils":7,"debug":540}],5:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./uriresolver")); },{"./uriresolver":6}],6:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); function UriResolver() { // TODO: make a resolver that actually checks if something is a valid http link return function http(uri, ctx) { return __awaiter(this, void 0, void 0, function* () { try { return new URL(uri).href; } catch (_a) { return null; } }); }; } exports.UriResolver = UriResolver; },{}],7:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); function firstResult(things, check, ctx) { return __awaiter(this, void 0, void 0, function* () { for (let index = 0; index < things.length; index++) { const result = yield check(things[index]); if (result) { return { result, index }; } } return null; }); } exports.firstResult = firstResult; },{}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@resolver-engine/core"); const importparser_1 = require("./parsers/importparser"); const githubresolver_1 = require("./resolvers/githubresolver"); const ipfsresolver_1 = require("./resolvers/ipfsresolver"); const swarmresolver_1 = require("./resolvers/swarmresolver"); function ImportsEngine() { return (new core_1.ResolverEngine() //.addResolver(FsResolver()) //.addResolver(EthPmResolver()) //.addResolver(NodeResolver()) .addResolver(githubresolver_1.GithubResolver()) .addResolver(swarmresolver_1.SwarmResolver()) .addResolver(ipfsresolver_1.IPFSResolver()) .addResolver(core_1.resolvers.UriResolver()) .addParser(importparser_1.ImportParser([core_1.parsers.UrlParser()]))); } exports.ImportsEngine = ImportsEngine; },{"./parsers/importparser":10,"./resolvers/githubresolver":11,"./resolvers/ipfsresolver":12,"./resolvers/swarmresolver":13,"@resolver-engine/core":1}],9:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); var importsengine_1 = require("./importsengine"); exports.ImportsEngine = importsengine_1.ImportsEngine; __export(require("./utils")); const core_1 = require("@resolver-engine/core"); const importparser_1 = require("./parsers/importparser"); const githubresolver_1 = require("./resolvers/githubresolver"); const ipfsresolver_1 = require("./resolvers/ipfsresolver"); const swarmresolver_1 = require("./resolvers/swarmresolver"); exports.resolvers = { GithubResolver: githubresolver_1.GithubResolver, IPFSResolver: ipfsresolver_1.IPFSResolver, SwarmResolver: swarmresolver_1.SwarmResolver, UriResolver: core_1.resolvers.UriResolver, }; exports.parsers = { ImportParser: importparser_1.ImportParser, UrlParser: core_1.parsers.UrlParser, }; },{"./importsengine":8,"./parsers/importparser":10,"./resolvers/githubresolver":11,"./resolvers/ipfsresolver":12,"./resolvers/swarmresolver":13,"./utils":14,"@resolver-engine/core":1}],10:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@resolver-engine/core"); const debug_1 = __importDefault(require("debug")); const debug = debug_1.default("resolverengine:importparser"); function ImportParser(sourceParsers) { return (url, ctx) => __awaiter(this, void 0, void 0, function* () { const source = yield core_1.firstResult(sourceParsers, parser => parser(url, ctx)); if (!source) { debug(`Can't find source for ${url}`); return null; } const provider = ctx.resolver; return { url, source: source.result, provider, }; }); } exports.ImportParser = ImportParser; },{"@resolver-engine/core":1,"debug":540}],11:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const hosted_git_info_1 = __importDefault(require("hosted-git-info")); const debug = debug_1.default("resolverengine:githubresolver"); // hosted-git-info is a godsend, but it doesn't support specific files // 1st group - protocol, location, owner, repo // 2nd group - file inside repo // 3rd group - commitish const GIT_HOSTED_INFO = /^((?:.+:\/\/)?[^:/]+[/:][^/]+[/][^/]+)[/](.+?)(#.+)?$/; // 1. (owner), 2. (repo), 3. (commit/file) const BROWSER_LINK = /^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/blob\/((?:[^/]+[/])*[^/]+)$/; // 1. (owner), 2. (repo), 3. (file); AFAIK no support for commits const REMIX_GITHUB_LINK = /^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/((?:[^/]+[/])*[^/]+)$/; // TODO(ritave): Support private repositories function GithubResolver() { return function github(what, ctx) { return __awaiter(this, void 0, void 0, function* () { const fileMatchLink = what.match(BROWSER_LINK); if (fileMatchLink) { const [, owner, repo, commitAndFile] = fileMatchLink; const gitRawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${commitAndFile}`; debug("Resolved uri to:", gitRawUrl); return gitRawUrl; } const fileMatchRemix = what.match(REMIX_GITHUB_LINK); if (fileMatchRemix) { const [, owner, repo, file] = fileMatchRemix; const gitRawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/master/${file}`; debug("Resolved uri to:", gitRawUrl); return gitRawUrl; } const fileMatchGitHostedInfo = what.match(GIT_HOSTED_INFO); if (fileMatchGitHostedInfo) { const [, url, file, comittish] = fileMatchGitHostedInfo; const gitInfo = hosted_git_info_1.default.fromUrl(url + (comittish || "")); if (!gitInfo) { return null; } const fileUrl = gitInfo.file(file); debug("Resolved uri to:", fileUrl); return fileUrl; } return null; }); }; } exports.GithubResolver = GithubResolver; },{"debug":540,"hosted-git-info":797}],12:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); // 1. (root / path to resource) const IPFS_URI = /^ipfs:\/\/(.+)$/; function IPFSResolver() { return function ipfs(uri, ctx) { return __awaiter(this, void 0, void 0, function* () { const ipfsMatch = uri.match(IPFS_URI); if (ipfsMatch) { const [, resourcePath] = ipfsMatch; const url = "https://gateway.ipfs.io/ipfs/" + resourcePath; return url; } return null; }); }; } exports.IPFSResolver = IPFSResolver; },{}],13:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); // 1. (hash) const SWARM_URI = /^bzz-raw:\/\/(\w+)/; const SWARM_GATEWAY = "https://swarm-gateways.net/bzz-raw:/"; function SwarmResolver() { return function swarm(uri, ctx) { return __awaiter(this, void 0, void 0, function* () { const swarmMatch = uri.match(SWARM_URI); if (swarmMatch) { const [, hash] = swarmMatch; return SWARM_GATEWAY + hash; } return null; }); }; } exports.SwarmResolver = SwarmResolver; },{}],14:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); function findImports(data) { let result = []; // regex below matches all possible import statements, namely: // - import "somefile"; // - import "somefile" as something; // - import something from "somefile" // (double that for single quotes) // and captures file names const regex = /import\s+(?:(?:"([^;]*)"|'([^;]*)')(?:;|\s+as\s+[^;]*;)|.+from\s+(?:"(.*)"|'(.*)');)/g; let match; while ((match = regex.exec(data.source))) { for (let i = 1; i < match.length; i++) { if (match[i] !== undefined) { result.push(match[i]); break; } } } return result; } exports.findImports = findImports; /** * This function accepts root files to be searched for and resolves the sources, finds the imports in each source and traverses the whole dependency tree gathering absolute and uri paths * @param roots * @param workingDir * @param resolver */ function gatherDepenencyTree(roots, workingDir, resolver) { return __awaiter(this, void 0, void 0, function* () { let result = []; let alreadyImported = new Set(); /** * This function traverses the depedency tree and calculates absolute paths for each import on the way storing each file in in a global array * @param file File in a depedency that should now be traversed * @returns An absolute path for the requested file */ function dfs(file) { return __awaiter(this, void 0, void 0, function* () { const url = yield resolver.resolve(file.uri, file.searchCwd); if (alreadyImported.has(url)) { return url; } const resolvedFile = yield resolver.require(file.uri, file.searchCwd); alreadyImported.add(url); const foundImportURIs = findImports(resolvedFile); const fileNode = Object.assign({ uri: file.uri, imports: [] }, resolvedFile); const resolvedCwd = path_1.default.dirname(url); for (const importUri of foundImportURIs) { const importUrl = yield dfs({ searchCwd: resolvedCwd, uri: importUri }); fileNode.imports.push({ uri: importUri, url: importUrl }); } result.push(fileNode); return resolvedFile.url; }); } yield Promise.all(roots.map(what => dfs({ searchCwd: workingDir, uri: what }))); return result; }); } function stripNodes(nodes) { return nodes.map(node => { return { url: node.url, source: node.source, provider: node.provider }; }); } /** * Starts with roots and traverses the whole depedency tree of imports, returning an array of sources * @param roots * @param workingDir What's the starting working dir for resolving relative imports in roots * @param resolver */ function gatherSources(roots, workingDir, resolver) { return __awaiter(this, void 0, void 0, function* () { let result = []; let queue = []; let alreadyImported = new Set(); const absoluteRoots = roots.map(what => path_1.default.join(workingDir, what)); for (const absWhat of absoluteRoots) { queue.push({ cwd: workingDir, file: absWhat, relativeTo: workingDir }); alreadyImported.add(absWhat); } while (queue.length > 0) { const fileData = queue.shift(); const resolvedFile = yield resolver.require(fileData.file, fileData.cwd); const foundImports = findImports(resolvedFile); // if imported path starts with '.' we assume it's relative and return it's // path relative to resolved name of the file that imported it // if not - return the same name it was imported with let relativePath; if (fileData.file[0] === ".") { relativePath = path_1.default.join(fileData.relativeTo, fileData.file); result.push({ url: relativePath, source: resolvedFile.source, provider: resolvedFile.provider }); } else { relativePath = fileData.file; result.push({ url: relativePath, source: resolvedFile.source, provider: resolvedFile.provider }); } const fileParentDir = path_1.default.dirname(resolvedFile.url); for (const i in foundImports) { let importName; if (i[0] === ".") { importName = path_1.default.join(relativePath, i); } else { importName = foundImports[i]; } if (!alreadyImported.has(importName)) { alreadyImported.add(importName); queue.push({ cwd: fileParentDir, file: foundImports[i], relativeTo: path_1.default.dirname(relativePath) }); } } } return result; }); } exports.gatherSources = gatherSources; /** * This function gathers sources and **REWRITES IMPORTS** inside the source files into resolved, absolute paths instead of using shortcut forms * Because the remapping api in solc is not compatible with multiple existing projects and frameworks, changing relative paths to absolute paths * makes us avoid any need for finding imports after starting the solc compilation * @param roots * @param workingDir What's the starting working dir for resolving relative imports in roots * @param resolver */ function gatherSourcesAndCanonizeImports(roots, workingDir, resolver) { return __awaiter(this, void 0, void 0, function* () { function canonizeFile(file) { file.imports.forEach(i => (file.source = file.source.replace(i.uri, i.url))); } let sources = yield gatherDepenencyTree(roots, workingDir, resolver); sources.forEach(canonizeFile); return stripNodes(sources); }); } exports.gatherSourcesAndCanonizeImports = gatherSourcesAndCanonizeImports; },{"path":1013}],15:[function(require,module,exports){ (function (process){ /* Copyright (c) 2017 Rod Vagg, MIT License */ function AbstractChainedBatch (db) { this._db = db this._operations = [] this._written = false } AbstractChainedBatch.prototype._serializeKey = function (key) { return this._db._serializeKey(key) } AbstractChainedBatch.prototype._serializeValue = function (value) { return this._db._serializeValue(value) } AbstractChainedBatch.prototype._checkWritten = function () { if (this._written) throw new Error('write() already called on this batch') } AbstractChainedBatch.prototype.put = function (key, value) { this._checkWritten() var err = this._db._checkKey(key, 'key', this._db._isBuffer) if (err) throw err key = this._serializeKey(key) value = this._serializeValue(value) if (typeof this._put == 'function' ) this._put(key, value) else this._operations.push({ type: 'put', key: key, value: value }) return this } AbstractChainedBatch.prototype.del = function (key) { this._checkWritten() var err = this._db._checkKey(key, 'key', this._db._isBuffer) if (err) throw err key = this._serializeKey(key) if (typeof this._del == 'function' ) this._del(key) else this._operations.push({ type: 'del', key: key }) return this } AbstractChainedBatch.prototype.clear = function () { this._checkWritten() this._operations = [] if (typeof this._clear == 'function' ) this._clear() return this } AbstractChainedBatch.prototype.write = function (options, callback) { this._checkWritten() if (typeof options == 'function') callback = options if (typeof callback != 'function') throw new Error('write() requires a callback argument') if (typeof options != 'object') options = {} this._written = true if (typeof this._write == 'function' ) return this._write(callback) if (typeof this._db._batch == 'function') return this._db._batch(this._operations, options, callback) process.nextTick(callback) } module.exports = AbstractChainedBatch }).call(this,require('_process')) },{"_process":125}],16:[function(require,module,exports){ (function (process){ /* Copyright (c) 2017 Rod Vagg, MIT License */ function AbstractIterator (db) { this.db = db this._ended = false this._nexting = false } AbstractIterator.prototype.next = function (callback) { var self = this if (typeof callback != 'function') throw new Error('next() requires a callback argument') if (self._ended) return callback(new Error('cannot call next() after end()')) if (self._nexting) return callback(new Error('cannot call next() before previous next() has completed')) self._nexting = true if (typeof self._next == 'function') { return self._next(function () { self._nexting = false callback.apply(null, arguments) }) } process.nextTick(function () { self._nexting = false callback() }) } AbstractIterator.prototype.end = function (callback) { if (typeof callback != 'function') throw new Error('end() requires a callback argument') if (this._ended) return callback(new Error('end() already called on iterator')) this._ended = true if (typeof this._end == 'function') return this._end(callback) process.nextTick(callback) } module.exports = AbstractIterator }).call(this,require('_process')) },{"_process":125}],17:[function(require,module,exports){ (function (Buffer,process){ /* Copyright (c) 2017 Rod Vagg, MIT License */ var xtend = require('xtend') , AbstractIterator = require('./abstract-iterator') , AbstractChainedBatch = require('./abstract-chained-batch') function AbstractLevelDOWN (location) { if (!arguments.length || location === undefined) throw new Error('constructor requires at least a location argument') if (typeof location != 'string') throw new Error('constructor requires a location string argument') this.location = location this.status = 'new' } AbstractLevelDOWN.prototype.open = function (options, callback) { var self = this , oldStatus = this.status if (typeof options == 'function') callback = options if (typeof callback != 'function') throw new Error('open() requires a callback argument') if (typeof options != 'object') options = {} options.createIfMissing = options.createIfMissing != false options.errorIfExists = !!options.errorIfExists if (typeof this._open == 'function') { this.status = 'opening' this._open(options, function (err) { if (err) { self.status = oldStatus return callback(err) } self.status = 'open' callback() }) } else { this.status = 'open' process.nextTick(callback) } } AbstractLevelDOWN.prototype.close = function (callback) { var self = this , oldStatus = this.status if (typeof callback != 'function') throw new Error('close() requires a callback argument') if (typeof this._close == 'function') { this.status = 'closing' this._close(function (err) { if (err) { self.status = oldStatus return callback(err) } self.status = 'closed' callback() }) } else { this.status = 'closed' process.nextTick(callback) } } AbstractLevelDOWN.prototype.get = function (key, options, callback) { var err if (typeof options == 'function') callback = options if (typeof callback != 'function') throw new Error('get() requires a callback argument') if (err = this._checkKey(key, 'key')) return callback(err) key = this._serializeKey(key) if (typeof options != 'object') options = {} options.asBuffer = options.asBuffer != false if (typeof this._get == 'function') return this._get(key, options, callback) process.nextTick(function () { callback(new Error('NotFound')) }) } AbstractLevelDOWN.prototype.put = function (key, value, options, callback) { var err if (typeof options == 'function') callback = options if (typeof callback != 'function') throw new Error('put() requires a callback argument') if (err = this._checkKey(key, 'key')) return callback(err) key = this._serializeKey(key) value = this._serializeValue(value) if (typeof options != 'object') options = {} if (typeof this._put == 'function') return this._put(key, value, options, callback) process.nextTick(callback) } AbstractLevelDOWN.prototype.del = function (key, options, callback) { var err if (typeof options == 'function') callback = options if (typeof callback != 'function') throw new Error('del() requires a callback argument') if (err = this._checkKey(key, 'key')) return callback(err) key = this._serializeKey(key) if (typeof options != 'object') options = {} if (typeof this._del == 'function') return this._del(key, options, callback) process.nextTick(callback) } AbstractLevelDOWN.prototype.batch = function (array, options, callback) { if (!arguments.length) return this._chainedBatch() if (typeof options == 'function') callback = options if (typeof array == 'function') callback = array if (typeof callback != 'function') throw new Error('batch(array) requires a callback argument') if (!Array.isArray(array)) return callback(new Error('batch(array) requires an array argument')) if (!options || typeof options != 'object') options = {} var i = 0 , l = array.length , e , err for (; i < l; i++) { e = array[i] if (typeof e != 'object') continue if (err = this._checkKey(e.type, 'type')) return callback(err) if (err = this._checkKey(e.key, 'key')) return callback(err) } if (typeof this._batch == 'function') return this._batch(array, options, callback) process.nextTick(callback) } //TODO: remove from here, not a necessary primitive AbstractLevelDOWN.prototype.approximateSize = function (start, end, callback) { if ( start == null || end == null || typeof start == 'function' || typeof end == 'function') { throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments') } if (typeof callback != 'function') throw new Error('approximateSize() requires a callback argument') start = this._serializeKey(start) end = this._serializeKey(end) if (typeof this._approximateSize == 'function') return this._approximateSize(start, end, callback) process.nextTick(function () { callback(null, 0) }) } AbstractLevelDOWN.prototype._setupIteratorOptions = function (options) { var self = this options = xtend(options) ;[ 'start', 'end', 'gt', 'gte', 'lt', 'lte' ].forEach(function (o) { if (options[o] && self._isBuffer(options[o]) && options[o].length === 0) delete options[o] }) options.reverse = !!options.reverse options.keys = options.keys != false options.values = options.values != false options.limit = 'limit' in options ? options.limit : -1 options.keyAsBuffer = options.keyAsBuffer != false options.valueAsBuffer = options.valueAsBuffer != false return options } AbstractLevelDOWN.prototype.iterator = function (options) { if (typeof options != 'object') options = {} options = this._setupIteratorOptions(options) if (typeof this._iterator == 'function') return this._iterator(options) return new AbstractIterator(this) } AbstractLevelDOWN.prototype._chainedBatch = function () { return new AbstractChainedBatch(this) } AbstractLevelDOWN.prototype._isBuffer = function (obj) { return Buffer.isBuffer(obj) } AbstractLevelDOWN.prototype._serializeKey = function (key) { return this._isBuffer(key) ? key : String(key) } AbstractLevelDOWN.prototype._serializeValue = function (value) { if (value == null) return '' return this._isBuffer(value) || process.browser ? value : String(value) } AbstractLevelDOWN.prototype._checkKey = function (obj, type) { if (obj === null || obj === undefined) return new Error(type + ' cannot be `null` or `undefined`') if (this._isBuffer(obj) && obj.length === 0) return new Error(type + ' cannot be an empty Buffer') else if (String(obj) === '') return new Error(type + ' cannot be an empty String') } module.exports = AbstractLevelDOWN }).call(this,{"isBuffer":require("../is-buffer/index.js")},require('_process')) },{"../is-buffer/index.js":820,"./abstract-chained-batch":15,"./abstract-iterator":16,"_process":125,"xtend":1631}],18:[function(require,module,exports){ exports.AbstractLevelDOWN = require('./abstract-leveldown') exports.AbstractIterator = require('./abstract-iterator') exports.AbstractChainedBatch = require('./abstract-chained-batch') exports.isLevelDOWN = require('./is-leveldown') },{"./abstract-chained-batch":15,"./abstract-iterator":16,"./abstract-leveldown":17,"./is-leveldown":19}],19:[function(require,module,exports){ var AbstractLevelDOWN = require('./abstract-leveldown') function isLevelDOWN (db) { if (!db || typeof db !== 'object') return false return Object.keys(AbstractLevelDOWN.prototype).filter(function (name) { // TODO remove approximateSize check when method is gone return name[0] != '_' && name != 'approximateSize' }).every(function (name) { return typeof db[name] == 'function' }) } module.exports = isLevelDOWN },{"./abstract-leveldown":17}],20:[function(require,module,exports){ ace.define("ace/mode/solidity_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"], function(acequire, exports, module) { "use strict"; var oop = acequire("../lib/oop"); var deepCopy = acequire("../lib/lang").deepCopy; var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules; var SolidityHighlightRules = function(options) { var intTypes = 'byte|int|uint'; for (var width = 8; width <= 256; width += 8) { intTypes += '|bytes' + (width / 8) + '|uint' + width + '|int' + width; } var mainKeywordsByType = { "variable.language": "this|super", "keyword": "as|emit|from|import|returns", "keyword.control": "break|continue|do|else|for|if|return|while", "keyword.control.deprecated": "throw", "keyword.operator": "delete|new", "keyword.other.reserved": // see https://solidity.readthedocs.io/en/develop/miscellaneous.html#reserved-keywords "abstract|after|alias|apply|auto|case|catch|copyof|default|" + "define|final|immutable|implements|in|inline|let|macro|match|" + "mutable|null|of|override|partial|promise|reference|relocatable|" + "sealed|sizeof|static|supports|switch|try|type|typedef|typeof|" + "unchecked", "storage.type": "contract|library|interface|function|constructor|event|modifier|" + "struct|mapping|enum|" + "var|bool|address|" + intTypes, "storage.type.array.dynamic": "bytes|string", "storage.modifier.inheritance": "is", "storage.modifier.storagelocation": "storage|memory|calldata", "storage.modifier.statemutability": "constant|payable|pure|view", "storage.modifier.visibility": "private|public|external|internal", "storage.modifier.event": "anonymous|indexed", "support.function": "addmod|assert|blockhash|ecrecover|gasleft|keccak256|mulmod|" + "require|revert|ripemd160|selfdestruct|sha256", "support.function.deprecated": "sha3|suicide", "support.variable": "now", "constant.language.boolean": "true|false", "constant.numeric.other.unit.currency": "wei|szabo|finney|ether", "constant.numeric.other.unit.time": "seconds|minutes|hours|days|weeks", "constant.numeric.other.unit.time.deprecated": "years" } var mainKeywordMapper = this.createKeywordMapper(mainKeywordsByType, "identifier"); var hasSeenFirstFunctionArgumentKeyword = false; var functionArgumentsKeywordMapper = function functionArgumentsKeywordMapper(value) { var mainKeywordToken = mainKeywordMapper(value); if ( hasSeenFirstFunctionArgumentKeyword && ("identifier" == mainKeywordToken) ) { mainKeywordToken = "variable.parameter"; } hasSeenFirstFunctionArgumentKeyword = true; return mainKeywordToken; }; var identifierRe = "[a-zA-Z_$][a-zA-Z_$0-9]*\\b|\\$"; // Single "$" can't have a word boundary since it's not a word char. var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex "u[0-9a-fA-F]{4}|" + // unicode ".)"; // stuff like "\r" "\n" "\t" etc. var commentWipMarkerRule = function commentWipMarkerRule(commentType) { return { token : "comment." + commentType + ".doc.documentation.tag.storage.type", regex : "\\b(?:TODO|FIXME|XXX|HACK)\\b" } }; var natSpecRule = function natSpecRule(commentType) { return { token : "comment." + commentType + ".doc.documentation.tag", regex : "\\B@(?:author|dev|notice|param|return|title)\\b" } }; var pushFunctionArgumentsState = function(currentState, stack) { if (currentState != "start" || stack.length) stack.unshift("function_arguments", currentState); hasSeenFirstFunctionArgumentKeyword = false; return "function_arguments"; }; this.$rules = { "start" : [ { token : "comment.block.doc.documentation", // doc comment regex : "\\/\\*(?=\\*)", push : "doc_comment" }, { token : "comment.line.triple-slash.double-slash.doc.documentation", // triple slash "NatSpec" doc comment regex : "\\/\\/\\/", push : "doc_line_comment" }, { token : "comment.block", // multi line comment regex : "\\/\\*", push : "comment" }, { token : "comment.line.double-slash", regex : "\\/\\/", push : "line_comment" }, { token : "text", regex : "\\s+|^$" }, { token : "string.quoted.single", regex : "'(?=.)", push : "qstring" }, { token : "string.quoted.double", regex : '"(?=.)', push : "qqstring" }, { token : "storage.type.reserved", // TODO really "reserved"? Compiler 0.4.24 says "UnimplementedFeatureError: Not yet implemented - FixedPointType." regex : "u?fixed(?:" + "8x[0-8]|" + // Docs say 0-80 for the fractional part. It's unclear whether 0-80 bits or 0-80 decimal places. "16x(?:1[0-6]|[0-9])|" + // Longest match has to be first alternative. "24x(?:2[0-4]|1[0-9]|[0-9])|" + "32x(?:3[0-2]|[1-2][0-9]|[0-9])|" + "40x(?:40|[1-3][0-9]|[0-9])|" + "48x(?:4[0-8]|[1-3][0-9]|[0-9])|" + "56x(?:5[0-6]|[1-4][0-9]|[0-9])|" + "64x(?:6[0-4]|[1-5][0-9]|[0-9])|" + "72x(?:7[0-2]|[1-6][0-9]|[0-9])|" + "(?:80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)x(?:80|[1-7][0-9]|[0-9])" + ")?", inheritingStateRuleId : "fixedNumberType" }, { token : "keyword.control", // PlaceholderStatement in ModifierDefinition regex : /\b_\b/ }, { token : [ // HexLiteral "string.other.hex", "string.other.hex", "string.other.hex", "string.other.hex", "string.other.hex" ], regex : /(\b)(hex)(['"])((?:[0-9a-fA-F]{2})*)(\3)/ }, { token : "constant.numeric.hex", // hex regex : /0[xX][0-9a-fA-F]+\b/ }, { token : "constant.numeric", // float regex : /[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/ }, { token : ["keyword", "text", "keyword", "text", "constant.other"], regex : "(pragma)(\\s+)(solidity|experimental)(\\s+)([^;]+)" }, { token : ["keyword", "text", "identifier", "text", "keyword", "text", "identifier"], // UsingForDeclaration regex : "(using)(\\s+)(" + identifierRe + ")(\\s+)(for)(\\s+)(" + identifierRe + "|\\*)" }, { token : "support.function.deprecated", // Not in keywordMapper because of ".". Longest match has to be first alternative. regex : /block\s*\.\s*blockhash|\.\s*callcode/ }, { token : "support.function", // Not in keywordMapper because of ".". Longest match has to be first alternative. regex : /abi\s*\.\s*(?:encodeWithSignature|encodeWithSelector|encodePacked|encode)|\.\s*(?:delegatecall|transfer|call|send)/ }, { token : "support.variable", // Not in keywordMapper because of ".". Longest match has to be first alternative. regex : /block\s*\.\s*(?:difficulty|timestamp|coinbase|gaslimit|number)|msg\s*\.\s*(?:sender|value|data)|tx\s*\.\s*(?:gasprice|origin)|\.\s*balance/ }, { token : "support.variable.deprecated", // Not in keywordMapper because of ".". Longest match has to be first alternative. regex : /msg\s*\.\s*gas/ }, { token : [ // FunctionDefinition "storage.type", "text", "entity.name.function", "text", "paren.lparen" ], regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()", next : pushFunctionArgumentsState }, { token : ["storage.type", "text", "paren.lparen"], // FunctionTypeName && fallback function definition regex : "(function)(\\s*)(\\()", next : pushFunctionArgumentsState }, { token : ["keyword", "text", "paren.lparen"], // "returns" clause regex : "(returns)(\\s*)(\\()", next : pushFunctionArgumentsState }, { token : mainKeywordMapper, regex : identifierRe, inheritingStateRuleId : "keywordMapper" }, { token : "keyword.operator", regex : /--|\*\*|\+\+|=>|<<|>>|<<=|>>=|&&|\|\||[!&|+\-*\/%~^<>=]=?/ }, { token : "punctuation.operator", regex : /[?:;]/ }, { token : "punctuation.operator", // keep "." and "," separate for easier cloning and modifying into "function_arguments" regex : /[.,]/, inheritingStateRuleId : "punctuation" }, { token : "paren.lparen", regex : /[\[{]/ }, { token : "paren.lparen", // keep "(" separate for easier cloning and modifying into "function_arguments" regex : /[(]/, inheritingStateRuleId : "lparen" }, { token : "paren.rparen", regex : /[\]}]/ }, { token : "paren.rparen", // keep ")" separate for easier cloning and modifying into "function_arguments" regex : /[)]/, inheritingStateRuleId : "rparen" } ], "comment" : [ commentWipMarkerRule("block"), { token : "comment.block", regex : "\\*\\/", next : "pop" }, { defaultToken : "comment.block", caseInsensitive : true } ], "line_comment" : [ commentWipMarkerRule("line"), { token : "comment.line.double-slash", regex : "$|^", next : "pop" }, { defaultToken : "comment.line.double-slash", caseInsensitive : true } ], "doc_comment" : [ commentWipMarkerRule("block"), natSpecRule("block"), { token : "comment.block.doc.documentation", // closing comment regex : "\\*\\/", next : "pop" }, { defaultToken : "comment.block.doc.documentation", caseInsensitive : true } ], "doc_line_comment" : [ commentWipMarkerRule("line"), natSpecRule("line"), { token : "comment.line.triple-slash.double-slash.doc.documentation", regex : "$|^", next : "pop" }, { defaultToken : "comment.line.triple-slash.double-slash.doc.documentation", caseInsensitive : true } ], "qqstring" : [ { token : "constant.language.escape", regex : escapedRe }, { token : "string.quoted.double", // Multi-line string by ending line with back-slash, i.e. escaping \n. regex : "\\\\$", next : "qqstring" }, { token : "string.quoted.double", regex : '"|$', next : "pop" }, { defaultToken : "string.quoted.double" } ], "qstring" : [ { token : "constant.language.escape", regex : escapedRe }, { token : "string.quoted.single", // Multi-line string by ending line with back-slash, i.e. escaping \n. regex : "\\\\$", next : "qstring" }, { token : "string.quoted.single", regex : "'|$", next : "pop" }, { defaultToken : "string.quoted.single" } ] }; var functionArgumentsRules = deepCopy(this.$rules["start"]); functionArgumentsRules.forEach(function(rule, ruleIndex) { if (rule.inheritingStateRuleId) { switch (rule.inheritingStateRuleId) { case "keywordMapper": rule.token = functionArgumentsKeywordMapper; break; case "punctuation": rule.onMatch = function onFunctionArgumentsPunctuationMatch(value, currentState, stack) { hasSeenFirstFunctionArgumentKeyword = false; return rule.token;