<commit_before>/* global grecaptcha */
import { h, Component } from 'preact';
import PropTypes from "prop-types";

const lang = typeof window !== "undefined" && (window.recaptchaOptions && window.recaptchaOptions.lang) ?
	`&hl=${window.recaptchaOptions.lang}` :
	"";
const URL = `https://www.google.com/recaptcha/api.js?&onload=recaptchaLoaded&render=explicit${lang}`;

const isRecaptchaLoaded = () => typeof window !== 'undefined' && typeof window.grecaptcha !== 'undefined';

export default class ReCaptcha extends Component {
	constructor() {
		super();
		this.waitingTimer = null;
		this.element = null;
		this.recaptchaId = null;

		this._captureRef = this.captureRef.bind(this);
		this._initializeRecaptcha = this.initializeRecaptcha.bind(this);
		this._handleExpired = this.handleExpired.bind(this);
		this._handleChange = this.handleChange.bind(this);
	}

	componentDidMount() {
		this.initializeRecaptcha();
	}

	componentWillUnmount() {
		this.clearTimer();
		if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null) {
			this.removeRecaptcha();
		}
		window.___grecaptcha_cfg.count = 0;
		window.___grecaptcha_cfg.clients = {};
	}

	render() {
		// eslint-disable-next-line no-unused-vars
		const { sitekey, onChange, theme, type, tabindex, onExpired, size, stoken, grecaptcha, badge, ...childProps } = this.props;
		return (
			<div {...childProps} ref={this._captureRef} />
		);
	}

	execute = () => {
		if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null && this.props.size === "invisible") {
			grecaptcha.execute(this.recaptchaId);
			return true;
		}
		return false;
	}

	reset = () => {
		if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null) {
			grecaptcha.reset(this.recaptchaId);
			return true;
		}
		return false;
	}

		getResponse = () => {
			if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null) {
				return grecaptcha.getResponse(this.recaptchaId);
			}
			return null;
		}

		handleChange = (response) => {
			if (this.props.onChange) {
				this.props.onChange(response);
			}
		}

		handleExpired = () => {
			if (this.props.onExpired) {
				this.props.onExpired();
			}
		}

		removeRecaptcha = () => {
			grecaptcha.reset(this.recaptchaId);
		}

		renderRecaptcha = () => {
			this.recaptchaId = grecaptcha.render(this.element, {
				sitekey: this.props.sitekey,
				callback: this._handleChange,
				theme: this.props.theme,
				type: this.props.type,
				tabindex: this.props.tabindex,
				"expired-callback": this._handleExpired,
				size: this.props.size,
				stoken: this.props.stoken,
				badge: this.props.badge
			});
		}

		captureRef = (elem) => {
			this.element = elem;
		}

		initializeRecaptcha = () => {
			if (isRecaptchaLoaded()) {
				// Initialize recaptcha
				this.clearTimer();
				this.renderRecaptcha();
			} else if (!this.isRecaptchaJSLibInjected()) {
				// Check if script already injected, if not load it async with callback
				let script = document.createElement("script");

				window.recaptchaLoaded = this.initializeRecaptcha.bind(this);

				script.src = URL;
				script.async = 1;
				script.defer = 1;

				script.onerror = () => {
					console.log("Error loading google recaptcha!");
				};

				document.body.appendChild(script);

			} else {
				this.startTimer();
			}
		}

		isRecaptchaJSLibInjected = () => {
			if (typeof window === 'undefined') { return false; }
			if (!document.scripts || document.scripts.length === 0) { return false; }
			let scripts = Object.assign([], document.scripts);
			return (scripts.filter((script) => {
				return script.src.match(/((http|https):)?\/\/(www\.)?google\.com\/recaptcha\/(.*)/i) !== null;
			})).length > 0;
		}

		startTimer = () => {
			this.waitingTimer = setTimeout(this._initializeRecaptcha, 200);
		}

		clearTimer = () => {
			if (this.waitingTimer !== null) {
				clearInterval(this.waitingTimer);
			}
		}
}

ReCaptcha.propTypes = {
	sitekey: PropTypes.string.isRequired,
	theme: PropTypes.oneOf(["dark", "light"]),
	type: PropTypes.oneOf(["image", "audio"]),
	tabindex: PropTypes.number,
	size: PropTypes.oneOf(["compact", "normal", "invisible"]),
	stoken: PropTypes.string,
	badge: PropTypes.oneOf(["bottomright", "bottomleft", "inline"]),
	onChange: PropTypes.func,
	onExpired: PropTypes.func
};
ReCaptcha.defaultProps = {
	theme: "light",
	type: "image",
	tabindex: 0,
	size: "normal",
	badge: "bottomright"
};
<commit_msg>Fix multiple recaptcha bug (#8)<commit_after>/* global grecaptcha */
import { h, Component } from 'preact';
import PropTypes from "prop-types";

const lang = typeof window !== "undefined" && (window.recaptchaOptions && window.recaptchaOptions.lang) ?
	`&hl=${window.recaptchaOptions.lang}` :
	"";
const URL = `https://www.google.com/recaptcha/api.js?&onload=recaptchaLoaded&render=explicit${lang}`;

const isRecaptchaLoaded = () => typeof window !== 'undefined' && typeof window.grecaptcha !== 'undefined';

export default class ReCaptcha extends Component {
	constructor() {
		super();
		this.waitingTimer = null;
		this.element = null;
		this.recaptchaId = null;

		this._captureRef = this.captureRef.bind(this);
		this._initializeRecaptcha = this.initializeRecaptcha.bind(this);
		this._handleExpired = this.handleExpired.bind(this);
		this._handleChange = this.handleChange.bind(this);
	}

	componentDidMount() {
		this.initializeRecaptcha();
	}

	componentWillUnmount() {
		this.clearTimer();
		if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null) {
			this.removeRecaptcha();
		}
		if ( window.___grecaptcha_cfg ) {
		    delete ___grecaptcha_cfg.clients[this.recaptchaId];
		    ___grecaptcha_cfg.count--;
		}
	}

	render() {
		// eslint-disable-next-line no-unused-vars
		const { sitekey, onChange, theme, type, tabindex, onExpired, size, stoken, grecaptcha, badge, ...childProps } = this.props;
		return (
			<div {...childProps} ref={this._captureRef} />
		);
	}

	execute = () => {
		if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null && this.props.size === "invisible") {
			grecaptcha.execute(this.recaptchaId);
			return true;
		}
		return false;
	}

	reset = () => {
		if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null) {
			grecaptcha.reset(this.recaptchaId);
			return true;
		}
		return false;
	}

		getResponse = () => {
			if (isRecaptchaLoaded() && this.element && this.recaptchaId !== null) {
				return grecaptcha.getResponse(this.recaptchaId);
			}
			return null;
		}

		handleChange = (response) => {
			if (this.props.onChange) {
				this.props.onChange(response);
			}
		}

		handleExpired = () => {
			if (this.props.onExpired) {
				this.props.onExpired();
			}
		}

		removeRecaptcha = () => {
			grecaptcha.reset(this.recaptchaId);
		}

		renderRecaptcha = () => {
			this.recaptchaId = grecaptcha.render(this.element, {
				sitekey: this.props.sitekey,
				callback: this._handleChange,
				theme: this.props.theme,
				type: this.props.type,
				tabindex: this.props.tabindex,
				"expired-callback": this._handleExpired,
				size: this.props.size,
				stoken: this.props.stoken,
				badge: this.props.badge
			});
		}

		captureRef = (elem) => {
			this.element = elem;
		}

		initializeRecaptcha = () => {
			if (isRecaptchaLoaded()) {
				// Initialize recaptcha
				this.clearTimer();
				this.renderRecaptcha();
			} else if (!this.isRecaptchaJSLibInjected()) {
				// Check if script already injected, if not load it async with callback
				let script = document.createElement("script");

				window.recaptchaLoaded = this.initializeRecaptcha.bind(this);

				script.src = URL;
				script.async = 1;
				script.defer = 1;

				script.onerror = () => {
					console.log("Error loading google recaptcha!");
				};

				document.body.appendChild(script);

			} else {
				this.startTimer();
			}
		}

		isRecaptchaJSLibInjected = () => {
			if (typeof window === 'undefined') { return false; }
			if (!document.scripts || document.scripts.length === 0) { return false; }
			let scripts = Object.assign([], document.scripts);
			return (scripts.filter((script) => {
				return script.src.match(/((http|https):)?\/\/(www\.)?google\.com\/recaptcha\/(.*)/i) !== null;
			})).length > 0;
		}

		startTimer = () => {
			this.waitingTimer = setTimeout(this._initializeRecaptcha, 200);
		}

		clearTimer = () => {
			if (this.waitingTimer !== null) {
				clearInterval(this.waitingTimer);
			}
		}
}

ReCaptcha.propTypes = {
	sitekey: PropTypes.string.isRequired,
	theme: PropTypes.oneOf(["dark", "light"]),
	type: PropTypes.oneOf(["image", "audio"]),
	tabindex: PropTypes.number,
	size: PropTypes.oneOf(["compact", "normal", "invisible"]),
	stoken: PropTypes.string,
	badge: PropTypes.oneOf(["bottomright", "bottomleft", "inline"]),
	onChange: PropTypes.func,
	onExpired: PropTypes.func
};
ReCaptcha.defaultProps = {
	theme: "light",
	type: "image",
	tabindex: 0,
	size: "normal",
	badge: "bottomright"
};
<|endoftext|>


<commit_before>const bodyParser = require('body-parser');
const express = require('express');
const fs = require('fs');
const helmet = require('helmet');
const morgan = require('morgan');
const uuid = require('uuid');
const config = require('./config');

// App and loaded modules.
const app = express();

const HTTP_OK_CODE = 200;
const HTTP_ERROR_CODE = 400;
const HTTP_TOOLARGE_CODE = 413;
const HTTP_INTERNALERROR_CODE = 500;

// Enable cross-origin ressource sharing.
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept'
  );
  res.setHeader('Content-Type', 'application/json');
  next();
});

const args = config.cliArgs;
app.use(bodyParser.json({limit: args.limit}));
app.use(bodyParser.urlencoded({extended: true, limit: args.limit}));

const accessLogStream = fs.createWriteStream(args.logdir + '/access.log', {
  flags: 'a'
});

app.use(morgan('combined', {stream: accessLogStream}));

app.use(helmet());

app.use((err, req, res, next) => {
  if (
    err instanceof SyntaxError &&
    err.status === HTTP_ERROR_CODE &&
    'body' in err
  ) {
    const message =
      'Invalid JSON object in request, please add jobs and vehicles to the object body';
    console.log(now() + ': ' + JSON.stringify(message));
    res.status(HTTP_ERROR_CODE);
    res.send({
      code: config.vroomErrorCodes.input,
      error: message
    });
  }
});

// Simple date generator for console output.
const now = function() {
  const date = new Date();
  return date.toUTCString();
};

const logToFile = function(input) {
  const timestamp = Math.floor(Date.now() / 1000); //eslint-disable-line
  const fileName = args.logdir + '/' + timestamp + '_' + uuid.v1() + '.json';
  fs.writeFileSync(fileName, input, (err, data) => {
    if (err) {
      console.log(now() + err);
    }
  });

  return fileName;
};

const fileExists = function(filePath) {
  try {
    return fs.statSync(filePath).isFile();
  } catch (err) {
    return false;
  }
};

