<commit_before>import React from 'react';
import { PrismCode } from 'react-prism';
import { Button, Container, Row, Col, Jumbotron } from 'reactstrap';
import { Link } from 'react-router';
import Example from '../examples/import-basic';

const importBasic = require('!!raw!../examples/import-basic');

export default () => {
  return (

      <Jumbotron tag="section" className="jumbotron-header text-center mb-3">
        <Container>
          <Row>
            <Col>

reactstrap

                Easy to use React Bootstrap 4 components

                <Button outline color="danger" href="https://github.com/reactstrap/reactstrap">View on Github</Button>
                <Button color="danger" tag={Link} to="/components/">View Components</Button>

            </Col>
          </Row>
        </Container>
      </Jumbotron>
      <Container>
        <Row>
          <Col sm={{ size: 8, offset: 2 }}>

Installation

NPM

Install reactstrap and peer dependencies via NPM

              <PrismCode className="language-bash">npm install --save reactstrap react-transition-group react react-dom</PrismCode>

Import the components you need

              <Example />

              <PrismCode className="language-jsx">
                {importBasic}
              </PrismCode>

Getting Started with Create React App

Follow the create-react-app instructions up to the Adding Bootstrap section and instead follow the reactstrap version of adding bootstrap.

tl;dr

              <PrismCode className="language-bash">
{`npm install -g create-react-app

create-react-app my-app
cd my-app/
npm start`}
              </PrismCode>

              Then open http://localhost:3000/ to see your app. The initial structure of your app is setup. Next, let's add reactstrap and bootstrap.

Adding Bootstrap

Install reactstrap and Bootstrap from NPM. Reactstrap does not include Bootstrap CSS so this needs to be installed as well:

              <PrismCode className="language-bash">
  {`npm install bootstrap@4.0.0-alpha.6 --save
npm install --save reactstrap react-addons-transition-group react-addons-css-transition-group react react-dom`}
              </PrismCode>

Import Bootstrap CSS in the src/index.js file:

              <PrismCode className="language-bash">import 'bootstrap/dist/css/bootstrap.css';</PrismCode>

Import required reactstrap components within src/App.js file or your custom component files:

              <PrismCode className="language-bash">
                {`import { Button } from 'reactstrap';`}
              </PrismCode>

Now you are ready to use the imported reactstrap components within your component hierarchy defined in the render method. Here is an example App.js redone using reactstrap.

CDN

Reactstrap can be included directly in your application's bundle or excluded during compilation and linked directly to a CDN.

              <PrismCode className="language-jsx">
                https://cdnjs.cloudflare.com/ajax/libs/reactstrap/4.8.0/reactstrap.min.js
              </PrismCode>

                Note: When using the external CDN library, be sure to include the required dependencies as necessary prior to the Reactstrap library:

React

ReactTransitionGroup

Check out the demo here

About the Project

This library contains React Bootstrap 4 components that favor composition and control. The library does not depend on jQuery or Bootstrap javascript. However, Tether is relied upon for advanced positioning of content like Tooltips, Popovers, and auto-flipping Dropdowns.

There are a few core concepts to understand in order to make the most out of this library.

1) Your content is expected to be composed via props.children rather than using named props to pass in Components.

              <PrismCode className="language-jsx">
{`// Content passed in via props
const Example = (props) => {
  return (

This is a tooltip <TooltipTrigger tooltip={TooltipContent}>example</TooltipTrigger>!

  );
}

// Content passed in as children (Preferred)
const PreferredExample = (props) => {
  return (

      This is a tooltip example.
      <Tooltip target="TooltipExample">
        <TooltipContent/>
      </Tooltip>

  );
}`}
              </PrismCode>

              2) Attributes in this library are used to pass in state, conveniently apply modifier classes, enable advanced functionality (like tether), or automatically include non-content based elements.

Examples:

isOpen - current state for items like dropdown, popover, tooltip

toggle - callback for toggling isOpen in the controlling component

color - applies color classes, ex: {'<Button color="danger"/>'}

size for controlling size classes. ex: {'<Button size="sm"/>'}

tag - customize component output by passing in an element name or Component

boolean based props (attributes) when possible for alternative style classes or sr-only content

          </Col>
        </Row>
      </Container>

  );
};
<commit_msg>docs(install): remove react-addons-css-transition-group (#603)<commit_after>import React from 'react';
import { PrismCode } from 'react-prism';
import { Button, Container, Row, Col, Jumbotron } from 'reactstrap';
import { Link } from 'react-router';
import Example from '../examples/import-basic';

const importBasic = require('!!raw!../examples/import-basic');

export default () => {
  return (

      <Jumbotron tag="section" className="jumbotron-header text-center mb-3">
        <Container>
          <Row>
            <Col>

reactstrap

                Easy to use React Bootstrap 4 components

                <Button outline color="danger" href="https://github.com/reactstrap/reactstrap">View on Github</Button>
                <Button color="danger" tag={Link} to="/components/">View Components</Button>

            </Col>
          </Row>
        </Container>
      </Jumbotron>
      <Container>
        <Row>
          <Col sm={{ size: 8, offset: 2 }}>

Installation

NPM

Install reactstrap and peer dependencies via NPM

              <PrismCode className="language-bash">npm install --save reactstrap react-transition-group react react-dom</PrismCode>

Import the components you need

              <Example />

              <PrismCode className="language-jsx">
                {importBasic}
              </PrismCode>

Getting Started with Create React App

Follow the create-react-app instructions up to the Adding Bootstrap section and instead follow the reactstrap version of adding bootstrap.

tl;dr

              <PrismCode className="language-bash">
{`npm install -g create-react-app

create-react-app my-app
cd my-app/
npm start`}
              </PrismCode>

              Then open http://localhost:3000/ to see your app. The initial structure of your app is setup. Next, let's add reactstrap and bootstrap.

Adding Bootstrap

Install reactstrap and Bootstrap from NPM. Reactstrap does not include Bootstrap CSS so this needs to be installed as well:

              <PrismCode className="language-bash">
  {`npm install bootstrap@4.0.0-alpha.6 --save
npm install --save reactstrap react-addons-transition-group react react-dom`}
              </PrismCode>

Import Bootstrap CSS in the src/index.js file:

              <PrismCode className="language-bash">import 'bootstrap/dist/css/bootstrap.css';</PrismCode>

Import required reactstrap components within src/App.js file or your custom component files:

              <PrismCode className="language-bash">
                {`import { Button } from 'reactstrap';`}
              </PrismCode>

Now you are ready to use the imported reactstrap components within your component hierarchy defined in the render method. Here is an example App.js redone using reactstrap.

CDN

Reactstrap can be included directly in your application's bundle or excluded during compilation and linked directly to a CDN.

              <PrismCode className="language-jsx">
                https://cdnjs.cloudflare.com/ajax/libs/reactstrap/4.8.0/reactstrap.min.js
              </PrismCode>

                Note: When using the external CDN library, be sure to include the required dependencies as necessary prior to the Reactstrap library:

React

ReactTransitionGroup

Check out the demo here

About the Project

This library contains React Bootstrap 4 components that favor composition and control. The library does not depend on jQuery or Bootstrap javascript. However, Tether is relied upon for advanced positioning of content like Tooltips, Popovers, and auto-flipping Dropdowns.

There are a few core concepts to understand in order to make the most out of this library.

1) Your content is expected to be composed via props.children rather than using named props to pass in Components.

              <PrismCode className="language-jsx">
{`// Content passed in via props
const Example = (props) => {
  return (

This is a tooltip <TooltipTrigger tooltip={TooltipContent}>example</TooltipTrigger>!

  );
}

// Content passed in as children (Preferred)
const PreferredExample = (props) => {
  return (

      This is a tooltip example.
      <Tooltip target="TooltipExample">
        <TooltipContent/>
      </Tooltip>

  );
}`}
              </PrismCode>

              2) Attributes in this library are used to pass in state, conveniently apply modifier classes, enable advanced functionality (like tether), or automatically include non-content based elements.

Examples:

isOpen - current state for items like dropdown, popover, tooltip

toggle - callback for toggling isOpen in the controlling component

color - applies color classes, ex: {'<Button color="danger"/>'}

size for controlling size classes. ex: {'<Button size="sm"/>'}

tag - customize component output by passing in an element name or Component

boolean based props (attributes) when possible for alternative style classes or sr-only content

          </Col>
        </Row>
      </Container>

  );
};
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');
var pegjs = require('pegjs');
var Promise = require('bluebird');
var print = require('./print');
var visit = require('./visit');

Promise.promisifyAll(fs);

var _outDir;
function getOutDir() {
  var dirName = __dirname + '/../out';
  return _outDir || (_outDir =
    exists(dirName).then(function (exists) {
      if (!exists) {
        return fs.mkdirAsync(dirName).then(function () {
          return dirName;
        });
      }
      return dirName;
    })
  );
}

function exists(dirName) {
  return new Promise(function (resolve) {
    fs.exists(dirName, resolve);
  });
}

printSpecHTML(__dirname + '/../README.md').then(function (html) {
  return getOutDir().then(function (outDir) {
    return Promise.all([
      fs.readFileAsync(__dirname + '/../css/spec.css', { encoding: 'utf8' }).then(function (css) {
        return fs.writeFileAsync(outDir + '/spec.css', css, { encoding: 'utf8' });
      }),
      fs.readFileAsync(__dirname + '/../css/highlight.css', { encoding: 'utf8' }).then(function (css) {
        return fs.writeFileAsync(outDir + '/highlight.css', css, { encoding: 'utf8' });
      }),
      fs.writeFileAsync(outDir + '/index.html', html, { encoding: 'utf8' }),
    ]);
  });
}).catch(function (error) {
  console.log(error);
  throw error;
});

///////////////////////////

function printSpecHTML(filepath) {
  return getParser().then(function (parser) {
    return importAST(parser, filepath);
  }).then(function (ast) {
    return print(ast);
  });
}

var _parser;
function getParser() {
  return _parser || (_parser =
    fs.readFileAsync(__dirname + '/grammar.pegjs', 'utf8').then(function (text) {
      return pegjs.buildParser(text, {
        output: 'parser',
        allowedStartRules: ['document']
      });
    })
  );
}

function importAST(parser, filepath) {
  var md = fs.readFileAsync(filepath, { encoding: 'utf8' });
  return md.then(function (md) {
    var ast = parser.parse(md);
    var importASTs = [];
    visit(ast, function (node) {
      if (node.type === 'Import') {
        var subfilepath = path.resolve(path.dirname(filepath), node.path);
        importASTs.push(importAST(parser, subfilepath));
      }
    });
    return Promise.all(importASTs).then(function (asts) {
      var cursor = 0;
      var needToFlattenContents = false;
      return visit(ast, {
        leave: function (node) {
          if (needToFlattenContents) {
            node.contents = node.contents.reduce(flattener, []);
          }
          if (node.type === 'Import') {
            needToFlattenContents = true;
            return asts[cursor++].contents;
          } else {
            needToFlattenContents = false;
          }
        }
      });
    });
  });
}

function flattener(array, item) {
  if (Array.isArray(item)) {
    return item.reduce(flattener, array);
  }
  array.push(item);
  return array;
}
<commit_msg>pass through objects<commit_after>'use strict';

