remix-ide
Version:
Minimalistic browser-based Solidity IDE
1,300 lines (1,162 loc) • 10.8 MB
JavaScript
(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;