// Callback for size and some input validity checks.
const sizeCheckCallback = function(maxLocationNumber, maxVehicleNumber) {
  return function(req, res, next) {
    const correctInput = 'jobs' in req.body && 'vehicles' in req.body;
    if (!correctInput) {
      const message =
        'Invalid JSON object in request, please add jobs and vehicles to the object body';
      console.error(now() + ': ' + JSON.stringify(message));
      res.status(HTTP_ERROR_CODE);
      res.send({
        code: config.vroomErrorCodes.input,
        error: message
      });
      return;
    }

    if (req.body.jobs.length > maxLocationNumber) {
      const jobs = req.body.jobs.length;
      const message = [
        'Too many jobs (',
        jobs,
        ') in query, maximum is set to',
        maxLocationNumber
      ].join(' ');
      console.error(now() + ': ' + JSON.stringify(message));
      res.status(HTTP_TOOLARGE_CODE);
      res.send({
        code: config.vroomErrorCodes.tooLarge,
        error: message
      });
      return;
    }
    if (req.body.vehicles.length > maxVehicleNumber) {
      const vehicles = req.body.vehicles.length;
      const message = [
        'Too many vehicles (',
        vehicles,
        ') in query, maximum is set to',
        maxVehicleNumber
      ].join(' ');
      console.error(now() + ': ' + JSON.stringify(message));
      res.status(HTTP_TOOLARGE_CODE);
      res.send({
        code: config.vroomErrorCodes.tooLarge,
        error: message
      });
      return;
    }
    next();
  };
};

// Cli wrapper and associated callback.
const spawn = require('child_process').spawn;

const vroomCommand = args.path + 'vroom';
const options = [];
options.push('-r', args.router);
if (args.router != 'libosrm') {
  const routingServers = config.routingServers;
  for (const profileName in routingServers) {
    const profile = routingServers[profileName];
    if ('host' in profile && 'port' in profile) {
      options.push('-a', profileName + ':' + profile.host);
      options.push('-p', profileName + ':' + profile.port);
    } else {
      console.error(
        "Incomplete configuration: profile '" +
          profileName +
          "' requires 'host' and 'port'."
      );
    }
  }
}
if (args.geometry) {
  options.push('-g');
}

const execCallback = function(req, res) {
  const reqOptions = options.slice();
  if (
    !args.geometry &&
    args.override &&
    'options' in req.body &&
    'g' in req.body.options &&
    req.body.options.g
  ) {
    reqOptions.push('-g');
  }

  const fileName = logToFile(JSON.stringify(req.body));
  reqOptions.push('-i ' + fileName);

  const vroom = spawn(vroomCommand, reqOptions, {shell: true});

  // Handle errors.
  vroom.on('error', err => {
    const message = ['Unknown internal error', err].join(': ');
    console.error(now() + ': ' + JSON.stringify(message));
    res.status(HTTP_INTERNALERROR_CODE);
    res.send({
      code: config.vroomErrorCodes.internal,
      error: message
    });
  });

  vroom.stderr.on('data', data => {
    console.error(now() + ': ' + data.toString());
  });

  // Handle solution. The temporary solution variable is required as
  // we also want to adjust the status that is only retrieved with
  // 'exit', after data is written in stdout.
  let solution = '';

  vroom.stdout.on('data', data => {
    solution += data.toString();
  });

  vroom.on('close', (code, signal) => {
    switch (code) {
      case config.vroomErrorCodes.ok:
        res.status(HTTP_OK_CODE);
        break;
      case config.vroomErrorCodes.internal:
        // Internal error.
        res.status(HTTP_INTERNALERROR_CODE);
        break;
      case config.vroomErrorCodes.input:
        // Input error.
        res.status(HTTP_ERROR_CODE);
        break;
      case config.vroomErrorCodes.routing:
        // Routing error.
        res.status(HTTP_INTERNALERROR_CODE);
        break;
      case 127: //eslint-disable-line
        // vroom not found on command line
        res.status(HTTP_INTERNALERROR_CODE);
        break;
    }
    res.send(solution);

    if (fileExists(fileName)) {
      fs.unlinkSync(fileName);
    }
  });
};

app.post('/', [
  sizeCheckCallback(args.maxlocations, args.maxvehicles),
  execCallback
]);

const server = app.listen(args.port, () => {
  console.log('vroom-express listening on port ' + args.port + '!');
});

server.setTimeout(args.timeout);
<commit_msg>Add number of shipment locations in total count.<commit_after>const bodyParser = require('body-parser');
const express = require('express');
const fs = require('fs');
const helmet = require('helmet');
const morgan = require('morgan');
const uuid = require('uuid');
const config = require('./config');

// App and loaded modules.
const app = express();

const HTTP_OK_CODE = 200;
const HTTP_ERROR_CODE = 400;
const HTTP_TOOLARGE_CODE = 413;
const HTTP_INTERNALERROR_CODE = 500;

// Enable cross-origin ressource sharing.
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept'
  );
  res.setHeader('Content-Type', 'application/json');
  next();
});

const args = config.cliArgs;
app.use(bodyParser.json({limit: args.limit}));
app.use(bodyParser.urlencoded({extended: true, limit: args.limit}));

const accessLogStream = fs.createWriteStream(args.logdir + '/access.log', {
  flags: 'a'
});

app.use(morgan('combined', {stream: accessLogStream}));

app.use(helmet());

app.use((err, req, res, next) => {
  if (
    err instanceof SyntaxError &&
    err.status === HTTP_ERROR_CODE &&
    'body' in err
  ) {
    const message =
      'Invalid JSON object in request, please add vehicles and jobs or shipments to the object body';
    console.log(now() + ': ' + JSON.stringify(message));
    res.status(HTTP_ERROR_CODE);
    res.send({
      code: config.vroomErrorCodes.input,
      error: message
    });
  }
});

// Simple date generator for console output.
const now = function() {
  const date = new Date();
  return date.toUTCString();
};

const logToFile = function(input) {
  const timestamp = Math.floor(Date.now() / 1000); //eslint-disable-line
  const fileName = args.logdir + '/' + timestamp + '_' + uuid.v1() + '.json';
  fs.writeFileSync(fileName, input, (err, data) => {
    if (err) {
      console.log(now() + err);
    }
  });

  return fileName;
};

const fileExists = function(filePath) {
  try {
    return fs.statSync(filePath).isFile();
  } catch (err) {
    return false;
  }
};

// Callback for size and some input validity checks.
const sizeCheckCallback = function(maxLocationNumber, maxVehicleNumber) {
  return function(req, res, next) {
    const hasJobs = 'jobs' in req.body;
    const hasShipments = 'shipments' in req.body;

    const correctInput = (hasJobs || hasShipments) && 'vehicles' in req.body;
    if (!correctInput) {
      const message =
        'Invalid JSON object in request, please add vehicles and jobs or shipments to the object body';
      console.error(now() + ': ' + JSON.stringify(message));
      res.status(HTTP_ERROR_CODE);
      res.send({
        code: config.vroomErrorCodes.input,
        error: message
      });
      return;
    }

    let nbLocations = 0;
    if (hasJobs) {
      nbLocations += req.body.jobs.length;
    }
    if (hasShipments) {
      nbLocations += 2 * req.body.shipments.length;
    }

    if (nbLocations > maxLocationNumber) {
      const message = [
        'Too many locations (',
        nbLocations,
        ') in query, maximum is set to',
        maxLocationNumber
      ].join(' ');
      console.error(now() + ': ' + JSON.stringify(message));
      res.status(HTTP_TOOLARGE_CODE);
      res.send({
        code: config.vroomErrorCodes.tooLarge,
        error: message
      });
      return;
    }
    if (req.body.vehicles.length > maxVehicleNumber) {
      const vehicles = req.body.vehicles.length;
      const message = [
        'Too many vehicles (',
        vehicles,
        ') in query, maximum is set to',
        maxVehicleNumber
      ].join(' ');
      console.error(now() + ': ' + JSON.stringify(message));
      res.status(HTTP_TOOLARGE_CODE);
      res.send({
        code: config.vroomErrorCodes.tooLarge,
        error: message
      });
      return;
    }
    next();
  };
};

// Cli wrapper and associated callback.
const spawn = require('child_process').spawn;

const vroomCommand = args.path + 'vroom';
const options = [];
options.push('-r', args.router);
if (args.router != 'libosrm') {
  const routingServers = config.routingServers;
  for (const profileName in routingServers) {
    const profile = routingServers[profileName];
    if ('host' in profile && 'port' in profile) {
      options.push('-a', profileName + ':' + profile.host);
      options.push('-p', profileName + ':' + profile.port);
    } else {
      console.error(
        "Incomplete configuration: profile '" +
          profileName +
          "' requires 'host' and 'port'."
      );
    }
  }
}
if (args.geometry) {
  options.push('-g');
}

const execCallback = function(req, res) {
  const reqOptions = options.slice();
  if (
    !args.geometry &&
    args.override &&
    'options' in req.body &&
    'g' in req.body.options &&
    req.body.options.g
  ) {
    reqOptions.push('-g');
  }

  const fileName = logToFile(JSON.stringify(req.body));
  reqOptions.push('-i ' + fileName);

  const vroom = spawn(vroomCommand, reqOptions, {shell: true});

  // Handle errors.
  vroom.on('error', err => {
    const message = ['Unknown internal error', err].join(': ');
    console.error(now() + ': ' + JSON.stringify(message));
    res.status(HTTP_INTERNALERROR_CODE);
    res.send({
      code: config.vroomErrorCodes.internal,
      error: message
    });
  });

  vroom.stderr.on('data', data => {
    console.error(now() + ': ' + data.toString());
  });

  // Handle solution. The temporary solution variable is required as
  // we also want to adjust the status that is only retrieved with
  // 'exit', after data is written in stdout.
  let solution = '';

  vroom.stdout.on('data', data => {
    solution += data.toString();
  });

  vroom.on('close', (code, signal) => {
    switch (code) {
      case config.vroomErrorCodes.ok:
        res.status(HTTP_OK_CODE);
        break;
      case config.vroomErrorCodes.internal:
        // Internal error.
        res.status(HTTP_INTERNALERROR_CODE);
        break;
      case config.vroomErrorCodes.input:
        // Input error.
        res.status(HTTP_ERROR_CODE);
        break;
      case config.vroomErrorCodes.routing:
        // Routing error.
        res.status(HTTP_INTERNALERROR_CODE);
        break;
      case 127: //eslint-disable-line
        // vroom not found on command line
        res.status(HTTP_INTERNALERROR_CODE);
        break;
    }
    res.send(solution);

    if (fileExists(fileName)) {
      fs.unlinkSync(fileName);
    }
  });
};

app.post('/', [
  sizeCheckCallback(args.maxlocations, args.maxvehicles),
  execCallback
]);

const server = app.listen(args.port, () => {
  console.log('vroom-express listening on port ' + args.port + '!');
});

server.setTimeout(args.timeout);
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ThemeProvider } from 'styled-components';
import App from './components/App';
import configureStore from './store/configureStore';
import theme from './theme';
// eslint-disable-next-line
import 'normalize.css';

const root = document.getElementById('root');
const store = configureStore();

// eslint-disable-next-line
const render = (Component, store) => ReactDOM.render(
    <Provider store={store}>
        <ThemeProvider theme={theme}>
            <Component />
        </ThemeProvider>
    </Provider>, root);

render(App, store);

if (process.env.NODE_ENV === 'development') {
    if (module.hot) {
        module.hot.accept('./components/App', async () => {
            const Next = await import('./components/App');
            render(Next.default, store);
        });
    }
}

<commit_msg>linter<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ThemeProvider } from 'styled-components';
import App from './components/App';
import configureStore from './store/configureStore';
import theme from './theme';
// eslint-disable-next-line
import 'normalize.css';

const root = document.getElementById('root');
const store = configureStore();

// eslint-disable-next-line
const render = (Component, store) => ReactDOM.render(
    <Provider store={store}>
        <ThemeProvider theme={theme}>
            <Component />
        </ThemeProvider>
    </Provider>,
    root,
);

render(App, store);

if (process.env.NODE_ENV === 'development') {
    if (module.hot) {
        module.hot.accept('./components/App', async () => {
            const Next = await import('./components/App');
            render(Next.default, store);
        });
    }
}
<|endoftext|>