var fs = require('fs');
var path = require('path');
var pegjs = require('pegjs');
var Promise = require('bluebird');
var print = require('./print');
var visit = require('./visit');

Promise.promisifyAll(fs);

var _outDir;
function getOutDir() {
  var dirName = __dirname + '/../out';
  return _outDir || (_outDir =
    exists(dirName).then(function (exists) {
      if (!exists) {
        return fs.mkdirAsync(dirName).then(function () {
          return dirName;
        });
      }
      return dirName;
    })
  );
}

function exists(dirName) {
  return new Promise(function (resolve) {
    fs.exists(dirName, resolve);
  });
}

printSpecHTML(__dirname + '/../README.md').then(function (html) {
  return getOutDir().then(function (outDir) {
    return Promise.all([
      fs.readFileAsync(__dirname + '/../css/spec.css', { encoding: 'utf8' }).then(function (css) {
        return fs.writeFileAsync(outDir + '/spec.css', css, { encoding: 'utf8' });
      }),
      fs.readFileAsync(__dirname + '/../css/highlight.css', { encoding: 'utf8' }).then(function (css) {
        return fs.writeFileAsync(outDir + '/highlight.css', css, { encoding: 'utf8' });
      }),
      fs.writeFileAsync(outDir + '/index.html', html, { encoding: 'utf8' }),
    ]);
  });
}).catch(function (error) {
  console.log(error);
  throw error;
});

///////////////////////////

function printSpecHTML(filepath, options) {
  return getParser().then(function (parser) {
    return importAST(parser, filepath);
  }).then(function (ast) {
    return print(ast, options);
  });
}

var _parser;
function getParser() {
  return _parser || (_parser =
    fs.readFileAsync(__dirname + '/grammar.pegjs', 'utf8').then(function (text) {
      return pegjs.buildParser(text, {
        output: 'parser',
        allowedStartRules: ['document']
      });
    })
  );
}

function importAST(parser, filepath) {
  var md = fs.readFileAsync(filepath, { encoding: 'utf8' });
  return md.then(function (md) {
    var ast = parser.parse(md);
    var importASTs = [];
    visit(ast, function (node) {
      if (node.type === 'Import') {
        var subfilepath = path.resolve(path.dirname(filepath), node.path);
        importASTs.push(importAST(parser, subfilepath));
      }
    });
    return Promise.all(importASTs).then(function (asts) {
      var cursor = 0;
      var needToFlattenContents = false;
      return visit(ast, {
        leave: function (node) {
          if (needToFlattenContents) {
            node.contents = node.contents.reduce(flattener, []);
          }
          if (node.type === 'Import') {
            needToFlattenContents = true;
            return asts[cursor++].contents;
          } else {
            needToFlattenContents = false;
          }
        }
      });
    });
  });
}

function flattener(array, item) {
  if (Array.isArray(item)) {
    return item.reduce(flattener, array);
  }
  array.push(item);
  return array;
}
<|endoftext|>


<commit_before>/**
 * Copyright 2016 The AMP HTML Authors. All Rights Reserved.
 *
 * 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 {Services} from './services';
import {dev} from './log';
import {getData} from './event-helper';
import {getServiceForDoc, registerServiceBuilderForDoc} from './service';
import {makeBodyVisible} from './style-installer';
import PriorityQueue from './utils/priority-queue';

/**
 * @const {string}
 */
const TAG = 'CHUNK';

/**
 * @type {boolean}
 */
let deactivated = /nochunking=1/.test(self.location.hash);

/**
 * @const {!Promise}
 */
const resolved = Promise.resolve();

/**
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @return {!Chunks}
 * @private
 */
function getChunkServiceForDoc_(nodeOrAmpDoc) {
  registerServiceBuilderForDoc(nodeOrAmpDoc, 'chunk', Chunks);
  return getServiceForDoc(nodeOrAmpDoc, 'chunk');
}

/**
 * Run the given function. For visible documents the function will be
 * called in a micro task (Essentially ASAP). If the document is
 * not visible, tasks will yield to the event loop (to give the browser
 * time to do other things) and may even be further delayed until
 * there is time.
 *
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @param {function(?IdleDeadline)} fn
 */
export function startupChunk(nodeOrAmpDoc, fn) {
  if (deactivated) {
    resolved.then(fn);
    return;
  }
  const service = getChunkServiceForDoc_(nodeOrAmpDoc);
  service.runForStartup_(fn);
}

/**
 * Run the given function sometime in the future without blocking UI.
 *
 * Higher priority tasks are executed before lower priority tasks.
 * Tasks with the same priority are executed in FIFO order.
 *
 * Uses `requestIdleCallback` if available and passes the `IdleDeadline`
 * object to the function, which can be used to perform a variable amount
 * of work depending on the remaining amount of idle time.
 *
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @param {function(?IdleDeadline)} fn
 * @param {ChunkPriority} priority
 */
export function chunk(nodeOrAmpDoc, fn, priority) {
  if (deactivated) {
    resolved.then(fn);
    return;
  }
  const service = getChunkServiceForDoc_(nodeOrAmpDoc);
  service.run(fn, priority);
}

/**
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @return {!Chunks}
 */
export function chunkInstanceForTesting(nodeOrAmpDoc) {
  return getChunkServiceForDoc_(nodeOrAmpDoc);
}

/**
 * Use a standard micro task for every invocation. This should only
 * be called from the AMP bootstrap script if it is known that
 * chunking makes no sense. In particular this is the case when
 * AMP runs in the `amp-shadow` multi document mode.
 */
export function deactivateChunking() {
  deactivated = true;
}

export function activateChunkingForTesting() {
  deactivated = false;
}

/**
 * Runs all currently scheduled chunks.
 * Independent of errors it will unwind the queue. Will afterwards
 * throw the first encountered error.
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 */
export function runChunksForTesting(nodeOrAmpDoc) {
  const service = chunkInstanceForTesting(nodeOrAmpDoc);
  const errors = [];
  while (true) {
    try {
      if (!service.execute_(/* idleDeadline */ null)) {
        break;
      }
    } catch (e) {
      errors.push(e);
    }
  }
  if (errors.length) {
    throw errors[0];
  }
}

/**
 * The priority of a chunk task. Higher priority tasks have higher values.
 * @enum {number}
 */
export const ChunkPriority = {
  HIGH: 20,
  LOW: 10,
  BACKGROUND: 0,
};

/** @enum {string} */
const TaskState = {
  NOT_RUN: 'not_run',
  RUN: 'run',
};

/**
 * A default chunkable task.
 * @private
 */
class Task {
  /**
   * @param {function(?IdleDeadline)} fn
   */
  constructor(fn) {
    /** @public {TaskState} */
    this.state = TaskState.NOT_RUN;

    /** @private @const {!function(?IdleDeadline)} */
    this.fn_ = fn;
  }

  /**
   * Executes the wrapped function.
   * @param {?IdleDeadline} idleDeadline
   * @throws {Error}
   * @private
   */
  runTask_(idleDeadline) {
    if (this.state == TaskState.RUN) {
      return;
    }
    this.state = TaskState.RUN;
    try {
      this.fn_(idleDeadline);
    } catch (e) {
      this.onTaskError_(e);
      throw e;
    }
  }

  /**
   * @return {string}
   * @private
   */
  getName_() {
    return this.fn_.displayName || this.fn_.name;
  }

  /**
   * Optional handling when a task run throws an error.
   * @param {Error} unusedError
   * @private
   */
  onTaskError_(unusedError) {
    // By default, no-op.
  }

  /**
   * Returns true if this task should be run without delay.
   * @return {boolean}
   * @private
   */
  immediateTriggerCondition_() {
    // By default, there are no immediate trigger conditions.
    return false;
  }

  /**
   * Returns true if this task should be scheduled using `requestIdleCallback`.
   * Otherwise, task is scheduled as macro-task on next event loop.
   * @return {boolean}
   * @private
   */
  useRequestIdleCallback_() {
    // By default, always use requestIdleCallback.
    return true;
  }
}

/**
 * A task that's run as part of AMP's startup sequence.
 * @private
 */
class StartupTask extends Task {
  /**
   * @param {function(?IdleDeadline)} fn
   * @param {!Window} win
   * @param {!Promise<!./service/viewer-impl.Viewer>} viewerPromise
   */
  constructor(fn, win, viewerPromise) {
    super(fn);

    /** @private {!Window} */
    this.win_ = win;

    /** @private {?./service/viewer-impl.Viewer} */
    this.viewer_ = null;

    viewerPromise.then(viewer => {
      this.viewer_ = viewer;

      if (this.viewer_.isVisible()) {
        this.runTask_(/* idleDeadline */ null);
      }
      this.viewer_.onVisibilityChanged(() => {
        if (this.viewer_.isVisible()) {
          this.runTask_(/* idleDeadline */ null);
        }
      });
    });
  }

  /** @override */
  onTaskError_(unusedError) {
    // Startup tasks run early in init. All errors should show the doc.
    makeBodyVisible(self.document);
  }

  /** @override */
  immediateTriggerCondition_() {
    // Run in a micro task when the doc is visible. Otherwise, run after
    // having yielded to the event queue once.
    return this.isVisible_();
  }

  /** @override */
  useRequestIdleCallback_() {
    // We only start using requestIdleCallback when the viewer has
    // been initialized. Otherwise we risk starving ourselves
    // before we get into a state where the viewer can tell us
    // that we are visible.
    return !!this.viewer_;
  }

  /**
   * @return {boolean}
   * @private
   */
  isVisible_() {
    // Ask the viewer first.
    if (this.viewer_) {
      return this.viewer_.isVisible();
    }
    // There is no viewer yet. Lets try to guess whether we are visible.
    if (this.win_.document.hidden) {
      return false;
    }
    // Viewers send a URL param if we are not visible.
    return !(/visibilityState=(hidden|prerender)/.test(
        this.win_.location.hash));
  }
}

/**
 * Handles queueing, scheduling and executing tasks.
 */
class Chunks {
  /**
   * @param {!./service/ampdoc-impl.AmpDoc} ampDoc
   */
  constructor(ampDoc) {
    /** @private @const */
    this.ampDoc_ = ampDoc;
    /** @private @const {!Window} */
    this.win_ = ampDoc.win;
    /** @private @const {!PriorityQueue<Task>} */
    this.tasks_ = new PriorityQueue();
    /** @private @const {function(?IdleDeadline)} */
    this.boundExecute_ = this.execute_.bind(this);

    /** @private @const {!Promise<!./service/viewer-impl.Viewer>} */
    this.viewerPromise_ = Services.viewerPromiseForDoc(ampDoc);

    this.win_.addEventListener('message', e => {
      if (getData(e) == 'amp-macro-task') {
        this.execute_(/* idleDeadline */ null);
      }
    });
  }

  /**
   * Run fn as a "chunk".
   * @param {function(?IdleDeadline)} fn
   * @param {number} priority
   */
  run(fn, priority) {
    const t = new Task(fn);
    this.enqueueTask_(t, priority);
  }

  /**
   * Run a fn that's part of AMP's startup sequence as a "chunk".
   * @param {function(?IdleDeadline)} fn
   * @private
   */
  runForStartup_(fn) {
    const t = new StartupTask(fn, this.win_, this.viewerPromise_);
    this.enqueueTask_(t, Number.POSITIVE_INFINITY);
  }

