Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

238
static/js/ketcher2/node_modules/budo/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,238 @@
# 10.x
:tada:
#### Breaking Changes
- Upgraded to `browserify@14`
- The `--pushstate` boolean argument should now come *after* entries in the CLI, as it supports subarg options. Using it before entries will still work but may log a warning.
- Major overhaul to LiveReload backend to make it faster and more robust [#194](https://github.com/mattdesl/budo/issues/194)
- No longer uses `tiny-lr` or the old school LiveReload stuff, so it no longer supports some of the feature set from that tool
- No longer supports the LiveReload browser plugin
- Budo runs everything on a single port/server instead of a second server for LiveReload
- `/budo/livereload.js` now serves the LiveReload client
#### Other Changes
- `opts.staticOptions` is now passed onto `serve-static` module
- `opts.pushstate` (boolean or object) is now passed onto `connect-pushstate` module
- CLI now supports subarg syntax for commands like `--static-options` and `--pushstate`
- `defaultIndex` function now accepts a `req` as the second parameter
# 9.4.7
- Make HTTP logging more accurate: previously the time and byte size was not correct
# 9.4.5 .. 9.4.6
- Small tweaks to frontend build error styling
- Add `pushstate` flag as a boolean so it doesn't swallow entry
# 9.4.3
- Disable cache control for `serve-static`, I've found this greatly reduces load time
- Slight change to `package.json` scripts so they work on Windows
# 9.4.2
- Improve Windows terminal color support, fixes [#179](https://github.com/mattdesl/budo/issues/179)
# 9.4.0
- Improve build error parsing and rendering
# 9.3.0
- Add `force-default-index` to CLI [#188](https://github.com/mattdesl/budo/pull/188)
# 9.2.2
- Minimize XSS risks in URLs on 404 [#182](https://github.com/mattdesl/budo/pull/183)
# 9.2.0
- Improved `--cors` flag in middleware stack [#172](https://github.com/mattdesl/budo/pull/172)
# 9.1.0
- Support `browserify: { entries: [] }` in API options [#167](https://github.com/mattdesl/budo/pull/167)
- The `connect` event also returns a `server` instance, so you can use it with things like SocketIO
# 9.0.0
When `--ssl` is specified without a `--cert` and `--key` option, budo will use [pem](https://www.npmjs.com/package/pem) to generate a self-signed certificate. This is a breaking change from previous versions, but more convenient for most users.
Also updated docs with more SSL info.
# 8.4.0
Add `--base` flag for working with push state servers.
# 8.3.0
Bump to latest browserify.
# 8.2.2
Fix shorthand for `--serve` (`-s`).
# 8.2.0
Add support for SSL (HTTPS) with `--ssl`, `--cert` and `--key` options.
# 8.1.0
Add `--cors` flag to enable `Access-Control-Allow-Origin: *`
# 8.0.4
Bump required deps.
# 8.0.3
Fix `opts.live` as a string, allowing an array of options to be passed to filter file names.
# 8.0.2
Fix flow so that bundling events start after server connects, also updated upstream in watchify-middleware.
# 8.0.1
Fix parsing issue with LiveReload resp modifier.
# 8.0.0
The server code has been refactored to use connect/express-style middleware stacking. Fixes [#80](https://github.com/mattdesl/budo/issues/80), [#79](https://github.com/mattdesl/budo/issues/79), [#124](https://github.com/mattdesl/budo/issues/124), [#128](https://github.com/mattdesl/budo/issues/128).
##### Major Changes
Functions for `opts.middleware` now assumes the following signature, and will not behave differently based on the number of arguments you specify:
- `middleware(req, res, next)`
##### Minor Changes
The `middleware` options can now be an array of functions, or a single function.
# 7.1.0
Added `--watch-glob` option which allows you to override the default watch glob without having to go through the `live()` / `watch()` API
# 7.0.4
Small patch [#117](https://github.com/mattdesl/budo/pull/117) to fix a failing test in 7.0.3.
# 7.0.3
- Bole no longer double-logs on shut-down and re-start.
- Fixed issue with request sizes being logged incorrectly in terminal
# 7.0.1 .. 7.0.2
Small patches for [#110](https://github.com/mattdesl/budo/pull/110) and [#111](https://github.com/mattdesl/budo/pull/111).
# 7.0.0
Fixes previous patch and also updates to garnish redesign, leading to new log styles.
Since various ndjson flags have changed, this is a potentially breaking change.
Also added a `--verbose` / `-v` option like watchify, which adds some additional debug messages.
# 6.1.1
Fixes live reload for directory routes like `localhost:9966/mydir`.
# 6.1.0
Search for `index.html` across all static `--dir` folders, finding the first one.
# 6.0.0
##### Major Changes
- `garnish` is now included by default in CLI and API
- you can use `--ndjson` and `ndjson: true` to have raw output (for custom pretty-printers)
##### Minor Changes
- added `--title` option for the default HTML title
- added `--css` option for a default style sheet
# 5.0.0
##### Major Changes
- you can just type `budo . | garnish` for the entry point (or `index.js`)
- added `--onupdate` for things like linting, see [the docs](docs/command-line-usage.md#--onupdate)
- if no `--host` is specified, resolves to internal IP
- you can still hit `localhost:9966` and it will work
- the `<script>` src defaults to the *filename* of the first entry
- eg: `budo src/index.js` leads to `<script src="index.js">`
- browserify options must come after a full stop `--`
- except `--no-debug` which is passed as a budo option
- eg: `budo index.js --no-debug -- -t babelify`
- `--dir` can be passed multiple times to use multiple static folders
- `budo index.js --dir public --dir tmp`
- removed `--live-plugin` option to reduce code complexity
- might be added back into CLI later
- API still supports `budo.live({ plugin: true })`
- portfinding is enabled by default in API and CLI
- user can disbale with `--no-portfind` or `portfind: false`
- removed `--verbose`, `-v`, timing is logged by default now
- entry files are now optional (i.e. if you just need a static HTML with LiveReload)
- added `--open`, `-o` to launch browser on connect
- syntax errors in code are shown in the DOM body now
- can disable with `--no-error-handler`
- in API can use `errorHandler: Boolean|Function`
- added `--version` to CLI
- `--live` can optionally be a string to only LiveReload on those globs, eg:
- `budo index.js --live=*.{css,html}`
- removed `--ignore-watch` and `--interval`
- use `budo.watch(glob, chokidarOpts)` instead
- shorthand for most CLI options now exists
- arg parsing has improved and uses camel-case in API
- most args are now supported before entries, eg:
- `budo --live src/index.js`
- cleaner error messaging in terminal
##### API Changes
- `dir` can be a string or array of static paths
- the `'connect'` event now passes `livePort`
- the `'connect'` event `ev.host` now uses internal IP by default
- exposed a CLI feature
- `require('budo').cli(process.argv.slice(2), { overrides... })`
- `errorHandler` can be used for custom bundle error handling
- `middleware` can be a `fn(req, res, next)` function for custom routes
- `'update'` event now passes `(contents, updates)`
##### Browserify Args
Users creating CLI tools on top of budo can use `opt.browserifyArgs` to handle subarg correctly. Example with minimist:
```js
var args = process.argv.slice(2)
var opts = require('minimist')(args, { '--': true })
budo.cli(args, {
browserifyArgs: opts['--']
})
```
If no `browserifyArgs` is specified, then `opt.browserify` can be used to send the actual JS object to the browserify constructor.
```js
budo.cli(args, {
browserify: {
transform: require('babelify')
}
})
```
# 4.2.0
- Added `--pushstate` option [#53](https://github.com/mattdesl/budo/pull/53)
# 4.1.0
- Fixed a bug with `budo ./foo.js`

21
static/js/ketcher2/node_modules/budo/LICENSE.md generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Matt DesLauriers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.

166
static/js/ketcher2/node_modules/budo/README.md generated vendored Normal file
View File

@ -0,0 +1,166 @@
# budō
[![build status][travis-image]][travis-url]
[![stability][stability-image]][stability-url]
[![NPM version][npm-image]][npm-url]
[![Downloads][downloads-image]][downloads-url]
[![js-standard-style][standard-image]][standard-url]
This is a [browserify](https://github.com/substack/node-browserify) development server focused on incremental reloading, LiveReload integration (including CSS injection) and other high-level features for rapid prototyping.
To install it globally:
```sh
npm install budo -g
```
Running budo will start a server with a default `index.html` and incrementally bundle your source on filesave. The requests are delayed until the bundle has finished, so you won't be served stale or empty bundles if you refresh the page mid-update. Examples:
```sh
# serve file on port 9966 and open browser
budo index.js --open
# enable LiveReload on HTML/CSS/JS file changes
budo index.js --live
# default html will use src="static/bundle.js"
budo src/index.js:static/bundle.js
# pass some options to browserify
budo index.js --live -- -t babelify
# use HTTPS and enable CORS headers
budo index.js --ssl --cors
```
Then open [http://localhost:9966/](http://localhost:9966/) to see the content in action.
By default, budo pretty-prints to terminal with [garnish](https://github.com/mattdesl/garnish).
<center><img src="https://raw.githubusercontent.com/mattdesl/budo/master/screenshots/terminal.png" width="75%" /></center>
See [docs](#docs) for more details and integrations, such as [React Hot Module Replacement](./docs/command-line-usage.md#hot-module-replacement), [Pushstate Servers](./docs/command-line-usage.md#pushstate) and [HTTPS](./docs/command-line-usage.md#ssl-and-https). PRs/suggestions/comments welcome.
## features
At a glance:
- serves a default `index.html`
- fast incremental bundling, suspending the response until the new source is ready
- watches HTML and CSS files for changes; CSS is injected without reloading the page
- can emit [ndjson](http://ndjson.org) logs to use another pretty-printer, like [bistre](https://github.com/hughsk/bistre).
- provides clear error messaging during development in DOM and console
- supports SSL and can generate a self-signed certificate
- the rich API allows you to build more complex development tools on top of budo
Below is an example of how syntax errors look during development, using the [babelify](https://github.com/babel/babelify) transform.
<center><img src="https://raw.githubusercontent.com/mattdesl/budo/master/screenshots/build-error.png" width="75%" /></center>
## docs
- [command line usage](./docs/command-line-usage.md)
- [API usage](./docs/api-usage.md)
- [running tests and examples](./docs/tests-and-examples.md)
- [rapid prototyping with budō](http://mattdesl.svbtle.com/rapid-prototyping)
- [experimental script injection with budo-chrome](https://github.com/mattdesl/budo-chrome)
## usage
[![NPM](https://nodei.co/npm/budo.png)](https://www.npmjs.com/package/budo)
### CLI
Details for `budo` command-line interface.
```txt
Usage:
budo index.js [opts] -- [browserify opts]
Options:
--help, -h show help message
--version show version
--port, -p the port to run, default 9966
--host, -H the host, default internal IP (localhost)
--dir, -d a path, or array of paths for base static content
--serve, -s override the bundle path being served
--live, -l enable default LiveReload integration
--live-port, -L the LiveReload port, default 35729
--open, -o launch the browser once connected
--pushstate, -P always render the index page instead of a 404 page
--base set the base path for the generated HTML, default to '/'
--onupdate a shell command to trigger on bundle update
--poll=N use polling for file watch, with optional interval N
--title optional title for default index.html
--css optional stylesheet href for default index.html
--ssl, -S create an HTTPS server instead of HTTP
--cert, -C the cert for SSL (default cert.pem)
--key, -K the key for SSL (default key.pem)
--cors set header to use CORS (Access-Control-Allow-Origin: *)
--ndjson print ndjson instead of pretty-printed logs
--verbose, -v also include debug messages
--force-default-index always serve a generated index.html instead of a static one
--no-stream do not print messages to stdout
--no-debug do not use inline source maps
--no-portfind will not attempt auto-portfinding
--no-error-handler disable default DOM error handling
--watch-glob, --wg glob(s) to watch for reloads, default '**/*.{html,css}'
--static-options subarg options to pass to serve-static module
```
By default, messages will be printed to `process.stdout`, and `--debug` will be sent to browserify (for source maps). You can turn these off with `--no-stream` and `--no-debug`, respectively.
Everything after `--` is passed directly to browserify. Example:
```js
budo index.js --live -- -t [ babelify --extensions .es6 ]
```
### API
The API mirrors the CLI except it does not write to `process.stdout` by default.
```js
var budo = require('budo')
var babelify = require('babelify')
budo('./src/index.js', {
live: true, // setup live reload
port: 8000, // use this port
browserify: {
transform: babelify // ES6
}
}).on('connect', function (ev) {
console.log('Server running on %s', ev.uri)
console.log('LiveReload running on port %s', ev.livePort)
}).on('update', function (buffer) {
console.log('bundle - %d bytes', buffer.length)
})
```
See [API usage](docs/api-usage.md) for details.
## See Also
budō combines several smaller and less opinionated modules.
- [watchify-middleware](https://www.npmjs.com/package/watchify-middleware) - the underlying request handler for serving incremental reloads
- [watchify-server](https://www.npmjs.com/package/watchify-server) - a less opinionated alternative to budo, built on the same underlying modules
- [simple-html-index](https://www.npmjs.com/package/simple-html-index) - a stream for a default `index.html` file
Also, special thanks to [beefy](https://github.com/chrisdickinson/beefy) and [wzrd](https://github.com/maxogden/wzrd) which originally inspired budo.
## License
MIT, see [LICENSE.md](http://github.com/mattdesl/budo/blob/master/LICENSE.md) for details.
[stability-image]: https://img.shields.io/badge/stability-stable-brightgreen.svg?style=flat-square
[stability-url]: https://nodejs.org/api/documentation.html#documentation_stability_index
[npm-image]: https://img.shields.io/npm/v/budo.svg?style=flat-square
[npm-url]: https://npmjs.org/package/budo
[travis-image]: https://img.shields.io/travis/mattdesl/budo/master.svg?style=flat-square
[travis-url]: http://travis-ci.org/mattdesl/budo
[downloads-image]: http://img.shields.io/npm/dm/budo.svg?style=flat-square
[downloads-url]: https://npmjs.org/package/budo
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square
[standard-url]: https://github.com/feross/standard

View File

@ -0,0 +1,37 @@
var browserify = require('browserify')
var path = require('path')
var fs = require('fs')
var UglifyJS = require('uglify-js')
var buildFolder = path.resolve(__dirname, '..', 'build')
var buildFile = path.resolve(buildFolder, 'bundled-livereload-client.js')
var clientFile = path.resolve(__dirname, '..', 'lib', 'reload', 'client.js')
mkdir(buildFolder, function (err) {
if (err) return error(err)
browserify().add(clientFile).bundle(function (err, src) {
if (err) return error(err)
var result
try {
result = UglifyJS.minify(src.toString(), { fromString: true }).code
} catch (err) {
return error(err)
}
fs.writeFile(buildFile, result, function (err) {
if (err) error(err)
})
})
})
function mkdir (path, cb) {
fs.mkdir(path, function (err) {
if (err && err.code === 'EEXIST') err = null
cb(err)
})
}
function error (err) {
console.error('ERROR: Could not bundle LiveReload client, budo ' +
'will fall back to browserifying it on the fly.')
console.error(err)
}

7
static/js/ketcher2/node_modules/budo/bin/cmd.js generated vendored Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env node
// Starts budo with stdout
// Handles --help and error messaging
// Uses auto port-finding
var args = process.argv.slice(2)
require('../').cli(args)

32
static/js/ketcher2/node_modules/budo/bin/help.txt generated vendored Normal file
View File

@ -0,0 +1,32 @@
Usage:
budo index.js [opts] -- [browserify opts]
Options:
--help, -h show help message
--version show version
--port, -p the port to run, default 9966
--host, -H the host, default internal IP (localhost)
--dir, -d a path, or array of paths for base static content
--serve, -s override the bundle path being served
--live, -l enable default LiveReload integration
--live-port, -L the LiveReload port, default 35729
--open, -o launch the browser once connected
--pushstate, -P always render the index page instead of a 404 page
--base set the base path for the generated HTML, default to '/'
--onupdate a shell command to trigger on bundle update
--poll=N use polling for file watch, with optional interval N
--title optional title for default index.html
--css optional stylesheet href for default index.html
--ssl, -S create an HTTPS server instead of HTTP
--cert, -C the cert for SSL (default cert.pem)
--key, -K the key for SSL (default key.pem)
--cors set header to use CORS (Access-Control-Allow-Origin: *)
--ndjson print ndjson instead of pretty-printed logs
--verbose, -v also include debug messages
--force-default-index always serve a generated index.html instead of a static one
--no-stream do not print messages to stdout
--no-debug do not use inline source maps
--no-portfind will not attempt auto-portfinding
--no-error-handler disable default DOM error handling
--watch-glob, --wg glob(s) to watch for reloads, default '**/*.{html,css}'
--static-options subarg options to pass to serve-static module

File diff suppressed because one or more lines are too long

86
static/js/ketcher2/node_modules/budo/index.js generated vendored Normal file
View File

@ -0,0 +1,86 @@
var parseArgs = require('./lib/parse-args')
var budo = require('./lib/budo')
var color = require('term-color')
var stdoutStream = require('stdout-stream')
var exec = require('child_process').exec
module.exports = budo
module.exports.cli = budoCLI
function budoCLI (args, opts) {
var argv = parseArgs(args, opts)
// if no stream is specified, default to stdout
if (argv.stream !== false) {
argv.stream = /^win/.test(process.platform) ? process.stdout : stdoutStream
}
var entries = argv._
delete argv._
argv.browserifyArgs = argv['--']
delete argv['--']
if (argv.version) {
console.log('budo v' + require('./package.json').version)
console.log('browserify v' + require('browserify/package.json').version)
console.log('watchify v' + require('watchify-middleware').getWatchifyVersion())
return null
}
if (argv.help) {
var help = require('path').join(__dirname, 'bin', 'help.txt')
require('fs').createReadStream(help)
.pipe(process.stdout)
return null
}
if (argv.outfile) {
console.error(color.yellow('WARNING'), '--outfile has been removed in budo@3.0')
}
if (typeof argv.pushstate === 'string') {
// support backwards compatibility with CLI like this:
// budo -P index.js:bundle.js
var newEntry = argv.pushstate
argv.pushstate = argv.P = true
entries.unshift(newEntry)
console.error(color.yellow('WARNING'), '\nAs of budo@10.x, --pushstate should come ' +
'after your JS entries.\nExample:\n' +
' budo index.js:bundle.js --pushstate')
}
if (typeof argv.port === 'string') {
argv.port = parseInt(argv.port, 10)
}
if (typeof argv.livePort === 'string') {
argv.livePort = parseInt(argv.livePort, 10)
}
// opts.live can be a glob or a boolean
if (typeof argv.live === 'string' && /(true|false)/.test(argv.live)) {
argv.live = argv.live === 'true'
}
// CLI only option for executing a child process
var instance = budo(entries, argv).on('error', exit)
var onUpdates = [].concat(argv.onupdate).filter(Boolean)
onUpdates.forEach(function (cmd) {
instance.on('update', execFunc(cmd))
})
return instance
}
function execFunc (cmd) {
return function run () {
var p = exec(cmd)
p.stderr.pipe(process.stderr)
p.stdout.pipe(process.stdout)
}
}
function exit (err) {
console.log(color.red('ERROR'), err.message)
process.exit(1)
}

308
static/js/ketcher2/node_modules/budo/lib/budo.js generated vendored Normal file
View File

@ -0,0 +1,308 @@
var bole = require('bole')
var xtend = require('xtend')
var once = require('once')
var path = require('path')
var EventEmitter = require('events').EventEmitter
var isMatch = require('micromatch')
var openUrl = require('opn')
var internalIp = require('internal-ip')
var garnish = require('garnish')
var defaults = require('./parse-args').defaults
var getPorts = require('./get-ports')
var createServer = require('./server')
var createBundler = require('./bundler')
var createFileWatch = require('./file-watch')
var createReloadServer = require('./reload/server')
var mapEntry = require('./map-entry')
var noop = function () {}
module.exports = createBudo
function createBudo (entries, opts) {
var log = bole('budo')
// if no entries are specified, just options
if (entries && !Array.isArray(entries) && typeof entries === 'object') {
opts = entries
entries = []
}
// do not mutate user options
opts = xtend({}, defaults, { stream: false }, opts)
entries = entries || []
// perhaps later this will be configurable
opts.cwd = process.cwd()
// log to output stream
if (opts.stream) {
// by default, pretty-print to the stream with info logging
if (!opts.ndjson) {
var pretty = garnish({
level: opts.verbose ? 'debug' : 'info',
name: 'budo'
})
pretty.pipe(opts.stream)
opts.stream = pretty
}
bole.output({
stream: opts.stream,
level: 'debug'
})
}
// optionally allow as arrays
entries = [].concat(entries).filter(Boolean)
var entryObjects = entries.map(mapEntry)
var entryFiles = entryObjects.map(function (entry) {
return entry.from
})
if (opts.serve && typeof opts.serve !== 'string') {
throw new TypeError('opts.serve must be a string or undefined')
} else if (!opts.serve && entries.length > 0) {
opts.serve = entryObjects[0].url
}
// default to cwd
if (!opts.dir || opts.dir.length === 0) {
opts.dir = opts.cwd
}
var emitter = new EventEmitter()
var bundler, middleware
if (entries.length > 0 || (opts.browserify && opts.browserify.entries)) {
bundler = createBundler(entryFiles, opts)
middleware = bundler.middleware
bundler.on('log', function (ev) {
if (ev.type === 'bundle') {
var time = ev.elapsed
ev.elapsed = time
ev.name = 'browserify'
ev.type = undefined
ev.colors = {
elapsed: time > 1000 ? 'yellow' : 'dim',
message: 'dim '
}
log.info(ev)
}
})
// uncaught syntax errors should not stop the server
// this only happens when errorHandler: false
bundler.on('error', function (err) {
console.error('Error:', err.message ? err.message : err)
})
bundler.on('bundle-error', emitter.emit.bind(emitter, 'bundle-error'))
bundler.on('update', emitter.emit.bind(emitter, 'update'))
bundler.on('pending', emitter.emit.bind(emitter, 'pending'))
emitter.on('update', function (contents, deps) {
if (deps.length > 1) {
log.debug({
name: 'browserify',
message: deps.length + ' files changed'
})
}
})
}
var defaultWatchGlob = opts.watchGlob || '**/*.{html,css}'
var server = null
var closed = false
var started = false
var fileWatcher = null
var reloader = null
var deferredWatch = noop
var deferredLive = noop
// public API
emitter.close = once(close)
emitter.reload = reload
emitter.live = live
emitter.watch = watch
// setup defaults for live reload / watchify
if (opts.live) {
var initialLiveOpts = typeof opts.live === 'object' ? opts.live : undefined
emitter
.watch()
.live(initialLiveOpts)
.on('watch', function (ev, file) {
if (ev !== 'change' && ev !== 'add') {
return
}
defaultFileEvent(file)
})
.on('pending', function () {
defaultFileEvent(opts.serve)
})
}
// First, setup a server
createServer(middleware, opts, function (err, serverInstance) {
if (err) {
emitter.emit('error', err)
return
}
server = serverInstance
// start portfinding + connect
getPorts(opts, handlePorts)
})
return emitter
function defaultFileEvent (file) {
var filename = path.basename(file)
if ((Array.isArray(opts.live) || typeof opts.live === 'string') &&
isMatch(filename, opts.live).length === 0) {
return
}
emitter.reload(file)
}
function reload (file) {
process.nextTick(emitter.emit.bind(emitter, 'reload', file))
if (reloader) {
reloader.reload(file)
}
}
// enable file watch capabilities
function watch (glob, watchOpt) {
if (!started) {
deferredWatch = emitter.watch.bind(null, glob, watchOpt)
} else {
// destroy previous
if (fileWatcher) fileWatcher.close()
glob = glob && glob.length > 0 ? glob : defaultWatchGlob
glob = Array.isArray(glob) ? glob : [ glob ]
watchOpt = xtend({ poll: opts.poll }, watchOpt)
fileWatcher = createFileWatch(glob, watchOpt)
fileWatcher.on('watch', emitter.emit.bind(emitter, 'watch'))
}
return emitter
}
// enables LiveReload capabilities
function live (liveOpts) {
if (!started) {
deferredLive = emitter.live.bind(null, liveOpts)
} else {
// destroy previous
if (reloader) reloader.close()
// pass some options for the server middleware
server.setLiveOptions(xtend(liveOpts))
// create a web socket server for live reload
reloader = createReloadServer(server, opts)
}
return emitter
}
function getHostAddress (host) {
// user can specify "::" or "0.0.0.0" as host exactly
// or if undefined, default to internal-ip
if (!host) {
host = server.address().address
if (host === '0.0.0.0') {
// node 0.10 returns this when no host is specified
// node 0.12 returns internal-ip
host = '::'
}
}
if (host === '::') {
host = internalIp()
}
return host
}
function handlePorts (err, result) {
if (closed) return
if (err) {
emitter.emit('error', err)
return
}
opts.port = result.port
// improve error messaging
server.on('error', function (err) {
if (err.code === 'EADDRINUSE') {
err.message = 'port ' + opts.port + ' is in use'
emitter.emit('error', err)
} else {
emitter.emit('error', err)
}
})
// start server
// no host -> use localhost + internal-ip
server.listen(opts.port, opts.host || undefined, connect)
}
function connect () {
if (closed) return
started = true
// default host is internal IP
opts.host = getHostAddress(opts.host)
var port = opts.port
var protocol = opts.ssl ? 'https' : 'http'
var uri = protocol + '://' + opts.host + ':' + port + '/'
log.info({ message: 'Server running at', url: uri, type: 'connect' })
// if live() or watch() was called before connection
deferredWatch()
deferredLive()
// provide info on server connection
emitter.emit('connect', {
uri: uri,
port: port,
host: opts.host,
serve: opts.serve,
entries: entryFiles,
server: server,
webSocketServer: reloader ? reloader.webSocketServer : undefined,
dir: opts.dir
})
// initial bundle should come after
// connect event!
if (bundler) bundler.bundle()
// launch browser
if (opts.open) {
openUrl(uri)
}
}
function close () {
var next = emitter.emit.bind(emitter, 'exit')
if (started) {
server.once('close', next)
} else {
process.nextTick(next)
}
if (started) bole.reset()
if (started) server.close()
if (reloader) reloader.close()
if (bundler) bundler.close()
if (fileWatcher) fileWatcher.close()
closed = true
started = false
}
}

50
static/js/ketcher2/node_modules/budo/lib/bundler.js generated vendored Normal file
View File

@ -0,0 +1,50 @@
var xtend = require('xtend')
var createMiddleware = require('watchify-middleware').emitter
var fromArgs = require('browserify/bin/args')
var browserify = require('browserify')
var path = require('path')
var defaultErrorHandler = require('./error-handler')
module.exports = createBundler
function createBundler (files, opts) {
var bOpts = xtend({
cache: {},
packageCache: {},
debug: opts.debug
}, opts.browserify)
var bundler
var args = opts.browserifyArgs
if (args && Array.isArray(args)) {
// CLI args for browserify
bundler = fromArgs(args, bOpts)
} else {
// just assume JS only options
bundler = browserify(bOpts)
}
files.forEach(function (file) {
bundler.add(path.resolve(file))
})
var errorHandler = opts.errorHandler
if (typeof errorHandler !== 'function' && errorHandler !== false) {
errorHandler = defaultErrorHandler
}
var cwd = opts.cwd
var rootDirName
if (cwd) {
cwd = path.normalize(cwd)
rootDirName = path.basename(cwd) + path.sep
}
return createMiddleware(bundler, {
delay: opts.delay || 0,
initialBundle: false,
errorHandler: typeof errorHandler === 'function'
? function (err) { // pass along directories as well
return errorHandler(err, cwd, rootDirName)
}
: errorHandler // pass undefined / false / etc
})
}

View File

@ -0,0 +1,241 @@
var stripAnsi = require('strip-ansi')
module.exports = errorHandler
module.exports.render = bundleError
function bundleError (message, cwd, rootDirName) {
// Everything has to be contained inside this function
// for it to get stringified correctly. i.e. no require()!
console.error(message)
if (typeof document === 'undefined') {
return
} else if (!document.body) {
document.addEventListener('DOMContentLoaded', createErrorBox)
} else {
createErrorBox()
}
function createErrorBox () {
var parsed = parseError(message)
var overlayBox = document.createElement('div')
css(overlayBox, {
position: 'fixed',
width: '100%',
height: '100%',
zIndex: '100000000',
top: '0',
left: '0',
padding: '20px',
margin: '0px',
'box-sizing': 'border-box',
background: '#fff',
display: 'block',
'font-size': '14px',
'font-weight': 'normal',
'font-family': 'monospace'
})
if (!parsed.format) {
var pre = document.createElement('pre')
pre.textContent = message
css(pre, {
'word-wrap': 'break-word',
'white-space': 'pre-wrap',
'box-sizing': 'border-box',
margin: '0',
color: '#ff0000'
})
overlayBox.appendChild(pre)
} else {
var commonElements = []
var messageDiv = document.createElement('div')
commonElements.push(messageDiv)
messageDiv.textContent = parsed.message
overlayBox.appendChild(messageDiv)
css(messageDiv, {
color: '#ff2e2e',
'font-size': '16px'
})
var pathLocContainer = document.createElement('div')
css(pathLocContainer, { 'padding-top': '10px' })
if (isFinite(parsed.line)) {
var location = document.createElement('div')
commonElements.push(location)
var colStr = isFinite(parsed.column) ? (', column ' + parsed.column) : ''
location.textContent = ('line ' + parsed.line + colStr).trim()
css(location, {
color: 'hsl(0, 0%, 50%)',
'padding-bottom': '0px',
'font-size': '12px',
'font-weight': 'bold'
})
pathLocContainer.appendChild(location)
}
var path = document.createElement('div')
path.textContent = trimPath(parsed.path)
commonElements.push(path)
css(path, { 'font-style': 'italic' })
pathLocContainer.appendChild(path)
overlayBox.appendChild(pathLocContainer)
if (parsed.code) {
var sourceContainer = document.createElement('div')
var source = document.createElement('div')
var hr = document.createElement('div')
css(hr, {
background: 'hsl(0, 0%, 90%)',
width: '100%',
height: '2px',
padding: '0',
'margin-bottom': '10px',
'margin-top': '10px'
})
commonElements.push(source)
source.textContent = parsed.code
css(source, {
color: 'black',
'font-weight': 'bold',
'font-size': '14px',
'padding-left': '0px'
})
sourceContainer.appendChild(hr)
sourceContainer.appendChild(source)
overlayBox.appendChild(sourceContainer)
}
// apply common styles
commonElements.forEach(function (e) {
css(e, {
'word-wrap': 'break-word',
'white-space': 'pre-wrap',
'box-sizing': 'border-box',
display: 'block',
margin: '0',
'vertical-align': 'bottom'
})
})
}
document.body.appendChild(overlayBox)
}
function trimPath (filePath) {
if (filePath.indexOf(cwd) === 0) {
filePath = rootDirName + filePath.substring(cwd.length + 1)
}
return filePath
}
function css (element, style) {
Object.keys(style).forEach(function (k) {
element.style[k] = style[k]
})
}
// parse an error message into pieces
function parseError (err) {
var filePath, lineNum, splitLines
var result = {}
// For root files that syntax-error doesn't pick up:
var parseFilePrefix = 'Parsing file '
if (err.indexOf(parseFilePrefix) === 0) {
var pathWithErr = err.substring(parseFilePrefix.length)
filePath = getFilePath(pathWithErr)
if (!filePath) return result
result.path = filePath
var messageAndLine = pathWithErr.substring(filePath.length)
lineNum = /\((\d+):(\d+)\)/.exec(messageAndLine)
if (!lineNum) return result
result.message = messageAndLine.substring(1, lineNum.index).trim()
result.line = parseInt(lineNum[1], 10)
result.column = parseInt(lineNum[2], 10)
result.format = true
return result
}
// if module not found
var cannotFindModule = /^Cannot find module '(.+)' from '(.+)'(?:$| while parsing file: (.*)$)/.exec(err.trim())
if (cannotFindModule) {
result.missingModule = cannotFindModule[1]
result.path = cannotFindModule[3] || cannotFindModule[2]
result.message = "Cannot find module '" + result.missingModule + "'"
result.format = true
return result
}
// syntax-error returns the path and line number, also a \n at start
err = err.trim()
filePath = getFilePath(err)
if (!filePath) return result
result.path = filePath
var restOfMessage = err.substring(filePath.length)
var parsedSyntaxError = /^:(\d+)/.exec(restOfMessage)
if (parsedSyntaxError) { // this is a syntax-error
lineNum = parseInt(parsedSyntaxError[1], 10)
if (isFinite(lineNum)) result.line = lineNum
splitLines = restOfMessage.split('\n')
var code = splitLines.slice(1, splitLines.length - 1).join('\n')
result.code = code
result.message = splitLines[splitLines.length - 1]
result.format = true
return result
}
// remove colon
restOfMessage = restOfMessage.substring(1).trim()
var whileParsing = 'while parsing file: '
var whileParsingIdx = restOfMessage.indexOf(whileParsing)
if (whileParsingIdx >= 0) {
var beforeWhile = restOfMessage.substring(0, whileParsingIdx)
lineNum = /\((\d+):(\d+)\)/.exec(beforeWhile.split('\n')[0])
var messageStr = beforeWhile
if (lineNum) {
var line = parseInt(lineNum[1], 10)
var col = parseInt(lineNum[2], 10)
if (isFinite(line)) result.line = line
if (isFinite(col)) result.column = col
messageStr = messageStr.substring(0, lineNum.index)
}
result.message = messageStr.trim()
splitLines = restOfMessage.split('\n')
result.code = splitLines.slice(2).join('\n')
result.format = true
}
return result
}
// get a file path from the error message
function getFilePath (str) {
var hasRoot = /^[a-z]:/i.exec(str)
var colonLeftIndex = 0
if (hasRoot) {
colonLeftIndex = hasRoot[0].length
}
var pathEnd = str.split('\n')[0].indexOf(':', colonLeftIndex)
if (pathEnd === -1) {
// invalid string, return non-formattable result
return null
}
return str.substring(0, pathEnd)
}
}
function errorHandler (err, cwd, rootDirName) {
console.error('%s', err)
var msgStr = stripAnsi(err.message)
var params = [
JSON.stringify(msgStr),
JSON.stringify(cwd),
JSON.stringify(rootDirName)
].join(',')
return ';(' + bundleError + ')(' + params + ');'
}

45
static/js/ketcher2/node_modules/budo/lib/file-watch.js generated vendored Normal file
View File

@ -0,0 +1,45 @@
// a thin wrapper around chokidar file watching HTML / CSS
var watch = require('chokidar').watch
var xtend = require('xtend')
var Emitter = require('events/')
var ignores = [
'node_modules/**', 'bower_components/**',
'.git', '.hg', '.svn', '.DS_Store',
'*.swp', 'thumbs.db', 'desktop.ini'
]
module.exports = function (glob, opt) {
opt = xtend({
usePolling: opt && opt.poll,
ignored: ignores,
ignoreInitial: true
}, opt)
var emitter = new Emitter()
var closed = false
var ready = false
var watcher = watch(glob, opt)
watcher.on('add', onWatch.bind(null, 'add'))
watcher.on('change', onWatch.bind(null, 'change'))
// chokidar@1.0.0-r6 only allows close after ready event
watcher.once('ready', function () {
ready = true
if (closed) watcher.close()
})
function onWatch (event, path) {
emitter.emit('watch', event, path)
}
emitter.close = function () {
if (closed) return
if (ready) watcher.close()
closed = true
}
return emitter
}
module.exports.ignores = ignores

24
static/js/ketcher2/node_modules/budo/lib/get-ports.js generated vendored Normal file
View File

@ -0,0 +1,24 @@
var xtend = require('xtend')
var getPorts = require('get-ports')
module.exports = getServerPorts
function getServerPorts (opt, cb) {
opt = xtend({ port: 9966 }, opt)
// try to use exact port specified or the defaults
if (!opt.portfind) {
return process.nextTick(function () {
cb(null, {
port: opt.port
})
})
}
// find available ports
getPorts([ opt.port ], function (err, ports) {
if (err) return cb(err)
cb(null, {
port: ports[0]
})
})
}

43
static/js/ketcher2/node_modules/budo/lib/map-entry.js generated vendored Normal file
View File

@ -0,0 +1,43 @@
var path = require('path')
var url = require('url')
var resolve = require('resolve')
module.exports = mapEntry
function mapEntry (file) {
if (file === '.') {
file = entry()
}
var parts
// absolute path with letter drive, eg C:/
if (/^[A-Z]:[/\\]+/.test(file)) {
parts = file.split(/:(?:(?=[^/\\]))/)
} else {
parts = file.split(':')
}
var pathFrom, pathUrl
if (parts.length > 1 && parts[1].length > 0) {
pathFrom = parts[0]
pathUrl = parts[1]
if (pathFrom === '.') {
pathFrom = entry()
}
} else {
pathFrom = file
pathUrl = url.parse(path.basename(pathFrom)).pathname
}
return {
url: pathUrl,
from: pathFrom
}
}
function entry () {
var cwd = process.cwd()
var file = resolve.sync('.', { basedir: cwd })
return file || 'index.js'
}

248
static/js/ketcher2/node_modules/budo/lib/middleware.js generated vendored Normal file
View File

@ -0,0 +1,248 @@
// TODO: Expose this like webpack-dev-server middleware
var stacked = require('stacked')
var serveStatic = require('serve-static')
var defaultIndex = require('simple-html-index')
var logger = require('./simple-http-logger')
var urlLib = require('url')
var xtend = require('xtend')
var pushState = require('connect-pushstate')
var liveReload = require('inject-lr-script')
var urlTrim = require('url-trim')
var escapeHtml = require('escape-html')
var fs = require('fs')
var browserify = require('browserify')
var path = require('path')
var liveReloadClientFile = path.resolve(__dirname, 'reload', 'client.js')
var bundledReloadClientFile = path.resolve(__dirname, '..', 'build', 'bundled-livereload-client.js')
module.exports = budoMiddleware
function budoMiddleware (entryMiddleware, opts) {
opts = opts || {}
var staticPaths = [].concat(opts.dir).filter(Boolean)
if (staticPaths.length === 0) {
staticPaths = [ process.cwd() ]
}
var entrySrc = opts.serve
var live = opts.live
var cors = opts.cors
var handler = stacked()
var middlewares = [].concat(opts.middleware).filter(Boolean)
// Everything is logged except favicon.ico
var logHandler = logger({
ignores: [ '/favicon.ico' ]
})
handler.use(function (req, res, next) {
if (cors) {
res.setHeader('Access-Control-Allow-Headers', 'Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With')
res.setHeader('Access-Control-Allow-Methods', 'GET, PUT, POST')
res.setHeader('Access-Control-Allow-Origin', '*')
}
logHandler(req, res, next)
})
// User middleware(s) can override others
middlewares.forEach(function (middleware) {
if (typeof middleware !== 'function') {
throw new Error('middleware options must be functions')
}
handler.use(function (req, res, next) {
logHandler.type = 'middleware'
middleware(req, res, next)
})
})
// Re-route for pushState support
if (opts.pushstate) {
if (typeof opts.pushstate === 'string') {
throw new Error('--pushstate is a string, you shouold use subarg options instead')
}
var pushStateOpts = xtend(typeof opts.pushstate === 'boolean' ? {} : opts.pushstate)
delete pushStateOpts._ // added by subarg
handler.use(pushState(pushStateOpts))
}
// Inject liveReload snippet on response
var liveInjector = liveReload({
local: true
})
// this is lazily set and cannot be changed dynamically
var liveScriptUrl
// By default, attempt to optimize the response
var shouldUseBundledLiveReload = true
// Cache the client by default to optimize the response
var liveReloadClient
handler.use(liveReloadHandler)
// Entry (watchify) middleware
if (entryMiddleware) {
var entryRoute = '/' + urlLib.parse(entrySrc).pathname
handler.use(function (req, res, next) {
if (urlTrim(req.url) === urlTrim(entryRoute)) {
entryMiddleware(req, res, next)
} else {
next()
}
})
}
// Ignore favicon clutter
handler.mount('/favicon.ico', favicon)
// If the user wishes to *always* serve
// a generated index instead of a static one.
if (opts.forceDefaultIndex) {
handler.use(indexHandler)
}
// Static assets (html/images/etc)
staticPaths.forEach(function (rootFile) {
var staticOpts = xtend({
cacheControl: false
}, opts.staticOptions)
delete staticOpts._ // from subarg
var staticHandler = serveStatic(rootFile, staticOpts)
handler.use(function (req, res, next) {
logHandler.type = 'static'
staticHandler(req, res, next)
})
})
// Generates a default index.html
// when none is found locally.
handler.use(indexHandler)
// Handle errors
handler.use(function (req, res) {
res.statusCode = 404
res.end('404 not found: ' + escapeHtml(req.url))
})
// Allow live options to be changed at runtime
handler.setLiveOptions = setLiveOptions
return handler
function setLiveOptions (opts) {
live = opts
}
function favicon (req, res) {
var maxAge = 345600 // 4 days
res.setHeader('Cache-Control', 'public, max-age=' + Math.floor(maxAge / 1000))
res.setHeader('Content-Type', 'image/x-icon')
res.statusCode = 200
res.end()
}
function indexHandler (req, res, next) {
if (urlLib.parse(req.url).pathname === '/' || /\/index.html?/i.test(req.url)) {
// If we reach this, our response will be generated
// (not static from local file system)
logHandler.type = 'generated'
res.setHeader('content-type', 'text/html')
var stream = opts.defaultIndex || defaultIndex
stream({
entry: entrySrc,
title: opts.title,
css: opts.css,
base: opts.base === true ? '/' : (opts.base || null)
}, req).pipe(res)
} else {
next()
}
}
function serveBundledLiveReload (res, successCallback) {
if (liveReloadClient) {
res.end(liveReloadClient)
successCallback(true)
} else {
fs.readFile(bundledReloadClientFile, function (err, src) {
if (err) {
if (shouldUseBundledLiveReload) {
console.error([
'NOTE: The bundled LiveReload client could not be found, so budo will',
'generate this on the fly.',
'This is most likely because you are using a git cloned version of budo',
'instead of installing it from npm.',
'You can run this from your cloned budo folder to create a build:',
' npm run bundle-live-client'
].join('\n'))
}
shouldUseBundledLiveReload = false
successCallback(false)
} else {
liveReloadClient = src
res.end(src)
successCallback(true)
}
})
}
}
function serveBrowserifyLiveReload (cache, debug, liveScripts, res) {
// Browserify the client file, e.g. if user has a script to include
if (cache && liveReloadClient) {
res.end(liveReloadClient)
} else {
var b = browserify({ debug: debug })
b.add(liveReloadClientFile)
if (live.expose) {
b.require(liveReloadClientFile, { expose: 'budo-livereload' })
}
liveScripts.forEach(function (file) {
b.add(path.resolve(file))
})
b.bundle(function (err, src) {
if (err) {
console.error('Error bundling LiveReload client:\n' + err.message)
res.statusCode = 500
res.end('Error bundling LiveReload client: ' + err)
} else {
liveReloadClient = src
res.end(src)
}
})
}
}
function liveReloadHandler (req, res, next) {
if (!live || live.plugin) return next()
if (!liveScriptUrl) {
liveScriptUrl = live.path || '/budo/livereload.js'
logHandler.ignores.push(liveScriptUrl)
} else if (liveScriptUrl && live.path && liveScriptUrl !== live.path) {
var errMessage = 'Error: The LiveReload path field cannot be changed dynamically.\n' +
'Please open an issue in budo if you have a specific use case for this.'
console.error(errMessage)
res.statusCode = 500
res.end(errMessage)
return
}
if (req.url === liveScriptUrl) {
res.statusCode = 200
res.setHeader('Content-Type', 'application/javascript')
var liveScripts = (Array.isArray(live.include) ? live.include : [ live.include ]).filter(Boolean)
var cache = live.cache !== false
var debug = live.debug
// Default setup - use a bundled JS file for LiveReload client
if (shouldUseBundledLiveReload && cache && !debug && liveScripts.length === 0) {
serveBundledLiveReload(res, function (success) {
// fall back to browserify on the fly
if (!success) serveBrowserifyLiveReload(cache, debug, liveScripts, res)
})
} else {
serveBrowserifyLiveReload(cache, debug, liveScripts, res)
}
} else {
liveInjector.path = liveScriptUrl
liveInjector(req, res, next)
}
}
}

70
static/js/ketcher2/node_modules/budo/lib/parse-args.js generated vendored Normal file
View File

@ -0,0 +1,70 @@
var subarg = require('subarg')
var xtend = require('xtend')
module.exports = parseArgs
function parseArgs (args, opt) {
// before parsing subarg, remove the bundler arguments
var bundlerFlags = []
var stopIndex = args.indexOf('--')
if (stopIndex >= 0) {
bundlerFlags = args.slice(stopIndex + 1)
args = args.slice(0, stopIndex)
}
var argv = subarg(args, {
boolean: [
'stream',
'debug',
'errorHandler',
'forceDefaultIndex',
'open',
'portfind',
'ndjson',
'verbose',
'cors',
'ssl'
],
string: [
'host',
'port',
'dir',
'onupdate',
'serve',
'title',
'watchGlob',
'cert',
'key'
],
default: module.exports.defaults,
alias: {
port: 'p',
ssl: 'S',
serve: 's',
cert: 'C',
key: 'K',
verbose: 'v',
help: 'h',
host: 'H',
dir: 'd',
live: 'l',
open: 'o',
staticOptions: [ 'static-options' ],
watchGlob: [ 'wg', 'watch-glob' ],
errorHandler: 'error-handler',
forceDefaultIndex: 'force-default-index',
pushstate: 'P'
},
'--': true
})
// add back in the bundler flags
argv['--'] = bundlerFlags
return xtend(argv, opt)
}
module.exports.defaults = {
title: 'budo',
port: 9966,
debug: true,
stream: true,
errorHandler: true,
portfind: true
}

View File

@ -0,0 +1,134 @@
var reloadCSS = require('reload-css')
module.exports = connect()
function connect () {
var reconnectPoll = 1000
var maxRetries = 50
var retries = 0
var reconnectInterval
var isReconnecting = false
var protocol = document.location.protocol
var hostname = document.location.hostname
var port = document.location.port
var host = hostname + ':' + port
var isIOS = /(iOS|iPhone|iPad|iPod)/i.test(navigator.userAgent)
var isSSL = /^https:/i.test(protocol)
var queued = []
var socket = createWebSocket()
var listeners = []
var api = {
send: function (message) {
message = JSON.stringify(message)
if (socket && socket.readyState === 1) {
socket.send(message)
} else {
queued.push(message)
}
},
listen: function (cb) {
if (typeof cb !== 'function') {
throw new TypeError('cb must be a function!')
}
listeners.push(cb)
},
reloadPage: reloadPage,
reloadCSS: reloadCSS
}
return api
function scheduleReconnect () {
if (isIOS && isSSL) {
// Special case for iOS with a self-signed certificate.
console.warn('[budo] LiveReload disconnected. You may need to generate and ' +
'trust a self-signed certificate, see here:\n' +
'https://github.com/mattdesl/budo/blob/master/docs/' +
'command-line-usage.md#ssl-on-ios')
return
}
if (isSSL) {
// Don't attempt to re-connect in SSL since it will likely be insecure
console.warn('[budo] LiveReload disconnected. Please reload the page to retry.')
return
}
if (retries >= maxRetries) {
console.warn('[budo] LiveReload disconnected, exceeded retry count. Please reload the page to retry.')
return
}
if (!isReconnecting) {
isReconnecting = true
console.warn('[budo] LiveReload disconnected, retrying...')
}
retries++
clearTimeout(reconnectInterval)
reconnectInterval = setTimeout(reconnect, reconnectPoll)
}
function reconnect () {
if (socket) {
// force close the existing socket
socket.onclose = function () {}
socket.close()
}
socket = createWebSocket()
}
function createWebSocket () {
var wsProtocol = isSSL ? 'wss://' : 'ws://'
var wsUrl = wsProtocol + host + '/livereload'
var ws = new window.WebSocket(wsUrl)
ws.onmessage = function (event) {
var data
try {
data = JSON.parse(event.data)
} catch (err) {
console.warn('Error parsing LiveReload server data: ' + event.data)
return
}
if (data.event === 'reload') {
if (/^\.?css$/i.test(data.ext)) {
reloadCSS(data.url)
} else {
reloadPage()
}
}
// let listeners receive data
listeners.forEach(function (listener) {
listener(data)
})
}
ws.onclose = function (ev) {
if (ev.code === 1000 || ev.code === 1001) {
// Browser is navigating away.
return
}
scheduleReconnect()
}
ws.onopen = function () {
if (isReconnecting) {
isReconnecting = false
retries = 0
console.warn('[budo] LiveReload reconnected.')
}
if (queued.length && ws.readyState === 1) {
queued.forEach(function (message) {
ws.send(message)
})
queued.length = 0
}
}
ws.onerror = function () {
return false
}
return ws
}
}
function reloadPage () {
window.location.reload(true)
}

View File

@ -0,0 +1,78 @@
var WebSocketServer = require('ws').Server
var log = require('bole')('budo')
var path = require('path')
var isAbsolute = require('path-is-absolute')
var color = require('term-color')
module.exports = function (server, opts) {
opts = opts || {}
log.info({ message: 'LiveReload running' })
// get a list of static folders to use as base dirs
var cwd = path.resolve(opts.cwd || process.cwd())
var staticDirs = Array.isArray(opts.dir) ? opts.dir : [ opts.dir ]
staticDirs = staticDirs.map(function (dir) {
return path.resolve(dir)
})
if (staticDirs.indexOf(cwd) === -1) staticDirs.push(cwd)
var closed = false
var wss = new WebSocketServer({
server: server,
perMessageDeflate: false
})
return {
webSocketServer: wss,
reload: reload,
close: function () {
if (closed) return
wss.close()
closed = true
}
}
function reload (file) {
if (closed) return
var url, ext
if (file && typeof file === 'string') {
// absolute file path
file = isAbsolute(file) ? path.normalize(file) : path.resolve(cwd, file)
// make it relative, removing the static folder parts
for (var i = 0; i < staticDirs.length; i++) {
var dir = staticDirs[i]
url = path.relative(dir, file)
// if the path doesn't starts with "../", then
// it should be relative to this folder
if (!/^(\.\.[/\\]|[/\\])/.test(url)) break
}
// turn it into a URL
url = url.replace(/\\/g, '/')
// ensure it starts at root of app
if (url.charAt(0) !== '/') url = '/' + url
ext = path.extname(file)
}
broadcast({ event: 'reload', ext: ext, url: url })
}
function broadcast (data) {
if (closed) return
data = JSON.stringify(data)
try {
wss.clients.forEach(function (client) {
client.send(data, {
binary: false
})
})
} catch (err) {
console.error(color.red('ERROR'), 'Error sending LiveReload event to client:')
console.error(err)
}
}
}

49
static/js/ketcher2/node_modules/budo/lib/server.js generated vendored Normal file
View File

@ -0,0 +1,49 @@
var http = require('http')
var https = require('https')
var pem = require('pem')
var createMiddleware = require('./middleware')
var fs = require('fs')
module.exports = function createServer (entryMiddleware, opts, cb) {
var handler = createMiddleware(entryMiddleware, opts)
var ssl = opts.ssl
if (ssl && (!opts.cert && opts.key) || (!opts.key && opts.cert)) {
throw new TypeError('If you specify a cert, you must specify a key and vice versa.\n' +
'Or, you can omit the "cert" and "key" options to generate a new self-signed certificate.')
}
if (opts.ssl) {
if (opts.cert && opts.key) {
// user specified their own cert/key pair
create({
cert: fs.readFileSync(opts.cert),
key: fs.readFileSync(opts.key)
})
} else {
// generate a self-signed cert
pem.createCertificate({ days: 1, selfSigned: true }, function (err, keys) {
if (err) return cb(err)
create({
key: keys.serviceKey,
cert: keys.certificate
})
})
}
} else {
// no HTTPS, handle normally
create()
}
function create (httpsOpts) {
var server = ssl
? https.createServer(httpsOpts, handler)
: http.createServer(handler)
server.setLiveOptions = handler.setLiveOptions
// TODO: Perhaps --ssl should support some sort of HTTP -> HTTPS redirect
process.nextTick(function () {
cb(null, server)
})
}
}

View File

@ -0,0 +1,75 @@
var log = require('bole')('budo')
var onResHeaders = require('on-headers')
var onResFinished = require('on-finished')
module.exports = simpleHttpLoggerMiddleware
function simpleHttpLoggerMiddleware (opts) {
opts = opts || {}
var httpLogger = function simpleHttpLogger (req, res, next) {
if (httpLogger.ignores.indexOf(req.url) >= 0) return next()
if (!req.url) return next()
// request data
req._startAt = undefined
// response data
res._startAt = undefined
// record request start
recordStartTime.call(req)
var byteLength = 0
var logRequest = function () {
if (!req._startAt || !res._startAt) {
// missing request and/or response start time
return
}
// calculate diff
var ms = (res._startAt[0] - req._startAt[0]) * 1000 +
(res._startAt[1] - req._startAt[1]) * 1e-6
log.info({
elapsed: ms,
contentLength: byteLength,
method: (req.method || 'GET').toUpperCase(),
url: req.url,
statusCode: res.statusCode,
type: httpLogger.type === 'static' ? undefined : httpLogger.type,
colors: {
elapsed: ms > 1000 ? 'yellow' : 'dim'
}
})
}
var isAlreadyLogging = res._simpleHttpLogger
res._simpleHttpLogger = true
if (!isAlreadyLogging) {
// record response start
onResHeaders(res, recordStartTime)
// log when response finished
onResFinished(res, logRequest)
var writeFn = res.write
// catch content-length of payload
res.write = function (payload) {
if (payload) byteLength += payload.length
return writeFn.apply(res, arguments)
}
}
next()
}
httpLogger.ignores = [].concat(opts.ignores).filter(Boolean)
httpLogger.type = 'static'
return httpLogger
}
function recordStartTime () {
this._startAt = process.hrtime()
}

124
static/js/ketcher2/node_modules/budo/package.json generated vendored Normal file
View File

@ -0,0 +1,124 @@
{
"_from": "budo@10.0.3",
"_id": "budo@10.0.3",
"_inBundle": false,
"_integrity": "sha1-jNrztQOqtae3BxH9okyky7lMYSQ=",
"_location": "/budo",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "budo@10.0.3",
"name": "budo",
"escapedName": "budo",
"rawSpec": "10.0.3",
"saveSpec": null,
"fetchSpec": "10.0.3"
},
"_requiredBy": [
"#DEV:/"
],
"_resolved": "https://registry.npmjs.org/budo/-/budo-10.0.3.tgz",
"_shasum": "8cdaf3b503aab5a7b70711fda24ca4cbb94c6124",
"_spec": "budo@10.0.3",
"_where": "/home/manfred/enviPath/ketcher2/ketcher",
"author": {
"name": "Matt DesLauriers",
"email": "dave.des@gmail.com",
"url": "https://github.com/mattdesl"
},
"bin": {
"budo": "./bin/cmd.js"
},
"bugs": {
"url": "https://github.com/mattdesl/budo/issues"
},
"bundleDependencies": false,
"dependencies": {
"bole": "^2.0.0",
"browserify": "^14.1.0",
"chokidar": "^1.0.1",
"connect-pushstate": "^1.1.0",
"escape-html": "^1.0.3",
"events": "^1.0.2",
"garnish": "^5.0.0",
"get-ports": "^1.0.2",
"inject-lr-script": "^2.1.0",
"internal-ip": "^1.0.1",
"micromatch": "^2.2.0",
"on-finished": "^2.3.0",
"on-headers": "^1.0.1",
"once": "^1.3.2",
"opn": "^3.0.2",
"path-is-absolute": "^1.0.1",
"pem": "^1.8.3",
"reload-css": "^1.0.0",
"resolve": "^1.1.6",
"serve-static": "^1.10.0",
"simple-html-index": "^1.4.0",
"stacked": "^1.1.1",
"stdout-stream": "^1.4.0",
"strip-ansi": "^3.0.0",
"subarg": "^1.0.0",
"term-color": "^1.0.1",
"url-trim": "^1.0.0",
"watchify-middleware": "^1.6.0",
"ws": "^1.1.1",
"xtend": "^4.0.0"
},
"deprecated": false,
"description": "a browserify server for rapid prototyping",
"devDependencies": {
"2d-context": "^1.2.0",
"babel-preset-es2015": "^6.18.0",
"babelify": "^7.3.0",
"brfs": "^1.4.0",
"canvas-loop": "^1.0.4",
"connect-slashes": "^1.3.1",
"getuservideo": "^0.1.3",
"ndjson": "^1.4.1",
"request": "^2.53.0",
"standard": "^8.6.0",
"tap-spec": "^4.1.0",
"tape": "^4.0.0",
"through2": "^2.0.0",
"tree-kill": "^1.0.0",
"uglify-js": "^2.7.5",
"win-spawn": "^2.0.0"
},
"homepage": "https://github.com/mattdesl/budo",
"keywords": [
"browserify",
"watchify",
"browser",
"dev",
"development",
"server",
"beefy",
"wzrd",
"local",
"locally",
"localhost",
"watch",
"live",
"reload",
"livereload",
"lr"
],
"license": "MIT",
"main": "index.js",
"name": "budo",
"repository": {
"type": "git",
"url": "git://github.com/mattdesl/budo.git"
},
"scripts": {
"bundle-live-client": "node bin/bundle-livereload-client.js",
"live": "node example/live.js example/app.js:bundle.js --dir example -- -t [ babelify --presets [ es2015 ] ]",
"prepublish": "npm run bundle-live-client",
"pushstate": "node bin/cmd.js example/app.js:bundle.js -v --dir example --live --pushstate -- -t [ babelify --presets [ es2015 ] ]",
"start": "node bin/cmd.js example/app.js:bundle.js --live -v --dir example -- -t [ babelify --presets [ es2015 ] ]",
"test": "standard && tape test/test*.js | tap-spec"
},
"version": "10.0.3"
}