<commit_before>/**
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

import os from 'os';
import jsdom from 'jsdom';
import loaderUtils from 'loader-utils';
import LibraryTemplatePlugin from 'webpack/lib/LibraryTemplatePlugin';
import NodeTemplatePlugin from 'webpack/lib/node/NodeTemplatePlugin';
import NodeTargetPlugin from 'webpack/lib/node/NodeTargetPlugin';
import { DefinePlugin } from 'webpack';
import MemoryFs from 'memory-fs';
import { runChildCompiler, getRootCompiler, getBestModuleExport, stringToModule, convertPathToRelative } from './util';
import { applyEntry } from './webpack-util';

// Used to annotate this plugin's hooks in Tappable invocations
const PLUGIN_NAME = 'prerender-loader';

// Internal name used for the output bundle (never written to disk)
const FILENAME = 'ssr-bundle.js';

// Searches for fields of the form {{prerender}} or {{prerender:./some/module}}
const PRERENDER_REG = /\{\{prerender(?::\s*([^}]+?)\s*)?\}\}/;

/**
 * prerender-loader can be applied to any HTML or JS file with the given options.
 * @public
 * @param {Options} options Options to control how Critters inlines CSS.
 *
 * @example
 * // webpack.config.js
 * module.exports = {
 *   plugins: [
 *     new HtmlWebpackPlugin({
 *       // `!!` tells webpack to skip any configured loaders for .html files
 *       // `?string` tells prerender-loader output a JS module exporting the HTML string
 *       template: '!!prerender-loader?string!index.html'
 *     })
 *   ]
 * }
 *
 * @example
 * // inline demo: assumes you have html-loader set up:
 * import prerenderedHtml from '!prerender-loader!./file.html';
 */
export default function PrerenderLoader (content) {
  const options = loaderUtils.getOptions(this) || {};
  const outputFilter = options.as === 'string' || options.string ? stringToModule : String;

  if (options.disabled === true) {
    return outputFilter(content);
  }

  // When applied to HTML, attempts to inject into a specified {{prerender}} field.
  // @note: this is only used when the entry module exports a String or function
  // that resolves to a String, otherwise the whole document is serialized.
  let inject = false;
  if (!this.request.match(/.(js|ts)x?$/i)) {
    const matches = content.match(PRERENDER_REG);
    if (matches) {
      inject = true;
      options.entry = matches[1];
    }
    options.templateContent = content;
  }

  const callback = this.async();

  prerender(this._compilation, this.request, options, inject, this)
    .then(output => {
      callback(null, outputFilter(output));
    })
    .catch(err => {
      // console.error(err);
      callback(err);
    });
}