  /**
   * Queues a task to be executed later with given priority.
   * @param {!Task} task
   * @param {number} priority
   * @private
   */
  enqueueTask_(task, priority) {
    this.tasks_.enqueue(task, priority);
    resolved.then(() => {
      this.schedule_();
    });
  }

  /**
   * Returns the next task that hasn't been run yet.
   * If `opt_dequeue` is true, remove the returned task from the queue.
   * @param {boolean=} opt_dequeue
   * @return {?Task}
   * @private
   */
  nextTask_(opt_dequeue) {
    let t = this.tasks_.peek();
    // Dequeue tasks until we find one that hasn't been run yet.
    while (t && t.state !== TaskState.NOT_RUN) {
      this.tasks_.dequeue();
      t = this.tasks_.peek();
    }
    // If `opt_dequeue` is true, remove this task from the queue.
    if (t && opt_dequeue) {
      this.tasks_.dequeue();
    }
    return t;
  }

  /**
   * Run a task.
   * Schedule the next round if there are more tasks.
   * @param {?IdleDeadline} idleDeadline
   * @return {boolean} Whether anything was executed.
   * @private
   */
  execute_(idleDeadline) {
    const t = this.nextTask_(/* opt_dequeue */ true);
    if (!t) {
      return false;
    }
    const before = Date.now();
    t.runTask_(idleDeadline);
    resolved.then(() => {
      this.schedule_();
    });
    dev().fine(TAG, t.getName_(), 'Chunk duration', Date.now() - before);
    return true;
  }

  /**
   * Calls `execute_()` asynchronously.
   * @param {?IdleDeadline} idleDeadline
   * @private
   */
  executeAsap_(idleDeadline) {
    resolved.then(() => {
      this.boundExecute_(idleDeadline);
    });
  }

  /**
   * Schedule running the next queued task.
   * @private
   */
  schedule_() {
    const nextTask = this.nextTask_();
    if (!nextTask) {
      return;
    }
    if (nextTask.immediateTriggerCondition_()) {
      this.executeAsap_(/* idleDeadline */ null);
      return;
    }
    // If requestIdleCallback exists, schedule a task with it, but
    // do not wait longer than two seconds.
    if (nextTask.useRequestIdleCallback_() && this.win_.requestIdleCallback) {
      onIdle(this.win_,
          // Wait until we have a budget of at least 15ms.
          // 15ms is a magic number. Budgets are higher when the user
          // is completely idle (around 40), but that occurs too
          // rarely to be usable. 15ms budgets can happen during scrolling
          // but only if the device is doing super, super well, and no
          // real processing is done between frames.
          15 /* minimumTimeRemaining */,
          2000 /* timeout */,
          this.boundExecute_);
      return;
    }
    // The message doesn't actually matter.
    this.win_.postMessage/*OK*/('amp-macro-task', '*');
  }
}

/**
 * Delays calling the given function until the browser is notifying us
 * about a certain minimum budget or the timeout is reached.
 * @param {!Window} win
 * @param {number} minimumTimeRemaining Minimum number of millis idle
 *     budget for callback to fire.
 * @param {number} timeout in millis for callback to fire.
 * @param {function(?IdleDeadline)} fn Callback.
 * @visibleForTesting
 */
export function onIdle(win, minimumTimeRemaining, timeout, fn) {
  const startTime = Date.now();
  function rIC(info) {
    if (info.timeRemaining() < minimumTimeRemaining) {
      const remainingTimeout = timeout - (Date.now() - startTime);
      if (remainingTimeout <= 0 || info.didTimeout) {
        dev().fine(TAG, 'Timed out', timeout, info.didTimeout);
        fn(info);
      } else {
        dev().fine(TAG, 'Rescheduling with', remainingTimeout,
            info.timeRemaining());
        win.requestIdleCallback(rIC, {timeout: remainingTimeout});
      }
    } else {
      dev().fine(TAG, 'Running idle callback with ', minimumTimeRemaining);
      fn(info);
    }
  }
  win.requestIdleCallback(rIC, {timeout});
}
<commit_msg>Cleanup chunk's private state (#14783)<commit_after>/**
 * Copyright 2016 The AMP HTML Authors. All Rights Reserved.
 *
 * 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 {Services} from './services';
import {dev} from './log';
import {getData} from './event-helper';
import {getServiceForDoc, registerServiceBuilderForDoc} from './service';
import {makeBodyVisible} from './style-installer';
import PriorityQueue from './utils/priority-queue';

/**
 * @const {string}
 */
const TAG = 'CHUNK';

/**
 * @type {boolean}
 */
let deactivated = /nochunking=1/.test(self.location.hash);

/**
 * @const {!Promise}
 */
const resolved = Promise.resolve();

/**
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @return {!Chunks}
 * @private
 */
function getChunkServiceForDoc_(nodeOrAmpDoc) {
  registerServiceBuilderForDoc(nodeOrAmpDoc, 'chunk', Chunks);
  return getServiceForDoc(nodeOrAmpDoc, 'chunk');
}

/**
 * Run the given function. For visible documents the function will be
 * called in a micro task (Essentially ASAP). If the document is
 * not visible, tasks will yield to the event loop (to give the browser
 * time to do other things) and may even be further delayed until
 * there is time.
 *
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @param {function(?IdleDeadline)} fn
 */
export function startupChunk(nodeOrAmpDoc, fn) {
  if (deactivated) {
    resolved.then(fn);
    return;
  }
  const service = getChunkServiceForDoc_(nodeOrAmpDoc);
  service.runForStartup(fn);
}

/**
 * Run the given function sometime in the future without blocking UI.
 *
 * Higher priority tasks are executed before lower priority tasks.
 * Tasks with the same priority are executed in FIFO order.
 *
 * Uses `requestIdleCallback` if available and passes the `IdleDeadline`
 * object to the function, which can be used to perform a variable amount
 * of work depending on the remaining amount of idle time.
 *
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @param {function(?IdleDeadline)} fn
 * @param {ChunkPriority} priority
 */
export function chunk(nodeOrAmpDoc, fn, priority) {
  if (deactivated) {
    resolved.then(fn);
    return;
  }
  const service = getChunkServiceForDoc_(nodeOrAmpDoc);
  service.run(fn, priority);
}

/**
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 * @return {!Chunks}
 */
export function chunkInstanceForTesting(nodeOrAmpDoc) {
  return getChunkServiceForDoc_(nodeOrAmpDoc);
}

/**
 * Use a standard micro task for every invocation. This should only
 * be called from the AMP bootstrap script if it is known that
 * chunking makes no sense. In particular this is the case when
 * AMP runs in the `amp-shadow` multi document mode.
 */
export function deactivateChunking() {
  deactivated = true;
}

export function activateChunkingForTesting() {
  deactivated = false;
}

/**
 * Runs all currently scheduled chunks.
 * Independent of errors it will unwind the queue. Will afterwards
 * throw the first encountered error.
 * @param {!Node|!./service/ampdoc-impl.AmpDoc} nodeOrAmpDoc
 */
export function runChunksForTesting(nodeOrAmpDoc) {
  const service = chunkInstanceForTesting(nodeOrAmpDoc);
  const errors = [];
  while (true) {
    try {
      if (!service.execute_(/* idleDeadline */ null)) {
        break;
      }
    } catch (e) {
      errors.push(e);
    }
  }
  if (errors.length) {
    throw errors[0];
  }
}

/**
 * The priority of a chunk task. Higher priority tasks have higher values.
 * @enum {number}
 */
export const ChunkPriority = {
  HIGH: 20,
  LOW: 10,
  BACKGROUND: 0,
};

/** @enum {string} */
const TaskState = {
  NOT_RUN: 'not_run',
  RUN: 'run',
};

/**
 * A default chunkable task.
 * @private
 */
class Task {
  /**
   * @param {function(?IdleDeadline)} fn
   */
  constructor(fn) {
    /** @public {TaskState} */
    this.state = TaskState.NOT_RUN;

    /** @private @const {!function(?IdleDeadline)} */
    this.fn_ = fn;
  }

  /**
   * Executes the wrapped function.
   * @param {?IdleDeadline} idleDeadline
   * @throws {Error}
   * @protected
   */
  runTask_(idleDeadline) {
    if (this.state == TaskState.RUN) {
      return;
    }
    this.state = TaskState.RUN;
    try {
      this.fn_(idleDeadline);
    } catch (e) {
      this.onTaskError_(e);
      throw e;
    }
  }

  /**
   * @return {string}
   * @protected
   */
  getName_() {
    return this.fn_.displayName || this.fn_.name;
  }

  /**
   * Optional handling when a task run throws an error.
   * @param {Error} unusedError
   * @private
   */
  onTaskError_(unusedError) {
    // By default, no-op.
  }

  /**
   * Returns true if this task should be run without delay.
   * @return {boolean}
   * @protected
   */
  immediateTriggerCondition_() {
    // By default, there are no immediate trigger conditions.
    return false;
  }

  /**
   * Returns true if this task should be scheduled using `requestIdleCallback`.
   * Otherwise, task is scheduled as macro-task on next event loop.
   * @return {boolean}
   * @protected
   */
  useRequestIdleCallback_() {
    // By default, always use requestIdleCallback.
    return true;
  }
}

/**
 * A task that's run as part of AMP's startup sequence.
 * @private
 */
class StartupTask extends Task {
  /**
   * @param {function(?IdleDeadline)} fn
   * @param {!Window} win
   * @param {!Promise<!./service/viewer-impl.Viewer>} viewerPromise
   */
  constructor(fn, win, viewerPromise) {
    super(fn);

    /** @private {!Window} */
    this.win_ = win;

    /** @private {?./service/viewer-impl.Viewer} */
    this.viewer_ = null;

    viewerPromise.then(viewer => {
      this.viewer_ = viewer;

      if (this.viewer_.isVisible()) {
        this.runTask_(/* idleDeadline */ null);
      }
      this.viewer_.onVisibilityChanged(() => {
        if (this.viewer_.isVisible()) {
          this.runTask_(/* idleDeadline */ null);
        }
      });
    });
  }

  /** @override */
  onTaskError_(unusedError) {
    // Startup tasks run early in init. All errors should show the doc.
    makeBodyVisible(self.document);
  }

  /** @override */
  immediateTriggerCondition_() {
    // Run in a micro task when the doc is visible. Otherwise, run after
    // having yielded to the event queue once.
    return this.isVisible_();
  }

  /** @override */
  useRequestIdleCallback_() {
    // We only start using requestIdleCallback when the viewer has
    // been initialized. Otherwise we risk starving ourselves
    // before we get into a state where the viewer can tell us
    // that we are visible.
    return !!this.viewer_;
  }

  /**
   * @return {boolean}
   * @private
   */
  isVisible_() {
    // Ask the viewer first.
    if (this.viewer_) {
      return this.viewer_.isVisible();
    }
    // There is no viewer yet. Lets try to guess whether we are visible.
    if (this.win_.document.hidden) {
      return false;
    }
    // Viewers send a URL param if we are not visible.
    return !(/visibilityState=(hidden|prerender)/.test(
        this.win_.location.hash));
  }
}

/**
 * Handles queueing, scheduling and executing tasks.
 */