async function prerender (parentCompilation, request, options, inject, loader) {
  const parentCompiler = getRootCompiler(parentCompilation.compiler);
  const context = parentCompiler.options.context || process.cwd();
  const customEntry = options.entry && ([].concat(options.entry).pop() || '').trim();
  const entry = customEntry ? ('./' + customEntry) : convertPathToRelative(context, parentCompiler.options.entry, './');

  const outputOptions = {
    // fix: some plugins ignore/bypass outputfilesystem, so use a temp directory and ignore any writes.
    path: os.tmpdir(),
    filename: FILENAME
  };

  // Only copy over allowed plugins (excluding them breaks extraction entirely).
  const allowedPlugins = ['MiniCssExtractPlugin', 'ExtractTextPlugin'];
  const plugins = (parentCompiler.options.plugins || []).filter(c => allowedPlugins.includes(c.constructor.name));

  // Compile to an in-memory filesystem since we just want the resulting bundled code as a string
  const compiler = parentCompilation.createChildCompiler('prerender', outputOptions, plugins);
  compiler.context = parentCompiler.context;
  compiler.outputFileSystem = new MemoryFs();

  // Define PRERENDER to be true within the SSR bundle
  new DefinePlugin({
    PRERENDER: 'true'
  }).apply(compiler);

  // ... then define PRERENDER to be false within the client bundle
  new DefinePlugin({
    PRERENDER: 'false'
  }).apply(parentCompiler);

  // Compile to CommonJS to be executed by Node
  new NodeTemplatePlugin(outputOptions).apply(compiler);
  new NodeTargetPlugin().apply(compiler);

  new LibraryTemplatePlugin('PRERENDER_RESULT', 'var').apply(compiler);

  // Kick off compilation at our entry module (either the parent compiler's entry or a custom one defined via `{{prerender:entry.js}}`)
  applyEntry(context, entry, compiler);

  // Set up cache inheritance for the child compiler
  const subCache = 'subcache ' + request;
  function addChildCache (compilation, data) {
    if (compilation.cache) {
      if (!compilation.cache[subCache]) compilation.cache[subCache] = {};
      compilation.cache = compilation.cache[subCache];
    }
  }
  if (compiler.hooks) {
    compiler.hooks.compilation.tap(PLUGIN_NAME, addChildCache);
  } else {
    compiler.plugin('compilation', addChildCache);
  }

  const compilation = await runChildCompiler(compiler);
  let result;
  let dom, window, injectParent, injectNextSibling;

  // A promise-like that never resolves and does not retain references to callbacks.
  function BrokenPromise () {}
  BrokenPromise.prototype.then = BrokenPromise.prototype.catch = BrokenPromise.prototype.finally = () => new BrokenPromise();

  if (compilation.assets[compilation.options.output.filename]) {
    // Get the compiled main bundle
    const output = compilation.assets[compilation.options.output.filename].source();

    // @TODO: provide a non-DOM option to allow turning off JSDOM entirely.

    const tpl = options.templateContent || '<!DOCTYPE html>';
    dom = new jsdom.JSDOM(tpl.replace(PRERENDER_REG, '

'), {
      // suppress console-proxied eval() errors, but keep console proxying
      virtualConsole: new jsdom.VirtualConsole({ omitJSDOMErrors: false }).sendTo(console),

      // `url` sets the value returned by `window.location`, `document.URL`...
      // Useful for routers that depend on the current URL (such as react-router or reach-router)
      url: options.documentUrl || 'http://localhost',

      // don't track source locations for performance reasons
      includeNodeLocations: false,

      // don't allow inline event handlers & script tag exec
      runScripts: 'outside-only'
    });
    window = dom.window;

    // Find the placeholder node for injection & remove it
    const injectPlaceholder = window.document.getElementById('PRERENDER_INJECT');
    if (injectPlaceholder) {
      injectParent = injectPlaceholder.parentNode;
      injectNextSibling = injectPlaceholder.nextSibling;
      injectPlaceholder.remove();
    }

    // These are missing from JSDOM
    let counter = 0;
    window.requestAnimationFrame = () => ++counter;
    window.cancelAnimationFrame = () => { };

    // Never prerender Custom Elements: by skipping registration, we get only the Light DOM which is desirable.
    window.customElements = {
      define () {},
      get () {},
      upgrade () {},
      whenDefined: () => new BrokenPromise()
    };

    // Fake MessagePort
    window.MessagePort = function () {
      (this.port1 = new window.EventTarget()).postMessage = () => {};
      (this.port2 = new window.EventTarget()).postMessage = () => {};
    };

    // Never matches
    window.matchMedia = () => ({ addListener () {} });

    // Never register ServiceWorkers
    if (!window.navigator) window.navigator = {};
    window.navigator.serviceWorker = {
      register: () => new BrokenPromise()
    };

    // When DefinePlugin isn't sufficient
    window.PRERENDER = true;

    // Inject a require shim
    window.require = moduleId => {
      const asset = compilation.assets[moduleId.replace(/^\.?\//g, '')];
      if (!asset) {
        throw Error(`Error:  Module not found. attempted require("${moduleId}")`);
      }
      const mod = { exports: {} };
      window.eval(`(function(exports, module, require){\n${asset.source()}\n})`)(mod.exports, mod, window.require);
      return mod.exports;
    };

    // Invoke the SSR bundle within the JSDOM document and grab the exported/returned result
    result = window.eval(output + '\nPRERENDER_RESULT');
  }

  // Deal with ES Module exports (just use the best guess):
  if (result && typeof result === 'object') {
    result = getBestModuleExport(result);
  }

  if (typeof result === 'function') {
    result = result(options.params || null);
  }

  // The entry can export or return a Promise in order to perform fully async prerendering:
  if (result && result.then) {
    result = await result;
  }

  // Returning or resolving to `null` / `undefined` defaults to serializing the whole document.
  // Note: this pypasses `inject` because the document is already derived from the template.
  if (result !== undefined && options.templateContent) {
    const template = window.document.createElement('template');
    template.innerHTML = result || '';
    const content = template.content || template;
    const parent = injectParent || window.document.body;
    let child;
    while ((child = content.firstChild)) {
      parent.insertBefore(child, injectNextSibling || null);
    }
  } else if (inject) {
    // Otherwise inject the prerendered HTML into the template
    return options.templateContent.replace(PRERENDER_REG, result || '');
  }

  // dom.serialize() doesn't properly serialize HTML appended to document.body.
  // return `<!DOCTYPE ${window.document.doctype.name}>${window.document.documentElement.outerHTML}`;
  let serialized = dom.serialize();
  if (!/^<!DOCTYPE /mi.test(serialized)) {
    serialized = `<!DOCTYPE html>${serialized}`;
  }
  return serialized;

  // // Returning or resolving to `null` / `undefined` defaults to serializing the whole document.
  // // Note: this pypasses `inject` because the document is already derived from the template.
  // if (result == null && dom) {
  //   // result = dom.serialize();
  // } else if (inject) {
  //   // @TODO determine if this is really worthwhile/necessary for the string return case
  //   if (injectParent || options.templateContent) {
  //     console.log(injectParent.outerHTML);
  //     (injectParent || document.body).insertAdjacentHTML('beforeend', result || '');
  //     // result = dom.serialize();
  //   } else {
  //     // Otherwise inject the prerendered HTML into the template
  //     return options.templateContent.replace(PRERENDER_REG, result || '');
  //   }
  // }

  // return dom.serialize();
  // return result;
}
<commit_msg>Switch to regex in case the casing was wrong<commit_after>/**
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

import os from 'os';
import jsdom from 'jsdom';
import loaderUtils from 'loader-utils';
import LibraryTemplatePlugin from 'webpack/lib/LibraryTemplatePlugin';
import NodeTemplatePlugin from 'webpack/lib/node/NodeTemplatePlugin';
import NodeTargetPlugin from 'webpack/lib/node/NodeTargetPlugin';
import { DefinePlugin } from 'webpack';
import MemoryFs from 'memory-fs';
import { runChildCompiler, getRootCompiler, getBestModuleExport, stringToModule, convertPathToRelative } from './util';
import { applyEntry } from './webpack-util';

// Used to annotate this plugin's hooks in Tappable invocations
const PLUGIN_NAME = 'prerender-loader';

// Internal name used for the output bundle (never written to disk)
const FILENAME = 'ssr-bundle.js';

// Searches for fields of the form {{prerender}} or {{prerender:./some/module}}
const PRERENDER_REG = /\{\{prerender(?::\s*([^}]+?)\s*)?\}\}/;

/**
 * prerender-loader can be applied to any HTML or JS file with the given options.
 * @public
 * @param {Options} options Options to control how Critters inlines CSS.
 *
 * @example
 * // webpack.config.js
 * module.exports = {
 *   plugins: [
 *     new HtmlWebpackPlugin({
 *       // `!!` tells webpack to skip any configured loaders for .html files
 *       // `?string` tells prerender-loader output a JS module exporting the HTML string
 *       template: '!!prerender-loader?string!index.html'
 *     })
 *   ]
 * }
 *
 * @example
 * // inline demo: assumes you have html-loader set up:
 * import prerenderedHtml from '!prerender-loader!./file.html';
 */
export default function PrerenderLoader (content) {
  const options = loaderUtils.getOptions(this) || {};
  const outputFilter = options.as === 'string' || options.string ? stringToModule : String;

  if (options.disabled === true) {
    return outputFilter(content);
  }

  // When applied to HTML, attempts to inject into a specified {{prerender}} field.
  // @note: this is only used when the entry module exports a String or function
  // that resolves to a String, otherwise the whole document is serialized.
  let inject = false;
  if (!this.request.match(/.(js|ts)x?$/i)) {
    const matches = content.match(PRERENDER_REG);
    if (matches) {
      inject = true;
      options.entry = matches[1];
    }
    options.templateContent = content;
  }

  const callback = this.async();

  prerender(this._compilation, this.request, options, inject, this)
    .then(output => {
      callback(null, outputFilter(output));
    })
    .catch(err => {
      // console.error(err);
      callback(err);
    });
}

async function prerender (parentCompilation, request, options, inject, loader) {
  const parentCompiler = getRootCompiler(parentCompilation.compiler);
  const context = parentCompiler.options.context || process.cwd();
  const customEntry = options.entry && ([].concat(options.entry).pop() || '').trim();
  const entry = customEntry ? ('./' + customEntry) : convertPathToRelative(context, parentCompiler.options.entry, './');

  const outputOptions = {
    // fix: some plugins ignore/bypass outputfilesystem, so use a temp directory and ignore any writes.
    path: os.tmpdir(),
    filename: FILENAME
  };

  // Only copy over allowed plugins (excluding them breaks extraction entirely).
  const allowedPlugins = /(MiniCssExtractPlugin|ExtractTextPlugin)/i;
  const plugins = (parentCompiler.options.plugins || []).filter(c => allowedPlugins.test(c.constructor.name));

  // Compile to an in-memory filesystem since we just want the resulting bundled code as a string
  const compiler = parentCompilation.createChildCompiler('prerender', outputOptions, plugins);
  compiler.context = parentCompiler.context;
  compiler.outputFileSystem = new MemoryFs();

  // Define PRERENDER to be true within the SSR bundle
  new DefinePlugin({
    PRERENDER: 'true'
  }).apply(compiler);

  // ... then define PRERENDER to be false within the client bundle
  new DefinePlugin({
    PRERENDER: 'false'
  }).apply(parentCompiler);

  // Compile to CommonJS to be executed by Node
  new NodeTemplatePlugin(outputOptions).apply(compiler);
  new NodeTargetPlugin().apply(compiler);

  new LibraryTemplatePlugin('PRERENDER_RESULT', 'var').apply(compiler);

  // Kick off compilation at our entry module (either the parent compiler's entry or a custom one defined via `{{prerender:entry.js}}`)
  applyEntry(context, entry, compiler);

  // Set up cache inheritance for the child compiler
  const subCache = 'subcache ' + request;
  function addChildCache (compilation, data) {
    if (compilation.cache) {
      if (!compilation.cache[subCache]) compilation.cache[subCache] = {};
      compilation.cache = compilation.cache[subCache];
    }
  }
  if (compiler.hooks) {
    compiler.hooks.compilation.tap(PLUGIN_NAME, addChildCache);
  } else {
    compiler.plugin('compilation', addChildCache);
  }

  const compilation = await runChildCompiler(compiler);
  let result;
  let dom, window, injectParent, injectNextSibling;

  // A promise-like that never resolves and does not retain references to callbacks.
  function BrokenPromise () {}
  BrokenPromise.prototype.then = BrokenPromise.prototype.catch = BrokenPromise.prototype.finally = () => new BrokenPromise();

  if (compilation.assets[compilation.options.output.filename]) {
    // Get the compiled main bundle
    const output = compilation.assets[compilation.options.output.filename].source();

    // @TODO: provide a non-DOM option to allow turning off JSDOM entirely.

    const tpl = options.templateContent || '<!DOCTYPE html>';
    dom = new jsdom.JSDOM(tpl.replace(PRERENDER_REG, '

'), {
      // suppress console-proxied eval() errors, but keep console proxying
      virtualConsole: new jsdom.VirtualConsole({ omitJSDOMErrors: false }).sendTo(console),

      // `url` sets the value returned by `window.location`, `document.URL`...
      // Useful for routers that depend on the current URL (such as react-router or reach-router)
      url: options.documentUrl || 'http://localhost',

      // don't track source locations for performance reasons
      includeNodeLocations: false,

      // don't allow inline event handlers & script tag exec
      runScripts: 'outside-only'
    });
    window = dom.window;

    // Find the placeholder node for injection & remove it
    const injectPlaceholder = window.document.getElementById('PRERENDER_INJECT');
    if (injectPlaceholder) {
      injectParent = injectPlaceholder.parentNode;
      injectNextSibling = injectPlaceholder.nextSibling;
      injectPlaceholder.remove();
    }

    // These are missing from JSDOM
    let counter = 0;
    window.requestAnimationFrame = () => ++counter;
    window.cancelAnimationFrame = () => { };

    // Never prerender Custom Elements: by skipping registration, we get only the Light DOM which is desirable.
    window.customElements = {
      define () {},
      get () {},
      upgrade () {},
      whenDefined: () => new BrokenPromise()
    };

    // Fake MessagePort
    window.MessagePort = function () {
      (this.port1 = new window.EventTarget()).postMessage = () => {};
      (this.port2 = new window.EventTarget()).postMessage = () => {};
    };

    // Never matches
    window.matchMedia = () => ({ addListener () {} });

    // Never register ServiceWorkers
    if (!window.navigator) window.navigator = {};
    window.navigator.serviceWorker = {
      register: () => new BrokenPromise()
    };

    // When DefinePlugin isn't sufficient
    window.PRERENDER = true;

    // Inject a require shim
    window.require = moduleId => {
      const asset = compilation.assets[moduleId.replace(/^\.?\//g, '')];
      if (!asset) {
        throw Error(`Error:  Module not found. attempted require("${moduleId}")`);
      }
      const mod = { exports: {} };
      window.eval(`(function(exports, module, require){\n${asset.source()}\n})`)(mod.exports, mod, window.require);
      return mod.exports;
    };

    // Invoke the SSR bundle within the JSDOM document and grab the exported/returned result
    result = window.eval(output + '\nPRERENDER_RESULT');
  }

  // Deal with ES Module exports (just use the best guess):
  if (result && typeof result === 'object') {
    result = getBestModuleExport(result);
  }

  if (typeof result === 'function') {
    result = result(options.params || null);
  }

  // The entry can export or return a Promise in order to perform fully async prerendering:
  if (result && result.then) {
    result = await result;
  }

  // Returning or resolving to `null` / `undefined` defaults to serializing the whole document.
  // Note: this pypasses `inject` because the document is already derived from the template.
  if (result !== undefined && options.templateContent) {
    const template = window.document.createElement('template');
    template.innerHTML = result || '';
    const content = template.content || template;
    const parent = injectParent || window.document.body;
    let child;
    while ((child = content.firstChild)) {
      parent.insertBefore(child, injectNextSibling || null);
    }
  } else if (inject) {
    // Otherwise inject the prerendered HTML into the template
    return options.templateContent.replace(PRERENDER_REG, result || '');
  }

  // dom.serialize() doesn't properly serialize HTML appended to document.body.
  // return `<!DOCTYPE ${window.document.doctype.name}>${window.document.documentElement.outerHTML}`;
  let serialized = dom.serialize();
  if (!/^<!DOCTYPE /mi.test(serialized)) {
    serialized = `<!DOCTYPE html>${serialized}`;
  }
  return serialized;

  // // Returning or resolving to `null` / `undefined` defaults to serializing the whole document.
  // // Note: this pypasses `inject` because the document is already derived from the template.
  // if (result == null && dom) {
  //   // result = dom.serialize();
  // } else if (inject) {
  //   // @TODO determine if this is really worthwhile/necessary for the string return case
  //   if (injectParent || options.templateContent) {
  //     console.log(injectParent.outerHTML);
  //     (injectParent || document.body).insertAdjacentHTML('beforeend', result || '');
  //     // result = dom.serialize();
  //   } else {
  //     // Otherwise inject the prerendered HTML into the template
  //     return options.templateContent.replace(PRERENDER_REG, result || '');
  //   }
  // }

  // return dom.serialize();
  // return result;
}
<|endoftext|>


<commit_before>// Here we export what we want to be accessible from the library to the developer

module.exports = {
	Hyperdeck: require("./hyperdeck/hyperdeck"),
	HyperdeckCore: require("./hypderdeck/core")
};
<commit_msg>fix typo<commit_after>// Here we export what we want to be accessible from the library to the developer

module.exports = {
	Hyperdeck: require("./hyperdeck/hyperdeck"),
	HyperdeckCore: require("./hyperdeck/core")
};
<|endoftext|>


<commit_before>'use strict';
import mutliTypeof from 'multi-typeof';

/**
 * Determine if string should be prepended with prependString
 * @param {String} string - string to prepend, conditionally
 * @param {String} prependString - string to prepend to string if string doesn't start with prependString
 * @return {Boolean} - should string be prepended with prependString?
 */
function defaultCondition(string, prependString) {
  return string.indexOf(prependString) !== 0;
}

/**
 * Prepend a string if a condition is met
 * @throws {TypeError} - if string or prependString is not a string
 * @param {String} string - string to prepend text to if condition is true
 * @param {String} prependString - string that should be prepended to string
 * @param {Function} [condition=defaultCondition] - if true, prepend string to string
 * @return {String} - string with prependString if condition is true, otherwise just string
 */
export default function prependIf(string, prependString, condition = defaultCondition) {
  if (typeof string !== 'string' || typeof prependString !== 'string') {
    throw new TypeError('Expected a string');
  }

  if (condition && !mutliTypeof(condition, ['boolean', 'function'])) {
    throw new TypeError('Expected a boolean or function');
  }

  if (typeof condition === 'boolean') {
    return condition ? prependString + string : string;
  }

  return condition(string, prependString) ? prependString + string : string;
}
<commit_msg>fix(src): use module.exports instead of export default<commit_after>'use strict';
import mutliTypeof from 'multi-typeof';

/**
 * Determine if string should be prepended with prependString
 * @param {String} string - string to prepend, conditionally
 * @param {String} prependString - string to prepend to string if string doesn't start with prependString
 * @return {Boolean} - should string be prepended with prependString?
 */
function defaultCondition(string, prependString) {
  return string.indexOf(prependString) !== 0;
}

/**
 * Prepend a string if a condition is met
 * @throws {TypeError} - if string or prependString is not a string
 * @param {String} string - string to prepend text to if condition is true
 * @param {String} prependString - string that should be prepended to string
 * @param {Function} [condition=defaultCondition] - if true, prepend string to string
 * @return {String} - string with prependString if condition is true, otherwise just string
 */
module.exports = function (string, prependString, condition = defaultCondition) {
  if (typeof string !== 'string' || typeof prependString !== 'string') {
    throw new TypeError('Expected a string');
  }

  if (condition && !mutliTypeof(condition, ['boolean', 'function'])) {
    throw new TypeError('Expected a boolean or function');
  }

  if (typeof condition === 'boolean') {
    return condition ? prependString + string : string;
  }

  return condition(string, prependString) ? prependString + string : string;
};
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM, {unstable_renderSubtreeIntoContainer as renderSubtreeIntoContainer} from 'react-dom'
import assign from 'object-assign'

class Card extends React.Component {
  static propTypes = {
    active: PropTypes.bool,
    position: PropTypes.oneOf([
      'top',
      'right',
      'bottom',
      'left'
    ]),
    arrow: PropTypes.oneOf([
      null,
      'center',
      'top',
      'right',
      'bottom',
      'left'
    ]),
    style: PropTypes.object
  }
  static defaultProps = {
    active: false,
    position: 'right',
    arrow: null,
    style: {style: {}, arrowStyle: {}}
  }
  state = {
    hover: false,
    transition: 'opacity',
    width: 0,
    height: 0
  }
  margin = 15
  defaultArrowStyle = {
    color: '#fff',
    borderColor: 'rgba(0,0,0,.4)'
  }
  getGlobalStyle() {
    if (!this.props.parentEl) {
      return {display: 'none'}
    }

    let style = {
      position: 'absolute',
      padding: '5px',
      background: '#fff',
      boxShadow: '0 0 8px rgba(0,0,0,.3)',
      borderRadius: '3px',
      transition: `${this.state.transition} .3s ease-in-out, visibility .3s ease-in-out`,
      opacity: this.state.hover || this.props.active ? 1 : 0,
      visibility: this.state.hover || this.props.active ? 'visible' : 'hidden',
      zIndex: 50
    }

    assign(style, this.getStyle(this.props.position, this.props.arrow))

    return this.mergeStyle(style, this.props.style.style)
  }
  getBaseArrowStyle() {
    return {
      position: 'absolute',
      content: '""',
      transition: 'all .3s ease-in-out'
    }
  }
  getArrowStyle() {
    let fgStyle = this.getBaseArrowStyle()
    let bgStyle = this.getBaseArrowStyle()
    fgStyle.zIndex = 60
    bgStyle.zIndex = 55

    let arrowStyle = assign(this.defaultArrowStyle, this.props.style.arrowStyle)
    let bgBorderColor = arrowStyle.borderColor ? arrowStyle.borderColor : 'transparent'

    let fgSize = 8
    let bgSize = 9
    let fgColorBorder = `10px solid ${arrowStyle.color}`
    let fgTransBorder = `${fgSize}px solid transparent`
    let bgColorBorder = `11px solid ${bgBorderColor}`
    let bgTransBorder = `${bgSize}px solid transparent`

    let {position, arrow} = this.props

    if (position === 'left' || position === 'right') {
      fgStyle.top = '50%'
      fgStyle.borderTop = fgTransBorder
      fgStyle.borderBottom = fgTransBorder
      fgStyle.marginTop = -7

      bgStyle.borderTop = bgTransBorder
      bgStyle.borderBottom = bgTransBorder
      bgStyle.top = '50%'
      bgStyle.marginTop = -8

      if (position === 'left') {
        fgStyle.right = -10
        fgStyle.borderLeft = fgColorBorder
        bgStyle.right = -11
        bgStyle.borderLeft = bgColorBorder
      }
      else {
        fgStyle.left = -10
        fgStyle.borderRight = fgColorBorder
        bgStyle.left = -11
        bgStyle.borderRight = bgColorBorder
      }

      if (arrow === 'top') {
        fgStyle.top = this.margin
        bgStyle.top = this.margin
      }
      if (arrow === 'bottom') {
        fgStyle.top = null
        fgStyle.bottom = this.margin - 7
        bgStyle.top = null
        bgStyle.bottom = this.margin - 8
      }
    }
    else {
      fgStyle.left = '50%'
      fgStyle.marginLeft = -10
      fgStyle.borderLeft = fgTransBorder
      fgStyle.borderRight = fgTransBorder
      bgStyle.left = '50%'
      bgStyle.marginLeft = -11
      bgStyle.borderLeft = bgTransBorder
      bgStyle.borderRight = bgTransBorder

      if (position === 'top') {
        fgStyle.bottom = -10
        fgStyle.borderTop = fgColorBorder
        bgStyle.bottom = -11
        bgStyle.borderTop = bgColorBorder
      }
      else {
        fgStyle.top = -10
        fgStyle.borderBottom = fgColorBorder
        bgStyle.top = -11
        bgStyle.borderBottom = bgColorBorder
      }

      if (arrow === 'right') {
        fgStyle.left = null
        fgStyle.right = this.margin + 1 - fgSize
        fgStyle.marginLeft = 0
        bgStyle.left = null
        bgStyle.right = this.margin - fgSize
        bgStyle.marginLeft = 0
      }
      if (arrow === 'left') {
        fgStyle.left = this.margin + 1 - fgSize
        fgStyle.marginLeft = 0
        bgStyle.left = this.margin - fgSize
        bgStyle.marginLeft = 0
      }
    }

    let {color, borderColor, ...propsArrowStyle} = this.props.style.arrowStyle

    return {
      fgStyle: this.mergeStyle(fgStyle, propsArrowStyle),
      bgStyle: this.mergeStyle(bgStyle, propsArrowStyle)
    }
  }
  mergeStyle(style, theme) {
    if (theme) {
      let {position, top, left, right, bottom, marginLeft, marginRight, ...validTheme} = theme

      return assign(style, validTheme)
    }

    return style
  }
  getStyle(position, arrow) {
    let parent = this.props.parentEl
    let tooltipPosition = parent.getBoundingClientRect()
    let scrollY = (window.scrollY !== undefined) ? window.scrollY : window.pageYOffset
    let scrollX = (window.scrollX !== undefined) ? window.scrollX : window.pageXOffset
    let top = scrollY + tooltipPosition.top
    let left = scrollX + tooltipPosition.left
    let style = {}

    const stylesFromPosition = {
      left: () => {
        style.top = top + parent.offsetHeight / 2 - this.state.height / 2
        style.left = left - this.state.width - this.margin
      },
      right: () => {
        style.top = top + parent.offsetHeight / 2 - this.state.height / 2
        style.left = left + parent.offsetWidth + this.margin
      },
      top: () => {
        style.left = left - this.state.width / 2 + parent.offsetWidth / 2
        style.top = top - this.state.height - this.margin
      },
      bottom: () => {
        style.left = left - this.state.width / 2 + parent.offsetWidth / 2
        style.top = top + parent.offsetHeight + this.margin
      },
    }

    const stylesFromArrow = {
      left: () => {
        style.left = left + parent.offsetWidth / 2 - this.margin
      },
      right: () => {
        style.left = left - this.state.width + parent.offsetWidth / 2 + this.margin
      },
      top: () => {
        style.top = top + parent.offsetHeight / 2 - this.margin
      },
      bottom: () => {
        style.top = top + parent.offsetHeight / 2 - this.state.height + this.margin
      },
    }

    executeFunctionIfExist(stylesFromPosition, position)
    executeFunctionIfExist(stylesFromArrow, arrow)

    return style
  }
  checkWindowPosition(style, arrowStyle) {
    if (this.props.position === 'top' || this.props.position === 'bottom') {
      if (style.left < 0) {
        let offset = style.left
        style.left = this.margin
        arrowStyle.fgStyle.marginLeft += offset
        arrowStyle.bgStyle.marginLeft += offset
      }
      else {
        let rightOffset = style.left + this.state.width - window.innerWidth
        if (rightOffset > 0) {
          let originalLeft = style.left
          style.left = window.innerWidth - this.state.width - this.margin
          arrowStyle.fgStyle.marginLeft += originalLeft - style.left
          arrowStyle.bgStyle.marginLeft += originalLeft - style.left
        }
      }
    }

    return {style, arrowStyle}
  }
  handleMouseEnter() {
    this.props.active && this.setState({hover: true})
  }
  handleMouseLeave() {
    this.setState({hover: false})
  }
  componentDidMount() {
    this.updateSize()
  }
  componentWillReceiveProps() {
    this.setState({transition: this.state.hover || this.props.active ? 'all' : 'opacity'}, () => {
      this.updateSize()
    })
  }
  updateSize() {
    let self = ReactDOM.findDOMNode(this)
    this.setState({
      width: self.offsetWidth,
      height: self.offsetHeight
    })
  }
  render() {
    let {style, arrowStyle} = this.checkWindowPosition(this.getGlobalStyle(), this.getArrowStyle())

    return (

        {this.props.arrow ? (

)
          : null
        }
        {this.props.children}

    )
  }
}

var portalNodes = {}

export default class ToolTip extends React.Component {
  static propTypes = {
    parent: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.object
    ]).isRequired,
    active: PropTypes.bool,
    group: PropTypes.string,
    tooltipTimeout: PropTypes.number
  }
  static defaultProps = {
    active: false,
    group: 'main',
    tooltipTimeout: 500
  }
  componentDidMount() {
    if (!this.props.active) {
      return
    }

    this.renderPortal(this.props)
  }
  componentWillReceiveProps(nextProps) {
    if ((!portalNodes[this.props.group] && !nextProps.active) ||
      (!this.props.active && !nextProps.active)) {
      return
    }

    let props = assign({}, nextProps)
    let newProps = assign({}, nextProps)

    if (portalNodes[this.props.group] && portalNodes[this.props.group].timeout) {
      clearTimeout(portalNodes[this.props.group].timeout)
    }

    if (this.props.active && !props.active) {
      newProps.active = true
      portalNodes[this.props.group].timeout = setTimeout(() => {
        props.active = false
        this.renderPortal(props)
      }, this.props.tooltipTimeout)
    }

    this.renderPortal(newProps)
  }
  componentWillUnmount() {
    if (portalNodes[this.props.group]) {
      ReactDOM.unmountComponentAtNode(portalNodes[this.props.group].node)
      clearTimeout(portalNodes[this.props.group].timeout)
    }
  }
  createPortal() {
    portalNodes[this.props.group] = {
      node: document.createElement('div'),
      timeout: false
    }
    portalNodes[this.props.group].node.className = 'ToolTipPortal'
    document.body.appendChild(portalNodes[this.props.group].node)
  }
  renderPortal(props) {
    if (!portalNodes[this.props.group]) {
      this.createPortal()
    }
    let {parent, ...other} = props
    let parentEl = typeof parent === 'string' ? document.querySelector(parent) : parent
    renderSubtreeIntoContainer(this, <Card parentEl={parentEl} {...other}/>, portalNodes[this.props.group].node)
  }
  shouldComponentUpdate() {
    return false
  }
  render() {
    return null
  }
}

const executeFunctionIfExist = (object, key) => {
  if (Object.prototype.hasOwnProperty.call(object, key)){
    object[key]()
  }
}
<commit_msg>fix tooltip arrow position<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM, {unstable_renderSubtreeIntoContainer as renderSubtreeIntoContainer} from 'react-dom'
import assign from 'object-assign'

class Card extends React.Component {
  static propTypes = {
    active: PropTypes.bool,
    position: PropTypes.oneOf([
      'top',
      'right',
      'bottom',
      'left'
    ]),
    arrow: PropTypes.oneOf([
      null,
      'center',
      'top',
      'right',
      'bottom',
      'left'
    ]),
    style: PropTypes.object
  }
  static defaultProps = {
    active: false,
    position: 'right',
    arrow: null,
    style: {style: {}, arrowStyle: {}}
  }
  state = {
    hover: false,
    transition: 'opacity',
    width: 0,
    height: 0
  }
  margin = 15
  defaultArrowStyle = {
    color: '#fff',
    borderColor: 'rgba(0,0,0,.4)'
  }
  getGlobalStyle() {
    if (!this.props.parentEl) {
      return {display: 'none'}
    }

    let style = {
      position: 'absolute',
      padding: '5px',
      background: '#fff',
      boxShadow: '0 0 8px rgba(0,0,0,.3)',
      borderRadius: '3px',
      transition: `${this.state.transition} .3s ease-in-out, visibility .3s ease-in-out`,
      opacity: this.state.hover || this.props.active ? 1 : 0,
      visibility: this.state.hover || this.props.active ? 'visible' : 'hidden',
      zIndex: 50
    }

    assign(style, this.getStyle(this.props.position, this.props.arrow))

    return this.mergeStyle(style, this.props.style.style)
  }
  getBaseArrowStyle() {
    return {
      position: 'absolute',
      content: '""',
      transition: 'all .3s ease-in-out'
    }
  }
  getArrowStyle() {
    let fgStyle = this.getBaseArrowStyle()
    let bgStyle = this.getBaseArrowStyle()
    fgStyle.zIndex = 60
    bgStyle.zIndex = 55

    let arrowStyle = assign(this.defaultArrowStyle, this.props.style.arrowStyle)
    let bgBorderColor = arrowStyle.borderColor ? arrowStyle.borderColor : 'transparent'

    let fgSize = 8
    let bgSize = 9
    let fgColorBorder = `10px solid ${arrowStyle.color}`
    let fgTransBorder = `${fgSize}px solid transparent`
    let bgColorBorder = `11px solid ${bgBorderColor}`
    let bgTransBorder = `${bgSize}px solid transparent`

    let {position, arrow} = this.props

    if (position === 'left' || position === 'right') {
      fgStyle.top = '50%'
      fgStyle.borderTop = fgTransBorder
      fgStyle.borderBottom = fgTransBorder
      fgStyle.marginTop = -7

      bgStyle.borderTop = bgTransBorder
      bgStyle.borderBottom = bgTransBorder
      bgStyle.top = '50%'
      bgStyle.marginTop = -8

      if (position === 'left') {
        fgStyle.right = -10
        fgStyle.borderLeft = fgColorBorder
        bgStyle.right = -11
        bgStyle.borderLeft = bgColorBorder
      }
      else {
        fgStyle.left = -10
        fgStyle.borderRight = fgColorBorder
        bgStyle.left = -11
        bgStyle.borderRight = bgColorBorder
      }

      if (arrow === 'top') {
        fgStyle.top = this.margin
        bgStyle.top = this.margin
      }
      if (arrow === 'bottom') {
        fgStyle.top = null
        fgStyle.bottom = this.margin - 7
        bgStyle.top = null
        bgStyle.bottom = this.margin - 8
      }
    }
    else {
      fgStyle.left = '50%'
      fgStyle.marginLeft = -10
      fgStyle.borderLeft = fgTransBorder
      fgStyle.borderRight = fgTransBorder
      bgStyle.left = '50%'
      bgStyle.marginLeft = -11
      bgStyle.borderLeft = bgTransBorder
      bgStyle.borderRight = bgTransBorder

      if (position === 'top') {
        fgStyle.bottom = -10
        fgStyle.borderTop = fgColorBorder
        bgStyle.bottom = -11
        bgStyle.borderTop = bgColorBorder
      }
      else {
        fgStyle.top = -10
        fgStyle.borderBottom = fgColorBorder
        bgStyle.top = -11
        bgStyle.borderBottom = bgColorBorder
      }

      if (arrow === 'right') {
        fgStyle.left = null
        fgStyle.right = this.margin + 1 - fgSize
        fgStyle.marginLeft = 0
        bgStyle.left = null
        bgStyle.right = this.margin - fgSize
        bgStyle.marginLeft = 0
      }
      if (arrow === 'left') {
        fgStyle.left = this.margin + 1 - fgSize
        fgStyle.marginLeft = 0
        bgStyle.left = this.margin - fgSize
        bgStyle.marginLeft = 0
      }
    }

    let {color, borderColor, ...propsArrowStyle} = this.props.style.arrowStyle

    return {
      fgStyle: this.mergeStyle(fgStyle, propsArrowStyle),
      bgStyle: this.mergeStyle(bgStyle, propsArrowStyle)
    }
  }
  mergeStyle(style, theme) {
    if (theme) {
      let {position, top, left, right, bottom, marginLeft, marginRight, ...validTheme} = theme

      return assign(style, validTheme)
    }

    return style
  }
  getStyle(position, arrow) {
    let parent = this.props.parentEl
    let tooltipPosition = parent.getBoundingClientRect()
    let scrollY = (window.scrollY !== undefined) ? window.scrollY : window.pageYOffset
    let scrollX = (window.scrollX !== undefined) ? window.scrollX : window.pageXOffset
    let top = scrollY + tooltipPosition.top
    let left = scrollX + tooltipPosition.left
    let style = {}

    const stylesFromPosition = {
      left: () => {
        style.top = top + parent.offsetHeight / 2 - this.state.height / 2
        style.left = left - this.state.width - this.margin
      },
      right: () => {
        style.top = top + parent.offsetHeight / 2 - this.state.height / 2
        style.left = left + parent.offsetWidth + this.margin
      },
      top: () => {
        style.left = left - this.state.width / 2 + parent.offsetWidth / 2
        style.top = top - this.state.height - this.margin
      },
      bottom: () => {
        style.left = left - this.state.width / 2 + parent.offsetWidth / 2
        style.top = top + parent.offsetHeight + this.margin
      },
    }

    const stylesFromArrow = {
      left: () => {
        style.left = left + parent.offsetWidth / 2 - this.margin
      },
      right: () => {
        style.left = left - this.state.width + parent.offsetWidth / 2 + this.margin
      },
      top: () => {
        style.top = top + parent.offsetHeight / 2 - this.margin
      },
      bottom: () => {
        style.top = top + parent.offsetHeight / 2 - this.state.height + this.margin
      },
    }

    executeFunctionIfExist(stylesFromPosition, position)
    executeFunctionIfExist(stylesFromArrow, arrow)

    return style
  }
  checkWindowPosition(style, arrowStyle) {
    if (this.props.position === 'top' || this.props.position === 'bottom') {
      if (style.left < 0) {
        const parent = this.props.parentEl
        if (parent && this.tooltipref) {
          const tooltipWidth = this.tooltipref.offsetWidth
          const parentWidth = parent.offsetWidth
          const newBgRight = Math.round(arrowStyle.bgStyle.right - style.left + this.margin)
          arrowStyle = Object.assign({}, arrowStyle, {
            bgStyle: Object.assign({}, arrowStyle.bgStyle, {right: newBgRight}),
            fgStyle: Object.assign({}, arrowStyle.fgStyle, {right: newBgRight + 1})
          })
        }
        style.left = this.margin
      }
      else {
        let rightOffset = style.left + this.state.width - window.innerWidth
        if (rightOffset > 0) {
          let originalLeft = style.left
          style.left = window.innerWidth - this.state.width - this.margin
          arrowStyle.fgStyle.marginLeft += originalLeft - style.left
          arrowStyle.bgStyle.marginLeft += originalLeft - style.left
        }
      }
    }
    return {style, arrowStyle}
  }
  handleMouseEnter() {
    this.props.active && this.setState({hover: true})
  }
  handleMouseLeave() {
    this.setState({hover: false})
  }
  componentDidMount() {
    this.updateSize()
  }
  componentWillReceiveProps() {
    this.setState({transition: this.state.hover || this.props.active ? 'all' : 'opacity'}, () => {
      this.updateSize()
    })
  }
  updateSize() {
    let self = ReactDOM.findDOMNode(this)
    this.setState({
      width: self.offsetWidth,
      height: self.offsetHeight
    })
  }
  render() {
    let {style, arrowStyle} = this.checkWindowPosition(this.getGlobalStyle(), this.getArrowStyle())

    return (

 this.tooltipref = node} style={style} onMouseEnter={::this.handleMouseEnter} onMouseLeave={::this.handleMouseLeave}>
        {this.props.arrow ? (

)
          : null
        }
        {this.props.children}

    )
  }
}

var portalNodes = {}

export default class ToolTip extends React.Component {
  static propTypes = {
    parent: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.object
    ]).isRequired,
    active: PropTypes.bool,
    group: PropTypes.string,
    tooltipTimeout: PropTypes.number
  }
  static defaultProps = {
    active: false,
    group: 'main',
    tooltipTimeout: 500
  }
  componentDidMount() {
    if (!this.props.active) {
      return
    }

    this.renderPortal(this.props)
  }
  componentWillReceiveProps(nextProps) {
    if ((!portalNodes[this.props.group] && !nextProps.active) ||
      (!this.props.active && !nextProps.active)) {
      return
    }

    let props = assign({}, nextProps)
    let newProps = assign({}, nextProps)

    if (portalNodes[this.props.group] && portalNodes[this.props.group].timeout) {
      clearTimeout(portalNodes[this.props.group].timeout)
    }

    if (this.props.active && !props.active) {
      newProps.active = true
      portalNodes[this.props.group].timeout = setTimeout(() => {
        props.active = false
        this.renderPortal(props)
      }, this.props.tooltipTimeout)
    }

    this.renderPortal(newProps)
  }
  componentWillUnmount() {
    if (portalNodes[this.props.group]) {
      ReactDOM.unmountComponentAtNode(portalNodes[this.props.group].node)
      clearTimeout(portalNodes[this.props.group].timeout)
    }
  }
  createPortal() {
    portalNodes[this.props.group] = {
      node: document.createElement('div'),
      timeout: false
    }
    portalNodes[this.props.group].node.className = 'ToolTipPortal'
    document.body.appendChild(portalNodes[this.props.group].node)
  }
  renderPortal(props) {
    if (!portalNodes[this.props.group]) {
      this.createPortal()
    }
    let {parent, ...other} = props
    let parentEl = typeof parent === 'string' ? document.querySelector(parent) : parent
    renderSubtreeIntoContainer(this, <Card parentEl={parentEl} {...other}/>, portalNodes[this.props.group].node)
  }
  shouldComponentUpdate() {
    return false
  }
  render() {
    return null
  }
}

const executeFunctionIfExist = (object, key) => {
  if (Object.prototype.hasOwnProperty.call(object, key)){
    object[key]()
  }
}
<|endoftext|>


<commit_before>
const {
  ObjetosEstandard,
  fundamentalObjects,
  globalFunctions,
  globalProperties,
  PropiedadesMetodosDeObjetosEstandard
} = require('./diccionario');

module.exports = function jaibascript({types: t}) {
  return {
    name: 'jaibascript',
    visitor: {
      CallExpression(path) {
        const callee = ObjetosEstandard[path.node.callee.name] ||
          globalFunctions[path.node.callee.name] || fundamentalObjects[path.node.callee.name];

        if (callee) {
          path.node.callee = t.identifier(callee);
        }
      },
      ExpressionStatement(path) {
        const expressionName = globalProperties[path.node.expression.name];

        if (expressionName) {
          path.node.expression = t.identifier(expressionName);
        }
      },
      MemberExpression(path) {
        const objectName = (path.node.object || {}).name || '';
        const primitiveIdentifier = ObjetosEstandard[objectName];

        if (primitiveIdentifier) {
          path.node.object = t.identifier(primitiveIdentifier);
        }

        const property = PropiedadesMetodosDeObjetosEstandard[path.node.property.name];

        if (property) {
          path.node.property = t.identifier(property);
        }
      },
      NewExpression(path) {
        const callee = ObjetosEstandard[path.node.callee.name];

        if (callee) {
          path.node.callee = t.identifier(callee);
        }
      },
    }
  }
};
<commit_msg>Remaping objects<commit_after>
const {
  fundamentalObjects,
  globalFunctions,
  globalProperties,
  indexedCollections,
  numbersAndDates,
  PropiedadesMetodosDeObjetosEstandard,
  textProcessing,
} = require('./diccionario');