class Chunks {
  /**
   * @param {!./service/ampdoc-impl.AmpDoc} ampDoc
   */
  constructor(ampDoc) {
    /** @private @const {!Window} */
    this.win_ = ampDoc.win;
    /** @private @const {!PriorityQueue<Task>} */
    this.tasks_ = new PriorityQueue();
    /** @private @const {function(?IdleDeadline)} */
    this.boundExecute_ = this.execute_.bind(this);

    /** @private @const {!Promise<!./service/viewer-impl.Viewer>} */
    this.viewerPromise_ = Services.viewerPromiseForDoc(ampDoc);

    this.win_.addEventListener('message', e => {
      if (getData(e) == 'amp-macro-task') {
        this.execute_(/* idleDeadline */ null);
      }
    });
  }

  /**
   * Run fn as a "chunk".
   * @param {function(?IdleDeadline)} fn
   * @param {number} priority
   */
  run(fn, priority) {
    const t = new Task(fn);
    this.enqueueTask_(t, priority);
  }

  /**
   * Run a fn that's part of AMP's startup sequence as a "chunk".
   * @param {function(?IdleDeadline)} fn
   */
  runForStartup(fn) {
    const t = new StartupTask(fn, this.win_, this.viewerPromise_);
    this.enqueueTask_(t, Number.POSITIVE_INFINITY);
  }

  /**
   * Queues a task to be executed later with given priority.
   * @param {!Task} task
   * @param {number} priority
   * @private
   */
  enqueueTask_(task, priority) {
    this.tasks_.enqueue(task, priority);
    resolved.then(() => {
      this.schedule_();
    });
  }

  /**
   * Returns the next task that hasn't been run yet.
   * If `opt_dequeue` is true, remove the returned task from the queue.
   * @param {boolean=} opt_dequeue
   * @return {?Task}
   * @private
   */
  nextTask_(opt_dequeue) {
    let t = this.tasks_.peek();
    // Dequeue tasks until we find one that hasn't been run yet.
    while (t && t.state !== TaskState.NOT_RUN) {
      this.tasks_.dequeue();
      t = this.tasks_.peek();
    }
    // If `opt_dequeue` is true, remove this task from the queue.
    if (t && opt_dequeue) {
      this.tasks_.dequeue();
    }
    return t;
  }

  /**
   * Run a task.
   * Schedule the next round if there are more tasks.
   * @param {?IdleDeadline} idleDeadline
   * @return {boolean} Whether anything was executed.
   * @private
   */
  execute_(idleDeadline) {
    const t = this.nextTask_(/* opt_dequeue */ true);
    if (!t) {
      return false;
    }
    const before = Date.now();
    t.runTask_(idleDeadline);
    resolved.then(() => {
      this.schedule_();
    });
    dev().fine(TAG, t.getName_(), 'Chunk duration', Date.now() - before);
    return true;
  }

  /**
   * Calls `execute_()` asynchronously.
   * @param {?IdleDeadline} idleDeadline
   * @private
   */
  executeAsap_(idleDeadline) {
    resolved.then(() => {
      this.boundExecute_(idleDeadline);
    });
  }

  /**
   * Schedule running the next queued task.
   * @private
   */
  schedule_() {
    const nextTask = this.nextTask_();
    if (!nextTask) {
      return;
    }
    if (nextTask.immediateTriggerCondition_()) {
      this.executeAsap_(/* idleDeadline */ null);
      return;
    }
    // If requestIdleCallback exists, schedule a task with it, but
    // do not wait longer than two seconds.
    if (nextTask.useRequestIdleCallback_() && this.win_.requestIdleCallback) {
      onIdle(this.win_,
          // Wait until we have a budget of at least 15ms.
          // 15ms is a magic number. Budgets are higher when the user
          // is completely idle (around 40), but that occurs too
          // rarely to be usable. 15ms budgets can happen during scrolling
          // but only if the device is doing super, super well, and no
          // real processing is done between frames.
          15 /* minimumTimeRemaining */,
          2000 /* timeout */,
          this.boundExecute_);
      return;
    }
    // The message doesn't actually matter.
    this.win_.postMessage/*OK*/('amp-macro-task', '*');
  }
}

/**
 * Delays calling the given function until the browser is notifying us
 * about a certain minimum budget or the timeout is reached.
 * @param {!Window} win
 * @param {number} minimumTimeRemaining Minimum number of millis idle
 *     budget for callback to fire.
 * @param {number} timeout in millis for callback to fire.
 * @param {function(?IdleDeadline)} fn Callback.
 * @visibleForTesting
 */
export function onIdle(win, minimumTimeRemaining, timeout, fn) {
  const startTime = Date.now();
  function rIC(info) {
    if (info.timeRemaining() < minimumTimeRemaining) {
      const remainingTimeout = timeout - (Date.now() - startTime);
      if (remainingTimeout <= 0 || info.didTimeout) {
        dev().fine(TAG, 'Timed out', timeout, info.didTimeout);
        fn(info);
      } else {
        dev().fine(TAG, 'Rescheduling with', remainingTimeout,
            info.timeRemaining());
        win.requestIdleCallback(rIC, {timeout: remainingTimeout});
      }
    } else {
      dev().fine(TAG, 'Running idle callback with ', minimumTimeRemaining);
      fn(info);
    }
  }
  win.requestIdleCallback(rIC, {timeout});
}
<|endoftext|>


<commit_before>'use strict';

// changeable contants
var C = 'constructor', // name of the constructor method
	X = 'extend'; // name of extend method

function Class() {}

Class[X] = function(subclass) {
	var self      = this,
		prototype = Object.create(self.prototype);

	subclass.call(prototype, self.prototype);

	var Extended = prototype.hasOwnProperty(C) ?
		prototype[C] :
		function() { prototype[C].apply(this, arguments); };

	Extended.prototype = prototype;
	Extended[X] = self[X];

	return Extended;
};<commit_msg>Remove unused 'self' variable<commit_after>'use strict';

// changeable contants
var C = 'constructor', // name of the constructor method
	X = 'extend'; // name of extend method

function Class() {}

Class[X] = function(subclass) {
	var prototype = Object.create(this.prototype);

	subclass.call(prototype, this.prototype);

	var Extended = prototype.hasOwnProperty(C) ?
		prototype[C] :
		function() { prototype[C].apply(this, arguments); };

	Extended.prototype = prototype;
	Extended[X] = this[X];

	return Extended;
};
<|endoftext|>


<commit_before>import crypto from 'crypto';
import { CRYPT_ALGO as algo } from '../conf/constants';

function CryptHelper(secret) {
    return {
        _crypt (text, isEncrypt) {
            let cryptMethod = isEncrypt ? 'createCipher' : 'createDecipher';
            let finalParam = isEncrypt ? 'hex' : 'utf8';
            let cipherArgs = isEncrypt ? [text, 'utf8', 'hex'] : [text, 'hex', 'utf8'];

            let cipher = crypto[cryptMethod](algo, secret);
            let result = cipher.update.apply(cipher, cipherArgs);
            result += cipher.final(finalParam);

            return result;
        },
        encrypt (text) {
            return this._crypt(text, true);
        },
        decrypt (text) {
            return this._crypt(text, false);
        },
        stringifyAndEncrypt (data, withEncryption) {
            let stringifiedData = JSON.stringify(data);

            if (withEncryption) {
                return this.encrypt(stringifiedData);
            } else {
                return stringifiedData;
            }
        },
        decryptAndParse (msg, withEncryption) {
            if (withEncryption) {
                msg = this.decrypt(msg);
            }
            return JSON.parse(msg);
        }
    };
}

export default CryptHelper;
<commit_msg>Renaming for clarity<commit_after>import crypto from 'crypto';
import { CRYPT_ALGO as algo } from '../conf/constants';

function CryptHelper(secret) {
    return {
        _cryptHelper (text, isEncrypt) {
            let cryptMethod = isEncrypt ? 'createCipher' : 'createDecipher';
            let finalParam = isEncrypt ? 'hex' : 'utf8';
            let cipherArgs = isEncrypt ? [text, 'utf8', 'hex'] : [text, 'hex', 'utf8'];

            let cipher = crypto[cryptMethod](algo, secret);
            let result = cipher.update.apply(cipher, cipherArgs);
            result += cipher.final(finalParam);

            return result;
        },
        encrypt (text) {
            return this._cryptHelper(text, true);
        },
        decrypt (text) {
            return this._cryptHelper(text, false);
        },
        stringifyAndEncrypt (data, withEncryption) {
            let stringifiedData = JSON.stringify(data);

            if (withEncryption) {
                return this.encrypt(stringifiedData);
            } else {
                return stringifiedData;
            }
        },
        decryptAndParse (msg, withEncryption) {
            if (withEncryption) {
                msg = this.decrypt(msg);
            }
            return JSON.parse(msg);
        }
    };
}

export default CryptHelper;
<|endoftext|>


<commit_before>require('./tags/todo.tag');

riot.mount('todo', {
  title: 'I want to behave!',
  items: [
    { title: 'Avoid excessive coffeine', done: true },
    { title: 'Hidden item', hidden: true },
    { title: 'Be less provocative' },
    { title: 'Be nice to people' }
  ]
});

<commit_msg>https://github.com/txchen/feplay/tree/gh-pages/riot_babel<commit_after>require("babel/polyfill");
require('./tags/todo.tag');

riot.mount('todo', {
  title: 'I want to behave!',
  items: [
    { title: 'Avoid excessive coffeine', done: true },
    { title: 'Hidden item', hidden: true },
    { title: 'Be less provocative' },
    { title: 'Be nice to people' }
  ]
});

<|endoftext|>


<commit_before>/*global $serverSide, createInheritVars, inheritVars, listenTo, objectEvents, walkInheritTree */
// Save a copy of the _on method to call as a $super method
var _on = Thorax.View.prototype.on;

inheritVars.event = {
  name: '_events',

  configure: function() {
    var self = this;
    walkInheritTree(this.constructor, '_events', true, function(event) {
      self.on.apply(self, event);
    });
    walkInheritTree(this, 'events', false, function(handler, eventName) {
      self.on(eventName, handler, self);
    });
  }
};

_.extend(Thorax.View, {
  on: function(eventName, callback) {
    createInheritVars(this);

    if (objectEvents(this, eventName, callback)) {
      return this;
    }

    //accept on({"rendered": handler})
    if (_.isObject(eventName)) {
      _.each(eventName, function(value, key) {
        this.on(key, value);
      }, this);
    } else {
      //accept on({"rendered": [handler, handler]})
      if (_.isArray(callback)) {
        _.each(callback, function(cb) {
          this._events.push([eventName, cb]);
        }, this);
      //accept on("rendered", handler)
      } else {
        this._events.push([eventName, callback]);
      }
    }
    return this;
  }
});