const ObjetosEstandard = {};

module.exports = function jaibascript({types: t}) {
  return {
    name: 'jaibascript',
    visitor: {
      CallExpression(path) {
        const calleeName = path.node.callee.name;

        const callee = numbersAndDates[calleeName] ||
          indexedCollections[calleeName] ||
          globalFunctions[calleeName] ||
          fundamentalObjects[calleeName];

        if (callee) {
          path.node.callee = t.identifier(callee);
        }
      },
      ExpressionStatement(path) {
        const nodeExpressionName = path.node.expression.name;
        const expressionName = globalProperties[nodeExpressionName];

        if (expressionName) {
          path.node.expression = t.identifier(expressionName);
        }
      },
      MemberExpression(path) {
        const objectName = (path.node.object || {}).name || '';

        const primitiveIdentifier = indexedCollections[objectName] || numbersAndDates[objectName] || textProcessing[objectName];

        if (primitiveIdentifier) {
          path.node.object = t.identifier(primitiveIdentifier);
        }

        const property = PropiedadesMetodosDeObjetosEstandard[path.node.property.name];

        if (property) {
          path.node.property = t.identifier(property);
        }
      },
      NewExpression(path) {
        const callee = numbersAndDates[path.node.callee.name];

        if (callee) {
          path.node.callee = t.identifier(callee);
        }
      },
    }
  }
};
<|endoftext|>


<commit_before>function trimDots(ary) {
  var i, part;
  for (i = 0; i < ary.length; ++i) {
      part = ary[i];
      if (part === '.') {
          ary.splice(i, 1);
          i -= 1;
      } else if (part === '..') {
          // If at the start, or previous value is still ..,
          // keep them so that when converted to a path it may
          // still work when converted to a path, even though
          // as an ID it is less than ideal. In larger point
          // releases, may be better to just kick out an error.
          if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') {
              continue;
          } else if (i > 0) {
              ary.splice(i - 1, 2);
              i -= 2;
          }
      }
  }
}

export function relativeToFile(name, file){
  var lastIndex,
      normalizedBaseParts,
      fileParts = (file && file.split('/'));

  name = name.trim();
  name = name.split('/');

  if (name[0].charAt(0) === '.' && fileParts) {
      //Convert file to array, and lop off the last part,
      //so that . matches that 'directory' and not name of the file's
      //module. For instance, file of 'one/two/three', maps to
      //'one/two/three.js', but we want the directory, 'one/two' for
      //this normalization.
      normalizedBaseParts = fileParts.slice(0, fileParts.length - 1);
      name = normalizedBaseParts.concat(name);
  }

  trimDots(name);

  return name.join('/');
}

export function join(path1, path2) {
  var url1, url2, url3, i, ii, urlPrefix;

  if(!path1){
    return path2;
  }

  if(!path2){
    return path1;
  }

  urlPrefix = path1.indexOf('//') === 0 ? '//' :
              path1.indexOf('/') === 0 ? '/' : '';
  trailingSlash = path2.slice(-1) == '/' ? '/' : '';

  url1 = path1.split('/');
  url2 = path2.split('/');
  url3 = [];

  for (i = 0, ii = url1.length; i < ii; ++i) {
    if (url1[i] == '..') {
      url3.pop();
    } else if (url1[i] == '.' || url1[i] == '') {
      continue;
    } else {
      url3.push(url1[i]);
    }
  }

  for (i = 0, ii = url2.length; i < ii; ++i) {
    if (url2[i] == '..') {
      url3.pop();
    } else if (url2[i] == '.' || url2[i] == '') {
      continue;
    } else {
      url3.push(url2[i]);
    }
  }

  return urlPrefix + url3.join('/').replace(/\:\//g, '://') + trailingSlash;
}

var r20 = /%20/g,
    rbracket = /\[\]$/,
    class2type = {};

'Boolean Number String Function Array Date RegExp Object Error'.split(' ').forEach((name, i) => {
  class2type['[object ' + name + ']'] = name.toLowerCase();
});

function type( obj ){
  if (obj == null){
    return obj + "";
  }

  // Support: Android<4.0 (functionish RegExp)
  return typeof obj === 'object' || typeof obj === 'function'
    ? class2type[ toString.call(obj) ] || 'object'
    : typeof obj;
}

export function buildQueryString(a, traditional){
  var prefix,
      s = [],
      add = function(key, value) {
        // If value is a function, invoke it and return its value
        value = typeof value === 'function' ? value() : (value == null ? '' : value);
        s[s.length] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
      };

  for(prefix in a){
    _buildQueryString(prefix, a[prefix], traditional, add);
  }

  // Return the resulting serialization
  return s.join('&').replace(r20, '+');
}

function _buildQueryString(prefix, obj, traditional, add){
  var name;

  if (Array.isArray(obj)){
    // Serialize array item.
    obj.forEach((v, i) => {
      if(traditional || rbracket.test(prefix)){
        // Treat each array item as a scalar.
        add(prefix, v);
      } else{
        // Item is non-scalar (array or object), encode its numeric index.
        _buildQueryString(
          prefix + '[' + (typeof v === 'object' ? i : '') + ']',
          v,
          traditional,
          add
        );
      }
    });
  } else if (!traditional && type(obj) === 'object'){
    // Serialize object item.
    for (name in obj) {
      _buildQueryString(prefix + '[' + name + ']', obj[name], traditional, add);
    }
  } else{
    // Serialize scalar item.
    add(prefix, obj);
  }
}
<commit_msg>fix(Path): declare trailingSlash<commit_after>function trimDots(ary) {
  var i, part;
  for (i = 0; i < ary.length; ++i) {
      part = ary[i];
      if (part === '.') {
          ary.splice(i, 1);
          i -= 1;
      } else if (part === '..') {
          // If at the start, or previous value is still ..,
          // keep them so that when converted to a path it may
          // still work when converted to a path, even though
          // as an ID it is less than ideal. In larger point
          // releases, may be better to just kick out an error.
          if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') {
              continue;
          } else if (i > 0) {
              ary.splice(i - 1, 2);
              i -= 2;
          }
      }
  }
}

export function relativeToFile(name, file){
  var lastIndex,
      normalizedBaseParts,
      fileParts = (file && file.split('/'));

  name = name.trim();
  name = name.split('/');

  if (name[0].charAt(0) === '.' && fileParts) {
      //Convert file to array, and lop off the last part,
      //so that . matches that 'directory' and not name of the file's
      //module. For instance, file of 'one/two/three', maps to
      //'one/two/three.js', but we want the directory, 'one/two' for
      //this normalization.
      normalizedBaseParts = fileParts.slice(0, fileParts.length - 1);
      name = normalizedBaseParts.concat(name);
  }

  trimDots(name);

  return name.join('/');
}