_.extend(Thorax.View.prototype, {
  on: function(eventName, callback, context) {
    if (objectEvents(this, eventName, callback, context)) {
      return this;
    }

    if (_.isObject(eventName) && arguments.length < 3) {
      //accept on({"rendered": callback})
      _.each(eventName, function(value, key) {
        this.on(key, value, callback || this);    // callback is context in this form of the call
      }, this);
    } else {
      //accept on("rendered", callback, context)
      //accept on("click a", callback, context)
      _.each((_.isArray(callback) ? callback : [callback]), function(callback) {
        var params = eventParamsFromEventItem.call(this, eventName, callback, context || this);
        if (params.type === 'DOM') {
          // Avoid overhead of handling DOM events on the server
          if ($serverSide) {
            return;
          }

          //will call _addEvent during delegateEvents()
          if (!this._eventsToDelegate) {
            this._eventsToDelegate = [];
          }
          this._eventsToDelegate.push(params);
        }
        if (params.type !== 'DOM' || this._eventsDelegated) {
          this._addEvent(params);
        }
      }, this);
    }
    return this;
  },
  delegateEvents: function(events) {
    this.undelegateEvents();
    if (events) {
      if (_.isFunction(events)) {
        events = events.call(this);
      }
      this._eventsToDelegate = [];
      this.on(events);
    }
    _.each(this._eventsToDelegate, this._addEvent, this);
    this._eventsDelegated = true;
  },
  //params may contain:
  //- name
  //- originalName
  //- selector
  //- type "view" || "DOM"
  //- handler
  _addEvent: function(params) {
    // If this is recursvie due to listenTo delegate below then pass through to super class
    if (params.handler._thoraxBind) {
      return _on.call(this, params.name, params.handler, params.context || this);
    }

    // Shortcircuit DOM events on the server
    if ($serverSide && params.type !== 'view') {
      return;
    }

    var boundHandler = bindEventHandler.call(this, params.type + '-event:', params);

    if (params.type === 'view') {
      // If we have our context set to an outside view then listen rather than directly bind so
      // we can cleanup properly.
      if (params.context && params.context !== this && params.context instanceof Thorax.View) {
        listenTo(params.context, this, params.name, boundHandler, params.context);
      } else {
        _on.call(this, params.name, boundHandler, params.context || this);
      }
    } else if (!$serverSide) {
      // DOM Events
      if (!params.nested) {
        boundHandler = containHandlerToCurentView(boundHandler, this.cid);
      }

      var name = params.name + '.delegateEvents' + this.cid;
      if (params.selector) {
        this.$el.on(name, params.selector, boundHandler);
      } else {
        this.$el.on(name, boundHandler);
      }
    }
  }
});

Thorax.View.prototype.bind = Thorax.View.prototype.on;

// When view is ready trigger ready event on all
// children that are present, then register an
// event that will trigger ready on new children
// when they are added
Thorax.View.on('ready', function(options) {
  if (!this._isReady) {
    this._isReady = true;
    function triggerReadyOnChild(child) {
      child._isReady || child.trigger('ready', options);
    }
    _.each(this.children, triggerReadyOnChild);
    this.on('child', triggerReadyOnChild);
  }
});

var eventSplitter = /^(nested\s+)?(\S+)(?:\s+(.+))?/;

var domEvents = [],
    domEventRegexp;
function pushDomEvents(events) {
  domEvents.push.apply(domEvents, events);
  domEventRegexp = new RegExp('^(nested\\s+)?(' + domEvents.join('|') + ')(?:\\s|$)');
}
pushDomEvents([
  'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout',
  'touchstart', 'touchend', 'touchmove',
  'click', 'dblclick',
  'keyup', 'keydown', 'keypress',
  'submit', 'change', 'input',
  'focus', 'blur'
]);

function containHandlerToCurentView(handler, cid) {
  return function(event) {
    var view = $(event.target).view({helper: false});
    if (view && view.cid === cid) {
      event.originalContext = this;
      return handler(event);
    }
  };
}

function bindEventHandler(eventName, params) {
  eventName += params.originalName;

  var callback = params.handler,
      method = _.isFunction(callback) ? callback : this[callback];
  if (!method) {
    throw new Error('Event "' + callback + '" does not exist ' + (this.name || this.cid) + ':' + eventName);
  }

  var context = params.context || this,
      ret = Thorax.bindSection(
        'thorax-event',
        {view: context.name || context.cid, eventName: eventName},
        _.bind(method, context));

  // Backbone will delegate to _callback in off calls so we should still be able to support
  // calling off on specific handlers.
  ret._callback = method;
  ret._thoraxBind = true;
  return ret;
}

function eventParamsFromEventItem(name, handler, context) {
  var params = {
    originalName: name,
    handler: _.isString(handler) ? this[handler] : handler
  };
  if (name.match(domEventRegexp)) {
    var match = eventSplitter.exec(name);
    params.nested = !!match[1];
    params.name = match[2];
    params.type = 'DOM';
    params.selector = match[3];
  } else {
    params.name = name;
    params.type = 'view';
  }
  params.context = context;
  return params;
}
<commit_msg>Handle cid remap in containHandleToCurrentView<commit_after>/*global $serverSide, createInheritVars, inheritVars, listenTo, objectEvents, walkInheritTree */
// Save a copy of the _on method to call as a $super method
var _on = Thorax.View.prototype.on;

inheritVars.event = {
  name: '_events',

  configure: function() {
    var self = this;
    walkInheritTree(this.constructor, '_events', true, function(event) {
      self.on.apply(self, event);
    });
    walkInheritTree(this, 'events', false, function(handler, eventName) {
      self.on(eventName, handler, self);
    });
  }
};

_.extend(Thorax.View, {
  on: function(eventName, callback) {
    createInheritVars(this);

    if (objectEvents(this, eventName, callback)) {
      return this;
    }

    //accept on({"rendered": handler})
    if (_.isObject(eventName)) {
      _.each(eventName, function(value, key) {
        this.on(key, value);
      }, this);
    } else {
      //accept on({"rendered": [handler, handler]})
      if (_.isArray(callback)) {
        _.each(callback, function(cb) {
          this._events.push([eventName, cb]);
        }, this);
      //accept on("rendered", handler)
      } else {
        this._events.push([eventName, callback]);
      }
    }
    return this;
  }
});

_.extend(Thorax.View.prototype, {
  on: function(eventName, callback, context) {
    if (objectEvents(this, eventName, callback, context)) {
      return this;
    }

    if (_.isObject(eventName) && arguments.length < 3) {
      //accept on({"rendered": callback})
      _.each(eventName, function(value, key) {
        this.on(key, value, callback || this);    // callback is context in this form of the call
      }, this);
    } else {
      //accept on("rendered", callback, context)
      //accept on("click a", callback, context)
      _.each((_.isArray(callback) ? callback : [callback]), function(callback) {
        var params = eventParamsFromEventItem.call(this, eventName, callback, context || this);
        if (params.type === 'DOM') {
          // Avoid overhead of handling DOM events on the server
          if ($serverSide) {
            return;
          }

          //will call _addEvent during delegateEvents()
          if (!this._eventsToDelegate) {
            this._eventsToDelegate = [];
          }
          this._eventsToDelegate.push(params);
        }
        if (params.type !== 'DOM' || this._eventsDelegated) {
          this._addEvent(params);
        }
      }, this);
    }
    return this;
  },
  delegateEvents: function(events) {
    this.undelegateEvents();
    if (events) {
      if (_.isFunction(events)) {
        events = events.call(this);
      }
      this._eventsToDelegate = [];
      this.on(events);
    }
    _.each(this._eventsToDelegate, this._addEvent, this);
    this._eventsDelegated = true;
  },
  //params may contain:
  //- name
  //- originalName
  //- selector
  //- type "view" || "DOM"
  //- handler
  _addEvent: function(params) {
    // If this is recursvie due to listenTo delegate below then pass through to super class
    if (params.handler._thoraxBind) {
      return _on.call(this, params.name, params.handler, params.context || this);
    }

    // Shortcircuit DOM events on the server
    if ($serverSide && params.type !== 'view') {
      return;
    }

    var boundHandler = bindEventHandler.call(this, params.type + '-event:', params);

    if (params.type === 'view') {
      // If we have our context set to an outside view then listen rather than directly bind so
      // we can cleanup properly.
      if (params.context && params.context !== this && params.context instanceof Thorax.View) {
        listenTo(params.context, this, params.name, boundHandler, params.context);
      } else {
        _on.call(this, params.name, boundHandler, params.context || this);
      }
    } else if (!$serverSide) {
      // DOM Events
      if (!params.nested) {
        boundHandler = containHandlerToCurentView(boundHandler, this);
      }

      var name = params.name + '.delegateEvents' + this.cid;
      if (params.selector) {
        this.$el.on(name, params.selector, boundHandler);
      } else {
        this.$el.on(name, boundHandler);
      }
    }
  }
});

Thorax.View.prototype.bind = Thorax.View.prototype.on;

// When view is ready trigger ready event on all
// children that are present, then register an
// event that will trigger ready on new children
// when they are added
Thorax.View.on('ready', function(options) {
  if (!this._isReady) {
    this._isReady = true;
    function triggerReadyOnChild(child) {
      child._isReady || child.trigger('ready', options);
    }
    _.each(this.children, triggerReadyOnChild);
    this.on('child', triggerReadyOnChild);
  }
});

var eventSplitter = /^(nested\s+)?(\S+)(?:\s+(.+))?/;

var domEvents = [],
    domEventRegexp;
function pushDomEvents(events) {
  domEvents.push.apply(domEvents, events);
  domEventRegexp = new RegExp('^(nested\\s+)?(' + domEvents.join('|') + ')(?:\\s|$)');
}
pushDomEvents([
  'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout',
  'touchstart', 'touchend', 'touchmove',
  'click', 'dblclick',
  'keyup', 'keydown', 'keypress',
  'submit', 'change', 'input',
  'focus', 'blur'
]);

function containHandlerToCurentView(handler, current) {
  return function(event) {
    var view = $(event.target).view({helper: false});
    if (view && view.cid === current.cid) {
      event.originalContext = this;
      return handler(event);
    }
  };
}

function bindEventHandler(eventName, params) {
  eventName += params.originalName;

  var callback = params.handler,
      method = _.isFunction(callback) ? callback : this[callback];
  if (!method) {
    throw new Error('Event "' + callback + '" does not exist ' + (this.name || this.cid) + ':' + eventName);
  }

  var context = params.context || this,
      ret = Thorax.bindSection(
        'thorax-event',
        {view: context.name || context.cid, eventName: eventName},
        _.bind(method, context));

  // Backbone will delegate to _callback in off calls so we should still be able to support
  // calling off on specific handlers.
  ret._callback = method;
  ret._thoraxBind = true;
  return ret;
}

function eventParamsFromEventItem(name, handler, context) {
  var params = {
    originalName: name,
    handler: _.isString(handler) ? this[handler] : handler
  };
  if (name.match(domEventRegexp)) {
    var match = eventSplitter.exec(name);
    params.nested = !!match[1];
    params.name = match[2];
    params.type = 'DOM';
    params.selector = match[3];
  } else {
    params.name = name;
    params.type = 'view';
  }
  params.context = context;
  return params;
}
<|endoftext|>


<commit_before>/**
 * Fetch an HTTP url to a local file.
 **/

var http = require("/http.js");

exports.fetch = function fetch (remote, local, headers, encoding) {
  var p = new node.Promise();

  var uri = http.parseUri(remote);
  headers = headers || {};
  headers.Host = uri.host;

  http
    .createClient(uri.port || (uri.protocol === "https" ? 443 : 80), uri.host)
    .get(uri.path || "/", headers)
    .finish(function (response) {
      // try to get the encoding
      response.setBodyEncoding("utf8");

      response.addListener("body", function (chunk) {
        // write the chunk...
        log("got a chunk of body");
      });
      response.addListener("error", function () {
        log("failure: could not download "+tarball);
        p.emitError();
      });
      response.addListener("complete", function () {
        log("downloaded: "+tarball);
        p.emitSuccess();
      });
    });

  return p;
};<commit_msg>Got the cookie thing figured out.  It's pretty weak right now, but it'll do for the moment.  Need a proper wget/curl type module, but that should probably be its own thing.<commit_after>/**
 * Fetch an HTTP url to a local file.
 **/