export function join(path1, path2) {
  var url1, url2, url3, i, ii, urlPrefix, trailingSlash;

  if(!path1){
    return path2;
  }

  if(!path2){
    return path1;
  }

  urlPrefix = path1.indexOf('//') === 0 ? '//' :
              path1.indexOf('/') === 0 ? '/' : '';
  trailingSlash = path2.slice(-1) == '/' ? '/' : '';

  url1 = path1.split('/');
  url2 = path2.split('/');
  url3 = [];

  for (i = 0, ii = url1.length; i < ii; ++i) {
    if (url1[i] == '..') {
      url3.pop();
    } else if (url1[i] == '.' || url1[i] == '') {
      continue;
    } else {
      url3.push(url1[i]);
    }
  }

  for (i = 0, ii = url2.length; i < ii; ++i) {
    if (url2[i] == '..') {
      url3.pop();
    } else if (url2[i] == '.' || url2[i] == '') {
      continue;
    } else {
      url3.push(url2[i]);
    }
  }

  return urlPrefix + url3.join('/').replace(/\:\//g, '://') + trailingSlash;
}

var r20 = /%20/g,
    rbracket = /\[\]$/,
    class2type = {};

'Boolean Number String Function Array Date RegExp Object Error'.split(' ').forEach((name, i) => {
  class2type['[object ' + name + ']'] = name.toLowerCase();
});

function type( obj ){
  if (obj == null){
    return obj + "";
  }

  // Support: Android<4.0 (functionish RegExp)
  return typeof obj === 'object' || typeof obj === 'function'
    ? class2type[ toString.call(obj) ] || 'object'
    : typeof obj;
}

export function buildQueryString(a, traditional){
  var prefix,
      s = [],
      add = function(key, value) {
        // If value is a function, invoke it and return its value
        value = typeof value === 'function' ? value() : (value == null ? '' : value);
        s[s.length] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
      };

  for(prefix in a){
    _buildQueryString(prefix, a[prefix], traditional, add);
  }

  // Return the resulting serialization
  return s.join('&').replace(r20, '+');
}

function _buildQueryString(prefix, obj, traditional, add){
  var name;

  if (Array.isArray(obj)){
    // Serialize array item.
    obj.forEach((v, i) => {
      if(traditional || rbracket.test(prefix)){
        // Treat each array item as a scalar.
        add(prefix, v);
      } else{
        // Item is non-scalar (array or object), encode its numeric index.
        _buildQueryString(
          prefix + '[' + (typeof v === 'object' ? i : '') + ']',
          v,
          traditional,
          add
        );
      }
    });
  } else if (!traditional && type(obj) === 'object'){
    // Serialize object item.
    for (name in obj) {
      _buildQueryString(prefix + '[' + name + ']', obj[name], traditional, add);
    }
  } else{
    // Serialize scalar item.
    add(prefix, obj);
  }
}
<|endoftext|>


<commit_before>import React from "react";
import ReactDOM from "react-dom";
import $ from "jquery";
import StandardLib from "../outts/Utils/StandardLib";
/* eslint-disable */
import WeaveLayoutManager from "./WeaveLayoutManager.jsx";
/* eslint-enable */

/*global Weave, weavejs*/

var weave = window.weave || (opener && opener.weave);

var urlParams = StandardLib.getUrlParams();
if (!weave && urlParams.file)
{
	weavejs.core.WeaveArchive.loadUrl(weave, urlParams.file).then(() => {
		$(() => {
			ReactDOM.render(<WeaveLayoutManager weave={weave}/>,	document.getElementById("weaveElt"));
		});
	});
}
else
{
	$(() => {
		ReactDOM.render(<WeaveLayoutManager weave={weave}/>,	document.getElementById("weaveElt"));
	});
}
<commit_msg>added weave instantiation<commit_after>import React from "react";
import ReactDOM from "react-dom";
import $ from "jquery";
import StandardLib from "../outts/Utils/StandardLib";
/* eslint-disable */
import WeaveLayoutManager from "./WeaveLayoutManager.jsx";
/* eslint-enable */

/*global Weave, weavejs*/

var weave = window.weave || (opener && opener.weave);

var urlParams = StandardLib.getUrlParams();
if (!weave && urlParams.file)
{
	weave = new Weave();
	weavejs.core.WeaveArchive.loadUrl(weave, urlParams.file).then(() => {
		$(() => {
			ReactDOM.render(<WeaveLayoutManager weave={weave}/>,	document.getElementById("weaveElt"));
		});
	});
}
else
{
	$(() => {
		ReactDOM.render(<WeaveLayoutManager weave={weave}/>,	document.getElementById("weaveElt"));
	});
}
<|endoftext|>


<commit_before>import React from 'react';
import App from './components/app';
import {
  encryptText
} from './crypto/api';
require('style!purecss');
require('style!./css/css.css');

React.render(<App />, document.getElementById('root'));

encryptText('hello');
<commit_msg>Revert "add decoder"<commit_after>import React from 'react';
import App from './components/app';
require('style!purecss');
require('style!./css/css.css');

React.render(<App />, document.getElementById('root'));
<|endoftext|>


<commit_before>/**
 * Insert elements into sorted array using binary search to indentify correct index
 * @module lib/index
 */

module.exports = binarySearchInsert

/**
 * @param {Array} sortedArray
 * @param {*} item
 * @param {Function} comparator
 * @return Number
 */
function binarySearchInsert (sortedArray, item, comparator) {
  var low = 0;
  var high = sortedArray.length - 1;
  var lastIndex = high;

  if (high === -1) {
    sortedArray.push(item);
    return 0;
  }

  var mid;
  while (low <= high) {
    // https://github.com/darkskyapp/binary-search
    // http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
    mid = low + (high - low >> 1);
    let cmp = comparator(sortedArray[mid], item);
    if (cmp <= 0.0) {
      // searching too low
      low = mid + 1;
    } else {
      // searching too high
      high = mid - 1;
    }
  }

  if (mid === lastIndex) {
    let cmp = comparator(sortedArray[mid], item);
    if (cmp <= 0.0) {
      mid++;
    }
  }

  sortedArray.splice(mid, 0, item)
  return mid;
}
<commit_msg>Define and initialize variables at top of func body<commit_after>/**
 * Insert elements into sorted array using binary search to indentify correct index
 * @module lib/index
 */

module.exports = binarySearchInsert

/**
 * @param {Array} sortedArray
 * @param {*} item
 * @param {Function} comparator
 * @return Number
 */
function binarySearchInsert (sortedArray, item, comparator) {
  var high = sortedArray.length - 1;
  var lastIndex = high;
  var low = 0;
  var mid;

  if (high === -1) {
    sortedArray.push(item);
    return 0;
  }

  while (low <= high) {
    // https://github.com/darkskyapp/binary-search
    // http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
    mid = low + (high - low >> 1);
    let cmp = comparator(sortedArray[mid], item);
    if (cmp <= 0.0) {
      // searching too low
      low = mid + 1;
    } else {
      // searching too high
      high = mid - 1;
    }
  }

  if (mid === lastIndex) {
    let cmp = comparator(sortedArray[mid], item);
    if (cmp <= 0.0) {
      mid++;
    }
  }

  sortedArray.splice(mid, 0, item)
  return mid;
}
<|endoftext|>


<commit_before>var utils = require('./utils/');

var debug = utils.debug;
var warn = debug('A-Frame:warn');

if (document.currentScript && document.currentScript.parentNode !== document.head &&
    !window.debug) {
  warn('Put the A-Frame <script> tag in the <head> of the HTML *before* the scene to ' +
       'ensure everything for A-Frame is properly registered before they are used from ' +
       'HTML.');
}

// Polyfill `Promise`.
window.Promise = window.Promise || require('promise-polyfill');

// Check before the polyfill runs
window.hasNativeWebVRImplementation = !!navigator.getVRDisplays || !!navigator.getVRDevices;

window.WebVRConfig = window.WebVRConfig || {
  BUFFER_SCALE: 1,
  CARDBOARD_UI_DISABLED: true,
  ROTATE_INSTRUCTIONS_DISABLED: true,
  TOUCH_PANNER_DISABLED: true,
  MOUSE_KEYBOARD_CONTROLS_DISABLED: true
};

// Workaround for iOS Safari canvas sizing issues in stereo (webvr-polyfill/issues/102).
// Only for iOS on versions older than 10.
if (utils.device.isIOSOlderThan10(navigator.userAgent)) {
  window.WebVRConfig.BUFFER_SCALE = 1 / window.devicePixelRatio;
}

// WebVR polyfill
require('webvr-polyfill');

require('present'); // Polyfill `performance.now()`.

// CSS.
if (utils.device.isBrowserEnvironment) {
  require('./style/aframe.css');
  require('./style/rStats.css');
}

// Required before `AEntity` so that all components are registered.
var AScene = require('./core/scene/a-scene');
var components = require('./core/component').components;
var registerComponent = require('./core/component').registerComponent;
var registerGeometry = require('./core/geometry').registerGeometry;
var registerPrimitive = require('./extras/primitives/primitives').registerPrimitive;
var registerShader = require('./core/shader').registerShader;
var registerSystem = require('./core/system').registerSystem;
var shaders = require('./core/shader').shaders;
var systems = require('./core/system').systems;
// Exports THREE to window so three.js can be used without alteration.
var THREE = window.THREE = require('./lib/three');
var TWEEN = window.TWEEN = require('tween.js');

var pkg = require('../package');

require('./components/index'); // Register standard components.
require('./geometries/index'); // Register standard geometries.
require('./shaders/index'); // Register standard shaders.
require('./systems/index'); // Register standard systems.
var ANode = require('./core/a-node');
var AEntity = require('./core/a-entity'); // Depends on ANode and core components.

require('./core/a-animation');
require('./core/a-assets');
require('./core/a-cubemap');
require('./core/a-mixin');

// Extras.
require('./extras/components/');
require('./extras/primitives/');

console.log('A-Frame Version: 0.5.0 (Date 01-04-2017, Commit #22c9ddb)');
console.log('three Version:', pkg.dependencies['three']);
console.log('WebVR Polyfill Version:', pkg.dependencies['webvr-polyfill']);

module.exports = window.AFRAME = {
  AComponent: require('./core/component').Component,
  AEntity: AEntity,
  ANode: ANode,
  AScene: AScene,
  components: components,
  geometries: require('./core/geometry').geometries,
  registerComponent: registerComponent,
  registerElement: require('./core/a-register-element').registerElement,
  registerGeometry: registerGeometry,
  registerPrimitive: registerPrimitive,
  registerShader: registerShader,
  registerSystem: registerSystem,
  primitives: {
    getMeshMixin: require('./extras/primitives/getMeshMixin'),
    primitives: require('./extras/primitives/primitives').primitives
  },
  scenes: require('./core/scene/scenes'),
  schema: require('./core/schema'),
  shaders: shaders,
  systems: systems,
  THREE: THREE,
  TWEEN: TWEEN,
  utils: utils,
  version: pkg.version
};
<commit_msg>Throw an error if HTML file is opened with `file://` protocol vs a local server or hosted (#2540)<commit_after>var utils = require('./utils/');

var debug = utils.debug;
var warn = debug('A-Frame:warn');

if (document.currentScript && document.currentScript.parentNode !== document.head &&
    !window.debug) {
  warn('Put the A-Frame <script> tag in the <head> of the HTML *before* the scene to ' +
       'ensure everything for A-Frame is properly registered before they are used from ' +
       'HTML.');
}

if (window.location.protocol === 'file:') {
  warn('This HTML file is currently served via the file:// protocol. This does not ' +
       'work well with assets or files fetched in the A-Frame scene. Consider serving ' +
       'this file from a hosted or local server with a http:// or https:// protocol.');
}

// Polyfill `Promise`.
window.Promise = window.Promise || require('promise-polyfill');

// Check before the polyfill runs
window.hasNativeWebVRImplementation = !!navigator.getVRDisplays || !!navigator.getVRDevices;

window.WebVRConfig = window.WebVRConfig || {
  BUFFER_SCALE: 1,
  CARDBOARD_UI_DISABLED: true,
  ROTATE_INSTRUCTIONS_DISABLED: true,
  TOUCH_PANNER_DISABLED: true,
  MOUSE_KEYBOARD_CONTROLS_DISABLED: true
};

// Workaround for iOS Safari canvas sizing issues in stereo (webvr-polyfill/issues/102).
// Only for iOS on versions older than 10.
if (utils.device.isIOSOlderThan10(navigator.userAgent)) {
  window.WebVRConfig.BUFFER_SCALE = 1 / window.devicePixelRatio;
}

// WebVR polyfill
require('webvr-polyfill');

require('present'); // Polyfill `performance.now()`.

// CSS.
if (utils.device.isBrowserEnvironment) {
  require('./style/aframe.css');
  require('./style/rStats.css');
}

// Required before `AEntity` so that all components are registered.
var AScene = require('./core/scene/a-scene');
var components = require('./core/component').components;
var registerComponent = require('./core/component').registerComponent;
var registerGeometry = require('./core/geometry').registerGeometry;
var registerPrimitive = require('./extras/primitives/primitives').registerPrimitive;
var registerShader = require('./core/shader').registerShader;
var registerSystem = require('./core/system').registerSystem;
var shaders = require('./core/shader').shaders;
var systems = require('./core/system').systems;
// Exports THREE to window so three.js can be used without alteration.
var THREE = window.THREE = require('./lib/three');
var TWEEN = window.TWEEN = require('tween.js');

var pkg = require('../package');

require('./components/index'); // Register standard components.
require('./geometries/index'); // Register standard geometries.
require('./shaders/index'); // Register standard shaders.
require('./systems/index'); // Register standard systems.
var ANode = require('./core/a-node');
var AEntity = require('./core/a-entity'); // Depends on ANode and core components.

require('./core/a-animation');
require('./core/a-assets');
require('./core/a-cubemap');
require('./core/a-mixin');

// Extras.
require('./extras/components/');
require('./extras/primitives/');

console.log('A-Frame Version: 0.5.0 (Date 01-04-2017, Commit #22c9ddb)');
console.log('three Version:', pkg.dependencies['three']);
console.log('WebVR Polyfill Version:', pkg.dependencies['webvr-polyfill']);

module.exports = window.AFRAME = {
  AComponent: require('./core/component').Component,
  AEntity: AEntity,
  ANode: ANode,
  AScene: AScene,
  components: components,
  geometries: require('./core/geometry').geometries,
  registerComponent: registerComponent,
  registerElement: require('./core/a-register-element').registerElement,
  registerGeometry: registerGeometry,
  registerPrimitive: registerPrimitive,
  registerShader: registerShader,
  registerSystem: registerSystem,
  primitives: {
    getMeshMixin: require('./extras/primitives/getMeshMixin'),
    primitives: require('./extras/primitives/primitives').primitives
  },
  scenes: require('./core/scene/scenes'),
  schema: require('./core/schema'),
  shaders: shaders,
  systems: systems,
  THREE: THREE,
  TWEEN: TWEEN,
  utils: utils,
  version: pkg.version
};
<|endoftext|>


<commit_before>// @flow
import blankie from 'blankie';

// Plugin sets content security policy headers
export function register(
	server: HapiServer,
	options: ?{ [string]: string }
): Promise<any> {
	server.ext('onPreResponse', (request, h) => {
		if (request.response.isBoom) {
			// don't set headers on error objects
			return h.continue;
		}
		// Tells browser that it should only be accessed using HTTPS & how long to remember that
		request.response.header('Strict-Transport-Security', 'max-age=7776000'); // 3 months

		// Enables XSS filtering. Browser will prevent rendering of the page if an attack is detected.
		request.response.header('X-XSS-Protection', '1; mode=block');
		return h.continue;
	});
	/**
	 * We are using Blankie to set our Content-Security-Policy header, which uses Scooter to
	 * detect the user agent and apply the appropriate CSP header, usually Content-Security-Policy
	 * but some older browsers are slightly different. A CSP compatible browser will use the header
	 * to ignore scripts not whitelisted in our policy header. https://github.com/nlf/blankie
	 */
	return blankie.plugin.register(server, options);
}

export const plugin = {
	register,
	name: 'mwp-csp',
	version: '1.0.0',
	depencencies: [
		'blankie', // sets `Content-Security-Policy` header based on user agent
		'scooter', // blankie dependency for detecting user agent
	],
};
<commit_msg>feat: add x-frame-options header to secure legacy iframes<commit_after>// @flow
import blankie from 'blankie';

// Plugin sets content security policy headers
export function register(
	server: HapiServer,
	options: ?{ [string]: string }
): Promise<any> {
	server.ext('onPreResponse', (request, h) => {
		if (request.response.isBoom) {
			// don't set headers on error objects
			return h.continue;
		}
		// Tells browser that it should only be accessed using HTTPS & how long to remember that
		request.response.header('Strict-Transport-Security', 'max-age=7776000'); // 3 months

		// Enables XSS filtering. Browser will prevent rendering of the page if an attack is detected.
		request.response.header('X-XSS-Protection', '1; mode=block');

		// legacy header for suppressing iframe rendering on other domains
		request.response.header('X-Frame-Options', 'SAMEORIGIN');

		return h.continue;
	});
	/**
	 * We are using Blankie to set our Content-Security-Policy header, which uses Scooter to
	 * detect the user agent and apply the appropriate CSP header, usually Content-Security-Policy
	 * but some older browsers are slightly different. A CSP compatible browser will use the header
	 * to ignore scripts not whitelisted in our policy header. https://github.com/nlf/blankie
	 */
	return blankie.plugin.register(server, options);
}

export const plugin = {
	register,
	name: 'mwp-csp',
	version: '1.0.0',
	depencencies: [
		'blankie', // sets `Content-Security-Policy` header based on user agent
		'scooter', // blankie dependency for detecting user agent
	],
};
<|endoftext|>


<commit_before>import program from 'commander'
import process from 'process'

import appFactory from './app-factory'

const packageJson = require('../package.json')

program
  .version(packageJson.version)
  .option('-s, --station [id]', 'Filter by station number')
  .parse(process.argv)

const stationParam = program.station
const stationIds = stationParam && stationParam.split(',')

const app = appFactory.create()

app.printStations(stationIds)
<commit_msg>simplify program arguments check<commit_after>import program from 'commander'
import process from 'process'

import appFactory from './app-factory'

const packageJson = require('../package.json')

const list = val => val.split(',')

program
  .version(packageJson.version)
  .option('-s, --station [id]', 'List station(s) (comma separated) ', list)
  .parse(process.argv)

const stationIds = program.station

const app = appFactory.create()

app.printStations(stationIds)
<|endoftext|>