var http = require("/http.js");

function get (obj, key) {
  for (var i in obj) if (i.toLowerCase() === key.toLowerCase()) return obj[i];
  return undefined;
};
function set (obj, key, val) {
  for (var i in obj) if (i.toLowerCase() === key.toLowerCase()) return obj[i] = val;
  return obj[key] = val;
};

function bind (o, fn) {
  return function () {
    return fn.apply(o, arguments);
  };
};

exports.fetch = function fetch (remote, local, headers) {
  var p = new node.Promise();

  var uri = http.parseUri(remote);
  headers = headers || {};
  headers.Host = uri.host;

  node.fs.open(
    local,
    node.O_CREAT | node.O_WRONLY | node.O_TRUNC | node.O_APPEND | node.O_SYMLINK,
    0755
  ).addErrback(function () {
    p.emitError("could not open "+local+" for writing.");
  }).addCallback(function (fd) {
    fetchAndWrite(remote, fd, p, headers);
  });

  return p;
};

function fetchAndWrite (remote, fd, p, headers, maxRedirects, redirects) {
  redirects = redirects || 0;
  maxRedirects = maxRedirects || 10;
  var uri = http.parseUri(remote);
  log(remote);
  set(headers, "Host", uri.host);

  http
    .createClient(uri.port || (uri.protocol === "https" ? 443 : 80), uri.host)
    .get(uri.path || "/", headers)
    .finish(function (response) {
      // handle redirects.
      var loc = get(response.headers, "location");
      if (loc && loc !== remote && redirects < maxRedirects) {
        // This is a laughably naïve way to handle this situation.
        // @TODO: Really need a full curl or wget style module that would
        // do all this kind of stuff for us.
        var cookie = get(response.headers, "Set-Cookie");
        if (cookie) {
          cookie = cookie.split(";").shift();
          set(headers, "Cookie", cookie);
        }
        return fetchAndWrite(loc, fd, p, headers, maxRedirects, redirects + 1);
      }

      // don't set the encoding, because we're just going to write the bytes as-is
      response.addListener("body", function (chunk) {
        // write the chunk...
        node.fs.write(fd, chunk)
          .addErrback(function () {
            p.emitError("write error");
          });
      });
      response.addListener("error", bind(p, p.emitError));
      response.addListener("complete", bind(p, p.emitSuccess));
    });
}

function log (msg) {
  node.stdio.writeError("npm: fetch "+msg+"\n");
}<|endoftext|>


<commit_before>var shell   = require('shelljs'),
    fs      = require('fs'),
    url     = require('url'),
    plugins = require('./util/plugins'),
    xml_helpers = require('./util/xml-helpers'),
    metadata = require('./util/metadata'),
    path    = require('path'),
    Q       = require('q'),
    registry = require('./registry/registry');
// XXX: leave the require('../plugman') because jasmine shits itself if you declare it up top
// possible options: link, subdir, git_ref, client, expected_id
// Returns a promise.
module.exports = function fetchPlugin(plugin_dir, plugins_dir, options) {
    require('../plugman').emit('log', 'Fetching plugin from "' + plugin_dir + '"...');
    // Ensure the containing directory exists.
    shell.mkdir('-p', plugins_dir);

    options = options || {};
    options.subdir = options.subdir || '.';

    // clone from git repository
    var uri = url.parse(plugin_dir);

    // If the hash exists, it has the form from npm: http://foo.com/bar#git-ref[:subdir]
    // NB: No leading or trailing slash on the subdir.
    if (uri.hash) {
        var result = uri.hash.match(/^#([^:]*)(?::\/?(.*?)\/?)?$/);
        if (result) {
            if (result[1])
                options.git_ref = result[1];
            if(result[2])
                options.subdir = result[2];

            // Recurse and exit with the new options and truncated URL.
            var new_dir = plugin_dir.substring(0, plugin_dir.indexOf('#'));
            return fetchPlugin(new_dir, plugins_dir, options);
        }
    }

    if ( uri.protocol && uri.protocol != 'file:' && !plugin_dir.match(/^\w+:\\/)) {
        if (options.link) {
            return Q.reject(new Error('--link is not supported for git URLs'));
        } else {
            var data = {
                source: {
                    type: 'git',
                    url:  plugin_dir,
                    subdir: options.subdir,
                    ref: options.git_ref
                }
            };

            return plugins.clonePluginGitRepo(plugin_dir, plugins_dir, options.subdir, options.git_ref)
            .then(function(dir) {
                return checkID(options, dir);
            })
            .then(function(dir) {
                metadata.save_fetch_metadata(dir, data);
                return dir;
            });
        }
    } else {

        // Copy from the local filesystem.
        // First, read the plugin.xml and grab the ID.
        // NOTE: Can't use uri.href here as it will convert spaces to %20 and make path invalid.
        // Use original plugin_dir value instead.
        plugin_dir = path.join(plugin_dir, options.subdir);

        var linkable = true;
        var movePlugin = function(plugin_dir) {
            var plugin_xml_path = path.join(plugin_dir, 'plugin.xml');
            require('../plugman').emit('verbose', 'Fetch is reading plugin.xml from location "' + plugin_xml_path + '"...');
            var xml = xml_helpers.parseElementtreeSync(plugin_xml_path);
            var plugin_id = xml.getroot().attrib.id;

            var dest = path.join(plugins_dir, plugin_id);

            if(fs.lstatSync(dest).isSymbolicLink()) fs.unlinkSync(dest);
            else shell.rm('-rf', dest);
            if (options.link && linkable) {
                require('../plugman').emit('verbose', 'Symlinking from location "' + plugin_dir + '" to location "' + dest + '"');
                fs.symlinkSync(plugin_dir, dest, 'dir');
            } else {
                shell.mkdir('-p', dest);
                require('../plugman').emit('verbose', 'Copying from location "' + plugin_dir + '" to location "' + dest + '"');
                shell.cp('-R', path.join(plugin_dir, '*') , dest);
            }

            var data = {
                source: {
                type: 'local',
                      path: plugin_dir
                }
            };
            metadata.save_fetch_metadata(dest, data);
            return dest;
        };

        var repoSet = options.repoSet;
        if(repoSet) {
            options.link = true; // 内部开发模式下，安装reposet下的插件使用link的方式
            var pluginPath = findPluginById(repoSet, plugin_dir);
            if(pluginPath) {
                require('../plugman').emit('verbose', 'Find plugin ' + plugin_dir + ' in location "' + pluginPath + '"');
                plugin_dir = pluginPath;
            }
        }
        if(!fs.existsSync(plugin_dir)) {
            return registry.fetch([plugin_dir], options.client)
            .then(function(dir) {
                linkable = false;
                return movePlugin(dir);
            })
            .then(function(dir) {
                return checkID(options, dir);
            });
        } else {
            return Q(movePlugin(plugin_dir))
            .then(function(dir) {
                return checkID(options, dir);
            });
        }
    }
};

function findPluginById(repoSet, pluginId) {
    var pluginPath = null;
    if (fs.existsSync(repoSet)) {
        fs.readdirSync(repoSet).every(function (fileName) {
            if(fileName.match(/-(extension|plugin)-/)) {
                var xml = xml_helpers.parseElementtreeSync(path.join(repoSet, fileName, 'plugin.xml'));
                if(pluginId == xml.getroot().attrib.id) {
                    pluginPath = path.join(repoSet, fileName);
                    return false;
                }
            }
            return true;
        });
    }
    return pluginPath;
}

// Helper function for checking expected plugin IDs against reality.
function checkID(options, dir) {
    // Read the plugin.xml file and check the ID matches options.expected_id if set.
    if (options.expected_id) {
        var et = xml_helpers.parseElementtreeSync(path.join(dir, 'plugin.xml'));
        if (et.getroot().attrib.id == options.expected_id) {
            return dir;
        } else {
            return Q.reject(new Error('Expected Fetched plugin to have ID "' + options.expected_id + '" but got "' + et.getroot().attrib.id + '".'));
        }
    }
    return dir;
}
<commit_msg>修正一处未检查文件是否存在的错误<commit_after>var shell   = require('shelljs'),
    fs      = require('fs'),
    url     = require('url'),
    plugins = require('./util/plugins'),
    xml_helpers = require('./util/xml-helpers'),
    metadata = require('./util/metadata'),
    path    = require('path'),
    Q       = require('q'),
    registry = require('./registry/registry');
// XXX: leave the require('../plugman') because jasmine shits itself if you declare it up top
// possible options: link, subdir, git_ref, client, expected_id
// Returns a promise.
module.exports = function fetchPlugin(plugin_dir, plugins_dir, options) {
    require('../plugman').emit('log', 'Fetching plugin from "' + plugin_dir + '"...');
    // Ensure the containing directory exists.
    shell.mkdir('-p', plugins_dir);

    options = options || {};
    options.subdir = options.subdir || '.';

    // clone from git repository
    var uri = url.parse(plugin_dir);

    // If the hash exists, it has the form from npm: http://foo.com/bar#git-ref[:subdir]
    // NB: No leading or trailing slash on the subdir.
    if (uri.hash) {
        var result = uri.hash.match(/^#([^:]*)(?::\/?(.*?)\/?)?$/);
        if (result) {
            if (result[1])
                options.git_ref = result[1];
            if(result[2])
                options.subdir = result[2];

            // Recurse and exit with the new options and truncated URL.
            var new_dir = plugin_dir.substring(0, plugin_dir.indexOf('#'));
            return fetchPlugin(new_dir, plugins_dir, options);
        }
    }

    if ( uri.protocol && uri.protocol != 'file:' && !plugin_dir.match(/^\w+:\\/)) {
        if (options.link) {
            return Q.reject(new Error('--link is not supported for git URLs'));
        } else {
            var data = {
                source: {
                    type: 'git',
                    url:  plugin_dir,
                    subdir: options.subdir,
                    ref: options.git_ref
                }
            };

            return plugins.clonePluginGitRepo(plugin_dir, plugins_dir, options.subdir, options.git_ref)
            .then(function(dir) {
                return checkID(options, dir);
            })
            .then(function(dir) {
                metadata.save_fetch_metadata(dir, data);
                return dir;
            });
        }
    } else {

        // Copy from the local filesystem.
        // First, read the plugin.xml and grab the ID.
        // NOTE: Can't use uri.href here as it will convert spaces to %20 and make path invalid.
        // Use original plugin_dir value instead.
        plugin_dir = path.join(plugin_dir, options.subdir);

        var linkable = true;
        var movePlugin = function(plugin_dir) {
            var plugin_xml_path = path.join(plugin_dir, 'plugin.xml');
            require('../plugman').emit('verbose', 'Fetch is reading plugin.xml from location "' + plugin_xml_path + '"...');
            var xml = xml_helpers.parseElementtreeSync(plugin_xml_path);
            var plugin_id = xml.getroot().attrib.id;

            var dest = path.join(plugins_dir, plugin_id);

            if(fs.existsSync(dest) && fs.lstatSync(dest).isSymbolicLink()) fs.unlinkSync(dest);
            else shell.rm('-rf', dest);
            if (options.link && linkable) {
                require('../plugman').emit('verbose', 'Symlinking from location "' + plugin_dir + '" to location "' + dest + '"');
                fs.symlinkSync(plugin_dir, dest, 'dir');
            } else {
                shell.mkdir('-p', dest);
                require('../plugman').emit('verbose', 'Copying from location "' + plugin_dir + '" to location "' + dest + '"');
                shell.cp('-R', path.join(plugin_dir, '*') , dest);
            }

            var data = {
                source: {
                type: 'local',
                      path: plugin_dir
                }
            };
            metadata.save_fetch_metadata(dest, data);
            return dest;
        };

        var repoSet = options.repoSet;
        if(repoSet) {
            options.link = true; // 内部开发模式下，安装reposet下的插件使用link的方式
            var pluginPath = findPluginById(repoSet, plugin_dir);
            if(pluginPath) {
                require('../plugman').emit('verbose', 'Find plugin ' + plugin_dir + ' in location "' + pluginPath + '"');
                plugin_dir = pluginPath;
            }
        }
        if(!fs.existsSync(plugin_dir)) {
            return registry.fetch([plugin_dir], options.client)
            .then(function(dir) {
                linkable = false;
                return movePlugin(dir);
            })
            .then(function(dir) {
                return checkID(options, dir);
            });
        } else {
            return Q(movePlugin(plugin_dir))
            .then(function(dir) {
                return checkID(options, dir);
            });
        }
    }
};

function findPluginById(repoSet, pluginId) {
    var pluginPath = null;
    if (fs.existsSync(repoSet)) {
        fs.readdirSync(repoSet).every(function (fileName) {
            if(fileName.match(/-(extension|plugin)-/)) {
                var xml = xml_helpers.parseElementtreeSync(path.join(repoSet, fileName, 'plugin.xml'));
                if(pluginId == xml.getroot().attrib.id) {
                    pluginPath = path.join(repoSet, fileName);
                    return false;
                }
            }
            return true;
        });
    }
    return pluginPath;
}

// Helper function for checking expected plugin IDs against reality.
function checkID(options, dir) {
    // Read the plugin.xml file and check the ID matches options.expected_id if set.
    if (options.expected_id) {
        var et = xml_helpers.parseElementtreeSync(path.join(dir, 'plugin.xml'));
        if (et.getroot().attrib.id == options.expected_id) {
            return dir;
        } else {
            return Q.reject(new Error('Expected Fetched plugin to have ID "' + options.expected_id + '" but got "' + et.getroot().attrib.id + '".'));
        }
    }
    return dir;
}
<|endoftext|>


<commit_before>// 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.

export function appArgs(yargs) {
  yargs.option('app-args', {
    description: 'Arguments passed to the app.',
    type: 'string',
  })
}

export function browsers(yargs) {
  yargs.option('browsers', {
    description: 'Browsers supported.',
    type: 'array',
  })
}

export function bundleStats(yargs) {
  yargs.option('bundle-stats', {
    description: 'Generate a “bundle-stats.json” file.',
    type: 'boolean',
  })
}

export function commentFlow(yargs) {
  yargs.option('comment-flow', {
    description: 'Convert Flow annotations to comments.',
    type: 'boolean',
  })
}

export function disableExperimentalPlugins(yargs) {
  yargs.option('disable-experimental-plugins', {
    description: 'Disable Babel’s experimental plugins.',
    type: 'boolean',
  })
}

export function disableFlowTyped(yargs) {
  yargs.option('disable-flow-typed', {
    description: 'Disable FlowTyped.',
    type: 'boolean',
  })
}

export function disableSourceMaps(yargs) {
  yargs.option('disable-source-maps', {
    description: 'Disable source map generation.',
    type: 'boolean',
  })
}

export function flow(yargs) {
  yargs.option('flow', {
    description: 'Enable Flow annotations.',
    type: 'boolean',
  })
}

export function inspect(yargs) {
  yargs.option('inspect', {
    description: 'Enable NodeJS inspector.',
    type: 'boolean',
  })
}

export function jsx(yargs) {
  yargs.option('jsx', {
    description: 'Enable JSX.',
    type: 'boolean',
  })
}

export function interactiveBundleStats(yargs) {
  yargs.option('interactive-bundle-stats', {
    description: 'Generate an interactive tree map of the bundle.',
    type: 'boolean',
  })
}

export function minify(yargs) {
  yargs.option('minify', {
    description: 'Minify source.',
    type: 'boolean',
  })
}

export function multiEntry(yargs) {
  yargs.option('multi-entry', {
    description: 'Enable default multi entries.',
    type: 'boolean',
  })
}

export function node(yargs) {
  yargs.option('node', {
    description: 'Minimum NodeJS version supported.',
    type: 'string',
  })
}

export function platforms(yargs) {
  yargs.option('platforms', {
    choices: ['browser', 'node'],
    description: 'Fine tune polyfills and linter.',
    type: 'array',
  })
}

export function port(yargs) {
  yargs.option('port', {
    description: 'Port used to serve the app.',
    type: 'number',
  })
}

export function production(yargs) {
  yargs.option('production', {
    description: 'Set NODE_ENV to production.',
    type: 'boolean',
  })
}

export function projectType(yargs) {
  yargs.option('project-type', {
    choices: [
      'cli',
      'lib',
      'node-app',
      'node-lib',
      'react',
      'web-lib',
    ],
    description: 'Affects the build output.',
    type: 'string',
  })
}

export function react(yargs) {
  yargs.option('react', {
    description: 'Enable React transformations.',
    type: 'boolean',
  })
}

export function removeFlow(yargs) {
  yargs.option('remove-flow', {
    description: 'Remove Flow annotations.',
    type: 'boolean',
  })
}

export function typeScript(yargs) {
  yargs.option('type-script', {
    description: 'Enable TypeScript.',
    type: 'boolean',
  })
}

export function watch(yargs) {
  yargs.options({
    watch: {
      default: false,
      description: 'Watch for changes.',
      type: 'boolean',
    },
  })
}
<commit_msg>Remove dead code<commit_after>// 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.

export function appArgs(yargs) {
  yargs.option('app-args', {
    description: 'Arguments passed to the app.',
    type: 'string',
  })
}

export function browsers(yargs) {
  yargs.option('browsers', {
    description: 'Browsers supported.',
    type: 'array',
  })
}

export function bundleStats(yargs) {
  yargs.option('bundle-stats', {
    description: 'Generate a “bundle-stats.json” file.',
    type: 'boolean',
  })
}

export function commentFlow(yargs) {
  yargs.option('comment-flow', {
    description: 'Convert Flow annotations to comments.',
    type: 'boolean',
  })
}

export function disableExperimentalPlugins(yargs) {
  yargs.option('disable-experimental-plugins', {
    description: 'Disable Babel’s experimental plugins.',
    type: 'boolean',
  })
}

export function disableSourceMaps(yargs) {
  yargs.option('disable-source-maps', {
    description: 'Disable source map generation.',
    type: 'boolean',
  })
}

export function flow(yargs) {
  yargs.option('flow', {
    description: 'Enable Flow annotations.',
    type: 'boolean',
  })
}

export function inspect(yargs) {
  yargs.option('inspect', {
    description: 'Enable NodeJS inspector.',
    type: 'boolean',
  })
}

export function jsx(yargs) {
  yargs.option('jsx', {
    description: 'Enable JSX.',
    type: 'boolean',
  })
}

export function interactiveBundleStats(yargs) {
  yargs.option('interactive-bundle-stats', {
    description: 'Generate an interactive tree map of the bundle.',
    type: 'boolean',
  })
}

export function minify(yargs) {
  yargs.option('minify', {
    description: 'Minify source.',
    type: 'boolean',
  })
}

export function multiEntry(yargs) {
  yargs.option('multi-entry', {
    description: 'Enable default multi entries.',
    type: 'boolean',
  })
}

export function node(yargs) {
  yargs.option('node', {
    description: 'Minimum NodeJS version supported.',
    type: 'string',
  })
}

export function platforms(yargs) {
  yargs.option('platforms', {
    choices: ['browser', 'node'],
    description: 'Fine tune polyfills and linter.',
    type: 'array',
  })
}

export function port(yargs) {
  yargs.option('port', {
    description: 'Port used to serve the app.',
    type: 'number',
  })
}

export function production(yargs) {
  yargs.option('production', {
    description: 'Set NODE_ENV to production.',
    type: 'boolean',
  })
}

export function projectType(yargs) {
  yargs.option('project-type', {
    choices: [
      'cli',
      'lib',
      'node-app',
      'node-lib',
      'react',
      'web-lib',
    ],
    description: 'Affects the build output.',
    type: 'string',
  })
}

export function react(yargs) {
  yargs.option('react', {
    description: 'Enable React transformations.',
    type: 'boolean',
  })
}

export function removeFlow(yargs) {
  yargs.option('remove-flow', {
    description: 'Remove Flow annotations.',
    type: 'boolean',
  })
}

export function typeScript(yargs) {
  yargs.option('type-script', {
    description: 'Enable TypeScript.',
    type: 'boolean',
  })
}

export function watch(yargs) {
  yargs.options({
    watch: {
      default: false,
      description: 'Watch for changes.',
      type: 'boolean',
    },
  })
}
<|endoftext|>


<commit_before>define(["./controls"], function (TrackballControls) {
    "use strict";

    var Frame = function (elem) {
        if (typeof elem === 'string') {
            elem = document.getElementById(elem);
        }

        var width = elem.scrollWidth;
        var height = elem.scrollHeight;

        this.scene = new THREE.Scene();

        this._initCamera(width/height);
        this.scene.add();

        this._initRenderer(width, height);
        elem.appendChild(this.renderer.domElement);

        this._initControls();

        this._initNodes();
        this.scene.add(this.particleSystem);
    };

    Frame.prototype._initCamera = function (aspect) {
        var viewAngle = 45;
        var near = 0.1;
        var far = 10000;

        var camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
        camera.position.z = 10;

        this.camera = camera;
    };

    Frame.prototype._initRenderer = function (width, height) {
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);

        this.renderer = renderer;
    };

    Frame.prototype._initControls = function () {
        var self = this;
        var controls = new TrackballControls(this.camera);

        controls.addEventListener('change', function () {
            self.renderer.render(self.scene, self.camera);
        });

        this.controls = controls;
    };

    Frame.prototype._initNodes = function () {
        var material = new THREE.ParticleSystemMaterial({
            size: 4,
            sizeAttenuation: false,
        });
        this.particles = new THREE.Geometry();
        this.particleSystem = new THREE.ParticleSystem(this.particles, material);
    };

    Frame.prototype.addNode = function (node) {
        this.particles.vertices.push(node.position);
    };

    Frame.prototype.addEdge = function (edge) {
        this.scene.add(edge.line);
    };

    Frame.prototype.render = function () {
        var self = this;

        (function animate() {
            window.requestAnimationFrame(animate);
            self.controls.update();
        }());
    };

    return Frame;
});
<commit_msg>Provide method to center the view<commit_after>define(["./controls", "./Core/BoundingSphere"], function (TrackballControls, BoundingSphere) {
    "use strict";

    var Frame = function (elem) {
        if (typeof elem === 'string') {
            elem = document.getElementById(elem);
        }

        var width = elem.scrollWidth;
        var height = elem.scrollHeight;

        this.scene = new THREE.Scene();

        this._initCamera(width/height);
        this.scene.add();

        this._initRenderer(width, height);
        elem.appendChild(this.renderer.domElement);

        this._initControls();

        this._initNodes();
        this.scene.add(this.particleSystem);
    };

    Frame.prototype._initCamera = function (aspect) {
        var viewAngle = 45;
        var near = 0.1;
        var far = 10000;

        var camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
        camera.position.z = 10;

        this.camera = camera;
    };

    Frame.prototype._initRenderer = function (width, height) {
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);

        this.renderer = renderer;
    };

    Frame.prototype._initControls = function () {
        var self = this;
        var controls = new TrackballControls(this.camera);

        controls.addEventListener('change', function () {
            self.renderer.render(self.scene, self.camera);
        });

        this.controls = controls;
    };

    Frame.prototype._initNodes = function () {
        var material = new THREE.ParticleSystemMaterial({
            size: 4,
            sizeAttenuation: false,
        });
        this.particles = new THREE.Geometry();
        this.particleSystem = new THREE.ParticleSystem(this.particles, material);
    };

    Frame.prototype.addNode = function (node) {
        this.particles.vertices.push(node.position);
    };

    Frame.prototype.addEdge = function (edge) {
        this.scene.add(edge.line);
    };

    Frame.prototype.centerView = function () {
        var sphere = BoundingSphere.fromPoints(this.particles.vertices);
        var center = new THREE.Vector3(sphere.center.x, sphere.center.y, sphere.center.z);
        this.controls.target = center;
    };

    Frame.prototype.render = function () {
        var self = this;

        this.centerView();

        (function animate() {
            window.requestAnimationFrame(animate);
            self.controls.update();
        }());
    };

    return Frame;
});
<|endoftext|>


<commit_before>define(["../lib/trackball-controls/TrackballControls"], function (TrackballControls) {
    "use strict";

    var Frame = function (elem, graph) {
        var self = this;

        if (typeof elem === 'string') {
            elem = document.getElementById(elem);
        }

        this.graph = graph;

        var width = elem.scrollWidth;
        var height = elem.scrollHeight;
        var aspectRatio = width/height;

        this._initScene();
        this._initCamera(aspectRatio);
        this._initRenderer(width, height, elem);
        this._initControls();
        this._initNodes(graph.getNodes());
        this._initEdges(graph.getEdges());

        window.addEventListener('resize', function () {
            self.camera.aspect = window.innerWidth / window.innerHeight;
            self.camera.updateProjectionMatrix();

            self.renderer.setSize(window.innerWidth, window.innerHeight);
            self.forceRerender();
        }, false);

        this._normalize();
        this._animate();
    };

    Frame.prototype._initScene = function () {
        this.scene = new THREE.Scene();
    };

    Frame.prototype._initCamera = function (aspect) {
        var viewAngle = 45;
        var near = 0.1;
        var far = 10000;

        var camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
        camera.position.z = 15;

        this.camera = camera;
    };

    Frame.prototype._initRenderer = function (width, height, elem) {
        var renderer = new THREE.WebGLRenderer({
            antialias: this.graph._antialias,
            alpha: true,
        });
        renderer.setClearColor(this.graph._bgColor, this.graph._bgOpacity);
        renderer.setSize(width, height);
        elem.appendChild(renderer.domElement);

        this.renderer = renderer;
    };

    Frame.prototype.forceRerender = function () {
        this.renderer.render(this.scene, this.camera);
    };

    Frame.prototype._initControls = function () {
        var self = this;
        var controls = new TrackballControls(this.camera);

        controls.addEventListener('change', function () {
            self.forceRerender();
        });

        this.controls = controls;
    };

    Frame.prototype._initNodes = function (nodes) {
        var self = this;

        var material = new THREE.ParticleSystemMaterial({
            size: this.graph._nodeSize,
            vertexColors: true,
            sizeAttenuation: this.graph._sizeAttenuation,
        });

        if (this.graph._nodeImage !== undefined) {
            var texture = THREE.ImageUtils.loadTexture(
                this.graph._nodeImage, undefined, function () {
                    // Force a rerender after node image has finished loading
                    self.forceRerender();
                });
            material.map = texture;
        }

        this.particles = new THREE.Geometry();
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            var vertex = node._pos.clone();
            var color = node._color.clone();

            this.particles.vertices.push(vertex);
            this.particles.colors.push(color);
        }

        this.particleSystem = new THREE.ParticleSystem(this.particles, material);

        if (this.graph._nodeImageTransparent === true) {
            material.transparent = true;
            this.particleSystem.sortParticles = true;
        }

        this.scene.add(this.particleSystem);
    };

    Frame.prototype._initEdges = function (edges) {
        var material = new THREE.LineBasicMaterial({
            vertexColors: true,
            linewidth: this.graph._edgeWidth,
        });
        this.edges = new THREE.Geometry();
        for (var i = 0; i < edges.length; i++) {
            var nodes = edges[i].getNodes();
            this.edges.vertices.push(nodes[0]._pos.clone());
            this.edges.colors.push(edges[i]._color.clone());
            this.edges.vertices.push(nodes[1]._pos.clone());
            this.edges.colors.push(edges[i]._color.clone());
        }
        this.line = new THREE.Line(this.edges, material, THREE.LinePieces);
        this.scene.add(this.line);
    };

    Frame.prototype._normalize = function () {
        // Calculate bounding sphere
        this.particles.computeBoundingSphere();
        var sphere = this.particles.boundingSphere;
        var center = [-sphere.center.x, -sphere.center.y, -sphere.center.z];

        // Create/apply translation transformation matrix
        var translation = new THREE.Matrix4();
        translation.makeTranslation.apply(translation, center);
        this.particles.applyMatrix(translation);
        this.edges.applyMatrix(translation);

        // Determine scale to normalize coordinates
        var scale = 5 / sphere.radius;

        // Scale coordinates
        this.particleSystem.scale.set(scale, scale, scale);
        this.line.scale.set(scale, scale, scale);
    };

    Frame.prototype._animate = function () {
        var self = this;

        (function animate() {
            window.requestAnimationFrame(animate);
            self.controls.update();
        }());
    };

    return Frame;
});
<commit_msg>Controls should use elem instead of document<commit_after>define(["../lib/trackball-controls/TrackballControls"], function (TrackballControls) {
    "use strict";

    var Frame = function (elem, graph) {
        var self = this;

        if (typeof elem === 'string') {
            elem = document.getElementById(elem);
        }

        this.graph = graph;

        var width = elem.scrollWidth;
        var height = elem.scrollHeight;
        var aspectRatio = width/height;

        this._initScene();
        this._initCamera(aspectRatio);
        this._initRenderer(width, height, elem);
        this._initControls(elem);
        this._initNodes(graph.getNodes());
        this._initEdges(graph.getEdges());

        window.addEventListener('resize', function () {
            self.camera.aspect = window.innerWidth / window.innerHeight;
            self.camera.updateProjectionMatrix();

            self.renderer.setSize(window.innerWidth, window.innerHeight);
            self.forceRerender();
        }, false);

        this._normalize();
        this._animate();
    };

    Frame.prototype._initScene = function () {
        this.scene = new THREE.Scene();
    };

    Frame.prototype._initCamera = function (aspect) {
        var viewAngle = 45;
        var near = 0.1;
        var far = 10000;

        var camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
        camera.position.z = 15;

        this.camera = camera;
    };

    Frame.prototype._initRenderer = function (width, height, elem) {
        var renderer = new THREE.WebGLRenderer({
            antialias: this.graph._antialias,
            alpha: true,
        });
        renderer.setClearColor(this.graph._bgColor, this.graph._bgOpacity);
        renderer.setSize(width, height);
        elem.appendChild(renderer.domElement);

        this.renderer = renderer;
    };

    Frame.prototype.forceRerender = function () {
        this.renderer.render(this.scene, this.camera);
    };

    Frame.prototype._initControls = function (elem) {
        var self = this;
        var controls = new TrackballControls(this.camera, elem);

        controls.addEventListener('change', function () {
            self.forceRerender();
        });

        this.controls = controls;
    };

    Frame.prototype._initNodes = function (nodes) {
        var self = this;

        var material = new THREE.ParticleSystemMaterial({
            size: this.graph._nodeSize,
            vertexColors: true,
            sizeAttenuation: this.graph._sizeAttenuation,
        });

        if (this.graph._nodeImage !== undefined) {
            var texture = THREE.ImageUtils.loadTexture(
                this.graph._nodeImage, undefined, function () {
                    // Force a rerender after node image has finished loading
                    self.forceRerender();
                });
            material.map = texture;
        }

        this.particles = new THREE.Geometry();
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            var vertex = node._pos.clone();
            var color = node._color.clone();

            this.particles.vertices.push(vertex);
            this.particles.colors.push(color);
        }

        this.particleSystem = new THREE.ParticleSystem(this.particles, material);

        if (this.graph._nodeImageTransparent === true) {
            material.transparent = true;
            this.particleSystem.sortParticles = true;
        }

        this.scene.add(this.particleSystem);
    };

    Frame.prototype._initEdges = function (edges) {
        var material = new THREE.LineBasicMaterial({
            vertexColors: true,
            linewidth: this.graph._edgeWidth,
        });
        this.edges = new THREE.Geometry();
        for (var i = 0; i < edges.length; i++) {
            var nodes = edges[i].getNodes();
            this.edges.vertices.push(nodes[0]._pos.clone());
            this.edges.colors.push(edges[i]._color.clone());
            this.edges.vertices.push(nodes[1]._pos.clone());
            this.edges.colors.push(edges[i]._color.clone());
        }
        this.line = new THREE.Line(this.edges, material, THREE.LinePieces);
        this.scene.add(this.line);
    };

    Frame.prototype._normalize = function () {
        // Calculate bounding sphere
        this.particles.computeBoundingSphere();
        var sphere = this.particles.boundingSphere;
        var center = [-sphere.center.x, -sphere.center.y, -sphere.center.z];

        // Create/apply translation transformation matrix
        var translation = new THREE.Matrix4();
        translation.makeTranslation.apply(translation, center);
        this.particles.applyMatrix(translation);
        this.edges.applyMatrix(translation);

        // Determine scale to normalize coordinates
        var scale = 5 / sphere.radius;

        // Scale coordinates
        this.particleSystem.scale.set(scale, scale, scale);
        this.line.scale.set(scale, scale, scale);
    };

    Frame.prototype._animate = function () {
        var self = this;

        (function animate() {
            window.requestAnimationFrame(animate);
            self.controls.update();
        }());
    };

    return Frame;
});
<|endoftext|>


<commit_before>export { e, a, x, l, m, p, q } from "./construct";

export { appendChild, insertChildBefore, removeChild } from "./modify";

export { docIter, nextNode, firstChild, nextSibling, parent, children, childrenByName } from "./access";

export { fromL3, toL3 } from "./l3";

export * from "./validate";

export { render } from "./render";

export * from "./dom-util";

export * from "./form";
<commit_msg>cleanup<commit_after>export * from "./construct";

export * from "./modify";

export * from "./access";

export * from "./l3";

export * from "./validate";

export * from "./render";

export * from "./dom-util";
<|endoftext|>