<commit_before>import React from 'react'

import LeftNav from 'material-ui/lib/left-nav'
import AppBar from 'material-ui/lib/app-bar'
import List from 'material-ui/lib/lists/list';
import ListItem from 'material-ui/lib/lists/list-item'
import ArrowDropRight from 'material-ui/lib/svg-icons/navigation-arrow-drop-right'
import RadioButton from 'material-ui/lib/radio-button'
import RaisedButton from 'material-ui/lib/raised-button'
import DeleteIcon from 'material-ui/lib/svg-icons/action/delete'
import colors from 'material-ui/lib/styles/colors'
import AutoComplete from 'material-ui/lib/auto-complete'

import Types from './types'

export default class AnnotateBar extends React.Component {
  render() {
    let open = !!this.props.currentAnnotation
    let title = this.props.currentAnnotation &&
      this.props.currentAnnotation.type === 'new' ?
      "Annotieren" : "Ändern"
    return (
      <LeftNav open={open} openRight={true} width={240}>
        <AppBar title={title} showMenuIconButton={false}/>
        <TypesMenu
            currentAnnotation={this.props.currentAnnotation}
            onType={this.props.onType} onDelete={this.props.onDelete}
            onMetadata={this.props.onMetadata}
            />
      </LeftNav>
    )
  }
}

class TypesMenu extends React.Component {
  render() {
    let annotation = this.props.currentAnnotation

    return (

        {Types.map((category, i) => (
          <List key={i}
              subheader={category.title}
              subheaderStyle={{ lineHeight: '32px' }}
              >
            {category.types.map((type, j) => (
              <ListItem key={j}
                  style={{ backgroundColor: `rgb(${type.rgb})` }}
                  title={type.hint}
                  leftCheckbox={<RadioButton
                      name="type" value={type.id}
                      checked={annotation && annotation.type == type.id}
                      onCheck={ev => this.onCheck(ev)}
                      />}
                    >

{type.title}

                {(type.metadata && annotation && annotation.type == type.id) ?
                  type.metadata.map((keyName, i) =>
                    <TypeMetadata key={i}
                        keyName={keyName} value={annotation && annotation[keyName]}
                        text={annotation && annotation.text}
                        onUpdate={value => this.props.onMetadata(keyName, value)}
                        />
                ) : ""}
              </ListItem>
            ))}
          </List>
        ))}

        {(annotation && annotation.type !== 'new') ?

            <RaisedButton label="Löschen" icon={<DeleteIcon/>}
                backgroundColor={colors.red700} labelColor="white"
                onClick={ev => this.props.onDelete()}
                />

 : ""
        }

    )
  }

  onCheck(ev) {
    let value = ev.target.value
    if (this.props.onType) {
      this.props.onType(value)
    }
  }
}

const METADATA_LABELS = {
  person: "Person",
  organization: "Gremium",
  meeting: "Sitzung",
  paper: "Vorlage",
  file: "Datei",
  location: "Ort"
}

class TypeMetadata extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      byLabel: {},
      labels: [],
      label: ""
    }
  }

  // TODO:
  // * suggest from context (other files in this session, session participants)
  // * suggest from other annotations ("Die Oberbürgermeisterin" maps to the same person)
  _fetchSuggestions(text) {
    // Query with current input or, if empty, annotation text
    let keyName = this.props.keyName
    let typeName = keyName === 'fileref' ? 'file' : keyName
    fetch(`/api/suggest/${typeName}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text: text })
    })
      .then(res => res.json())
      .then(suggestions => {
        let byLabel = {}
        let labels = suggestions.map(suggestion => {
          let s = suggestion.name
          if (suggestion.shortName) s = `${suggestion.shortName}: ${s}`
          if (suggestion.status) s = `${s} (${suggestion.status})`
          byLabel[s] = suggestion.id
          return s
        })
        this.setState({
          byLabel: byLabel,
          labels: labels
        })
        if (!this.state.label && labels[0]) {
          // Nothing yet, input the first suggestion and trigger updateAnnotation
          this.handleUpdateInput(labels[0])
        }
      })
  }

  componentDidMount() {
    if (this.props.value) {
      // Copy metadata value if already existing
      this.setState({
        id: this.props.value.id,
        label: this.props.value.label
      })
    }

    // Initialize suggestions from annotation text
    this._fetchSuggestions(this.props.text)
  }

  componentWillUpdate(nextProps, nextState) {
    if (this.props.value !== nextProps.value || this.props.text !== nextProps.text) {
      // Reset & reinit
      this.setState({
        id: null,
        label: null
      }, () => this.componentDidMount())
    }
  }

  handleUpdateInput(label) {
    let id = this.state.byLabel[label]

    this.setState({ id, label }, () => {
      if (!id) {
        // Update suggestions from text input
        this._fetchSuggestions(label)
      }
      this.props.onUpdate({ id, label })
    })
  }

  render() {
    return (

        <AutoComplete hintText={METADATA_LABELS[this.props.keyName]}
            searchText={this.state.label}
            dataSource={this.state.labels}
            onUpdateInput={label => this.handleUpdateInput(label)}
            onNewRequest={label => this.handleUpdateInput(label)}
            filter={(searchText, key) => true}
            anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
            fullWidth={true}
            />

    )
  }
}
<commit_msg>widen annotate_bar<commit_after>import React from 'react'

import LeftNav from 'material-ui/lib/left-nav'
import AppBar from 'material-ui/lib/app-bar'
import List from 'material-ui/lib/lists/list';
import ListItem from 'material-ui/lib/lists/list-item'
import ArrowDropRight from 'material-ui/lib/svg-icons/navigation-arrow-drop-right'
import RadioButton from 'material-ui/lib/radio-button'
import RaisedButton from 'material-ui/lib/raised-button'
import DeleteIcon from 'material-ui/lib/svg-icons/action/delete'
import colors from 'material-ui/lib/styles/colors'
import AutoComplete from 'material-ui/lib/auto-complete'

import Types from './types'

export default class AnnotateBar extends React.Component {
  render() {
    let open = !!this.props.currentAnnotation
    let title = this.props.currentAnnotation &&
      this.props.currentAnnotation.type === 'new' ?
      "Annotieren" : "Ändern"
    return (
      <LeftNav open={open} openRight={true} width={260}>
        <AppBar title={title} showMenuIconButton={false}/>
        <TypesMenu
            currentAnnotation={this.props.currentAnnotation}
            onType={this.props.onType} onDelete={this.props.onDelete}
            onMetadata={this.props.onMetadata}
            />
      </LeftNav>
    )
  }
}

class TypesMenu extends React.Component {
  render() {
    let annotation = this.props.currentAnnotation

    return (

        {Types.map((category, i) => (
          <List key={i}
              subheader={category.title}
              subheaderStyle={{ lineHeight: '32px' }}
              >
            {category.types.map((type, j) => (
              <ListItem key={j}
                  style={{ backgroundColor: `rgb(${type.rgb})` }}
                  title={type.hint}
                  leftCheckbox={<RadioButton
                      name="type" value={type.id}
                      checked={annotation && annotation.type == type.id}
                      onCheck={ev => this.onCheck(ev)}
                      />}
                    >

{type.title}

                {(type.metadata && annotation && annotation.type == type.id) ?
                  type.metadata.map((keyName, i) =>
                    <TypeMetadata key={i}
                        keyName={keyName} value={annotation && annotation[keyName]}
                        text={annotation && annotation.text}
                        onUpdate={value => this.props.onMetadata(keyName, value)}
                        />
                ) : ""}
              </ListItem>
            ))}
          </List>
        ))}

        {(annotation && annotation.type !== 'new') ?

            <RaisedButton label="Löschen" icon={<DeleteIcon/>}
                backgroundColor={colors.red700} labelColor="white"
                onClick={ev => this.props.onDelete()}
                />

 : ""
        }

    )
  }

  onCheck(ev) {
    let value = ev.target.value
    if (this.props.onType) {
      this.props.onType(value)
    }
  }
}

const METADATA_LABELS = {
  person: "Person",
  organization: "Gremium",
  meeting: "Sitzung",
  paper: "Vorlage",
  file: "Datei",
  location: "Ort"
}

class TypeMetadata extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      byLabel: {},
      labels: [],
      label: ""
    }
  }

  // TODO:
  // * suggest from context (other files in this session, session participants)
  // * suggest from other annotations ("Die Oberbürgermeisterin" maps to the same person)
  _fetchSuggestions(text) {
    // Query with current input or, if empty, annotation text
    let keyName = this.props.keyName
    let typeName = keyName === 'fileref' ? 'file' : keyName
    fetch(`/api/suggest/${typeName}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text: text })
    })
      .then(res => res.json())
      .then(suggestions => {
        let byLabel = {}
        let labels = suggestions.map(suggestion => {
          let s = suggestion.name
          if (suggestion.shortName) s = `${suggestion.shortName}: ${s}`
          if (suggestion.status) s = `${s} (${suggestion.status})`
          byLabel[s] = suggestion.id
          return s
        })
        this.setState({
          byLabel: byLabel,
          labels: labels
        })
        if (!this.state.label && labels[0]) {
          // Nothing yet, input the first suggestion and trigger updateAnnotation
          this.handleUpdateInput(labels[0])
        }
      })
  }

  componentDidMount() {
    if (this.props.value) {
      // Copy metadata value if already existing
      this.setState({
        id: this.props.value.id,
        label: this.props.value.label
      })
    }

    // Initialize suggestions from annotation text
    this._fetchSuggestions(this.props.text)
  }

  componentWillUpdate(nextProps, nextState) {
    if (this.props.value !== nextProps.value || this.props.text !== nextProps.text) {
      // Reset & reinit
      this.setState({
        id: null,
        label: null
      }, () => this.componentDidMount())
    }
  }

  handleUpdateInput(label) {
    let id = this.state.byLabel[label]

    this.setState({ id, label }, () => {
      if (!id) {
        // Update suggestions from text input
        this._fetchSuggestions(label)
      }
      this.props.onUpdate({ id, label })
    })
  }

  render() {
    return (

        <AutoComplete hintText={METADATA_LABELS[this.props.keyName]}
            searchText={this.state.label}
            dataSource={this.state.labels}
            onUpdateInput={label => this.handleUpdateInput(label)}
            onNewRequest={label => this.handleUpdateInput(label)}
            filter={(searchText, key) => true}
            anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
            fullWidth={true}
            />

    )
  }
}
<|endoftext|>


<commit_before>const Keyboard = {
  addListener(eventname, handler) {
    return {
      remove: () => {}
    };
  }
};

module.exports = Keyboard;
<commit_msg>add remaining keyboard methods<commit_after>const Keyboard = {
  addListener(eventname, handler) {
    return {
      remove: () => {}
    };
  },
  removeListener: () => {},
  removeAllListeners: () => {},
  dismiss: () => {}
};

module.exports = Keyboard;
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://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.
const express = require('express');
const im = require('imagemagick');
const Promise = require("bluebird");
const path = require('path');
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const Firestore = require('@google-cloud/firestore');

const app = express();

app.post('/', async (req, res) => {
    try {
        console.log('Collage request');

        const thumbnailFiles = [];
        const pictureStore = new Firestore().collection('pictures');
        const snapshot = await pictureStore.orderBy('created', 'desc').limit(4).get();

        if (snapshot.empty) {
            console.log('Empty collection, no collage to make');
            res.status(204).send("No collage created.");
        } else {
            snapshot.forEach(doc => {
                thumbnailFiles.push(doc.id);
            });
            console.log(`Picture file names: ${JSON.stringify(thumbnailFiles)}`);

            const thumbBucket = storage.bucket('thumbnail-pictures');

            await Promise.all(thumbnailFiles.map(async fileName => {
                const filePath = path.resolve('/tmp', fileName);
                await thumbBucket.file(fileName).download({
                    destination: filePath
                });
                console.log(`Downloaded ${fileName}`);
            }));
            console.log('Downloaded all thumbnails');

            const collagePath = path.resolve('/tmp', 'collage.png');

            const thumbnailPaths = thumbnailFiles.map(f => path.resolve('/tmp', f));
            const convert = Promise.promisify(im.convert);
            await convert([
                '(', ...thumbnailPaths.slice(0, 2), '+append', ')',
                '(', ...thumbnailPaths.slice(2), '+append', ')',
                '-size', '400x400', 'xc:none', '-background', 'none',  '-append',
                collagePath]);
            console.log("Created local collage picture");

            await thumbBucket.upload(collagePath);
            console.log("Uploaded collage to Cloud Storage");

            res.status(204).send("Collage created.");
        }
    } catch (err) {
        console.log(`Error: creating the collage: ${err}`);
        console.error(err);
        res.status(500).send(err);
    }
});

const PORT = process.env.PORT || 8080;

app.listen(PORT, () => {
    console.log(`Started collage service on port ${PORT}`);
});
<commit_msg>move the asynchronous call at the end of the block<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://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.
const express = require('express');
const im = require('imagemagick');
const Promise = require("bluebird");
const path = require('path');
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const Firestore = require('@google-cloud/firestore');

const app = express();

app.post('/', async (req, res) => {
    try {
        console.log('Collage request');

        const thumbnailFiles = [];
        const pictureStore = new Firestore().collection('pictures');
        const snapshot = await pictureStore.orderBy('created', 'desc').limit(4).get();

        if (snapshot.empty) {
            console.log('Empty collection, no collage to make');
            res.status(204).send("No collage created.");
        } else {
            snapshot.forEach(doc => {
                thumbnailFiles.push(doc.id);
            });
            console.log(`Picture file names: ${JSON.stringify(thumbnailFiles)}`);

            const thumbBucket = storage.bucket('thumbnail-pictures');

            await Promise.all(thumbnailFiles.map(async fileName => {
                const filePath = path.resolve('/tmp', fileName);
                console.log(`Downloading ${fileName}...`);
                await thumbBucket.file(fileName).download({
                    destination: filePath
                });
            }));
            console.log('Downloaded all thumbnails');

            const collagePath = path.resolve('/tmp', 'collage.png');

            const thumbnailPaths = thumbnailFiles.map(f => path.resolve('/tmp', f));
            const convert = Promise.promisify(im.convert);
            await convert([
                '(', ...thumbnailPaths.slice(0, 2), '+append', ')',
                '(', ...thumbnailPaths.slice(2), '+append', ')',
                '-size', '400x400', 'xc:none', '-background', 'none',  '-append',
                collagePath]);
            console.log("Created local collage picture");

            await thumbBucket.upload(collagePath);
            console.log("Uploaded collage to Cloud Storage");

            res.status(204).send("Collage created.");
        }
    } catch (err) {
        console.log(`Error: creating the collage: ${err}`);
        console.error(err);
        res.status(500).send(err);
    }
});

const PORT = process.env.PORT || 8080;

app.listen(PORT, () => {
    console.log(`Started collage service on port ${PORT}`);
});
<|endoftext|>


<commit_before><commit_msg>Added stoping condition to vote countdown in controllers/vote-controller<commit_after><|endoftext|>


<commit_before>/**
 * Interpolates a Catmull-Rom Spline through a series of x/y points
 * Converts the CR Spline to Cubic Beziers for use with SVG items
 *
 * If 'alpha' is 0.5 then the 'Centripetal' variant is used
 * If 'alpha' is 1 then the 'Chordal' variant is used
 *
 *
 * @param  {Array} data - Array of points, each point an object literal holding x/y values
 * @return {String} d - SVG string with cubic bezier curves representing the Catmull-Rom Spline
 * source: https://gist.github.com/nicholaswmin/c2661eb11cad5671d816
 */
var catmullRomFitting = function (data,alpha) {

    if (alpha == 0 || alpha === undefined) {
      return false;
    } else {
      var p0, p1, p2, p3, bp1, bp2, d1, d2, d3, A, B, N, M;
      var d3powA, d2powA, d3pow2A, d2pow2A, d1pow2A, d1powA;
      var d = Math.round(data[0].x) + ',' + Math.round(data[0].y) + ' ';
      var length = data.length;
      for (var i = 0; i < length - 1; i++) {

        p0 = i == 0 ? data[0] : data[i - 1];
        p1 = data[i];
        p2 = data[i + 1];
        p3 = i + 2 < length ? data[i + 2] : p2;

        d1 = Math.sqrt(Math.pow(p0.x - p1.x, 2) + Math.pow(p0.y - p1.y, 2));
        d2 = Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
        d3 = Math.sqrt(Math.pow(p2.x - p3.x, 2) + Math.pow(p2.y - p3.y, 2));

        // Catmull-Rom to Cubic Bezier conversion matrix

        // A = 2d1^2a + 3d1^a * d2^a + d3^2a
        // B = 2d3^2a + 3d3^a * d2^a + d2^2a

        // [   0             1            0          0          ]
        // [   -d2^2a /N     A/N          d1^2a /N   0          ]
        // [   0             d3^2a /M     B/M        -d2^2a /M  ]
        // [   0             0            1          0          ]

        d3powA = Math.pow(d3, alpha);
        d3pow2A = Math.pow(d3, 2 * alpha);
        d2powA = Math.pow(d2, alpha);
        d2pow2A = Math.pow(d2, 2 * alpha);
        d1powA = Math.pow(d1, alpha);
        d1pow2A = Math.pow(d1, 2 * alpha);

        A = 2 * d1pow2A + 3 * d1powA * d2powA + d2pow2A;
        B = 2 * d3pow2A + 3 * d3powA * d2powA + d2pow2A;
        N = 3 * d1powA * (d1powA + d2powA);
        if (N > 0) {
          N = 1 / N;
        }
        M = 3 * d3powA * (d3powA + d2powA);
        if (M > 0) {
          M = 1 / M;
        }

        bp1 = { x: (-d2pow2A * p0.x + A * p1.x + d1pow2A * p2.x) * N,
          y: (-d2pow2A * p0.y + A * p1.y + d1pow2A * p2.y) * N };

        bp2 = { x: (d3pow2A * p1.x + B * p2.x - d2pow2A * p3.x) * M,
          y: (d3pow2A * p1.y + B * p2.y - d2pow2A * p3.y) * M };

        if (bp1.x == 0 && bp1.y == 0) {
          bp1 = p1;
        }
        if (bp2.x == 0 && bp2.y == 0) {
          bp2 = p2;
        }

        d += 'C' + bp1.x + ',' + bp1.y + ' ' + bp2.x + ',' + bp2.y + ' ' + p2.x + ',' + p2.y + ' ';
      }

      return d;
    }
};

module.exports = catmullRomFitting;<commit_msg>fix SVG string builder by prepending moveTo command, M<commit_after>/**
 * Interpolates a Catmull-Rom Spline through a series of x/y points
 * Converts the CR Spline to Cubic Beziers for use with SVG items
 *
 * If 'alpha' is 0.5 then the 'Centripetal' variant is used
 * If 'alpha' is 1 then the 'Chordal' variant is used
 *
 *
 * @param  {Array} data - Array of points, each point an object literal holding x/y values
 * @return {String} d - SVG string with cubic bezier curves representing the Catmull-Rom Spline
 * source: https://gist.github.com/nicholaswmin/c2661eb11cad5671d816
 */
var catmullRomFitting = function (data,alpha) {

    if (alpha == 0 || alpha === undefined) {
      return false;
    } else {
      var p0, p1, p2, p3, bp1, bp2, d1, d2, d3, A, B, N, M;
      var d3powA, d2powA, d3pow2A, d2pow2A, d1pow2A, d1powA;
      var d = 'M' + Math.round(data[0].x) + ',' + Math.round(data[0].y) + ' ';
      var length = data.length;
      for (var i = 0; i < length - 1; i++) {

        p0 = i == 0 ? data[0] : data[i - 1];
        p1 = data[i];
        p2 = data[i + 1];
        p3 = i + 2 < length ? data[i + 2] : p2;

        d1 = Math.sqrt(Math.pow(p0.x - p1.x, 2) + Math.pow(p0.y - p1.y, 2));
        d2 = Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
        d3 = Math.sqrt(Math.pow(p2.x - p3.x, 2) + Math.pow(p2.y - p3.y, 2));

        // Catmull-Rom to Cubic Bezier conversion matrix

        // A = 2d1^2a + 3d1^a * d2^a + d3^2a
        // B = 2d3^2a + 3d3^a * d2^a + d2^2a

        // [   0             1            0          0          ]
        // [   -d2^2a /N     A/N          d1^2a /N   0          ]
        // [   0             d3^2a /M     B/M        -d2^2a /M  ]
        // [   0             0            1          0          ]

        d3powA = Math.pow(d3, alpha);
        d3pow2A = Math.pow(d3, 2 * alpha);
        d2powA = Math.pow(d2, alpha);
        d2pow2A = Math.pow(d2, 2 * alpha);
        d1powA = Math.pow(d1, alpha);
        d1pow2A = Math.pow(d1, 2 * alpha);

        A = 2 * d1pow2A + 3 * d1powA * d2powA + d2pow2A;
        B = 2 * d3pow2A + 3 * d3powA * d2powA + d2pow2A;
        N = 3 * d1powA * (d1powA + d2powA);
        if (N > 0) {
          N = 1 / N;
        }
        M = 3 * d3powA * (d3powA + d2powA);
        if (M > 0) {
          M = 1 / M;
        }

        bp1 = { x: (-d2pow2A * p0.x + A * p1.x + d1pow2A * p2.x) * N,
          y: (-d2pow2A * p0.y + A * p1.y + d1pow2A * p2.y) * N };

        bp2 = { x: (d3pow2A * p1.x + B * p2.x - d2pow2A * p3.x) * M,
          y: (d3pow2A * p1.y + B * p2.y - d2pow2A * p3.y) * M };

        if (bp1.x == 0 && bp1.y == 0) {
          bp1 = p1;
        }
        if (bp2.x == 0 && bp2.y == 0) {
          bp2 = p2;
        }

        // ///// SVG syntax notes for cubic Bezier curves /////////
        // prefix: C = "curveto"
        // parameters: (x1 y1 x2 y2 x y)+
        // Draws a cubic Bézier curve from the current point to (x,y) using (x1,y1)
        // as the control point at the beginning of the curve and (x2,y2) as the
        // control point at the end of the curve. C (uppercase) indicates that
        // absolute coordinates will follow; c (lowercase) indicates that
        // relative coordinates will follow. Multiple sets of coordinates may be
        // specified to draw a polybézier. At the end of the command, the new
        // current point becomes the final (x,y) coordinate pair used in the polybézier.
        // source: https://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands

        d += 'C' + bp1.x + ',' + bp1.y + ' ' + bp2.x + ',' + bp2.y + ' ' + p2.x + ',' + p2.y + ' ';
      }

      return d;
    }
};

module.exports = catmullRomFitting;<|endoftext|>


<commit_before>var util = require('util');

exports.init = function (y, config, messages, cron, logger) {
	messages.add('spaghetti_opening', "Spaghetti for lunch? Superzise? Like this message if you'd like to join.");
	messages.add('spaghetti_opening', "Spaghetti for lunch? Like this message if you'd like to join.");

	messages.add('spaghetti_closing', "Mamma mia ramba zamba! [count] hungry monkeys?? \nThe following are registered for lunch: [joiners]");
	messages.add('spaghetti_closing', "Ooooooohh! [count] hungry monkeys?? \nThe following are registered for lunch: [joiners]");

	messages.add('spaghetti_notenough', "A minimum of 5 joiners is required to justify the effort of making spaghetti. There will be no spaghetti today. Sorry");
	messages.add('spaghetti_noone', "Noone?? Alright then... ;(");

	messages.add('spaghetti_chef', "[chef_name], [count] mouths to feed! Hurry!!");

	messages.add('spaghetti_threadclosed', "Sorry, you're to late.");

	var yammer_account = config.yammer[config.yammer_account];

	new cron.CronJob(config.spaghetti.cron_open, function () {
		var openingMessage = messages.get('spaghetti_opening');

		y.sendMessage(function (error, msg) {
			logger.info('spaghetti opening message OK: ' + msg.id());
			var thread = y.thread(msg.threadId());
			thread.setProperty('type', 'spaghetti');
			thread.setProperty('status', 'open');
			thread.setProperty('joiners', []);
			y.persistThread(thread);
		}, openingMessage);
	});

	new cron.CronJob(config.spaghetti.cron_close, function () {
		for (var threadId in y.threads()) {
			(function (thId) {
				var th = y.thread(thId);

				if (th.property('status') == 'open' && th.property('type') == 'spaghetti') {
					th.setProperty('status', 'closed');
					y.persistThread(th);

					y.updateThreadMessages(th, function (th) {
						var message = y.message(th.messageId());
						var joinersCount = message.likes();
						var joinerNames = message.likers();
						var joiners = [];
						var joinerIds = [];
						var joinersList = '';

						for (var i = 0; i < joinerNames.length; i++) {
							joiners.push(y.userByName(joinerNames[i]));
						}

						for (var i in joiners) {
							var user = joiners[i];
							joinerIds.push(user.id());

							if (i > 0) {
								joinersList += ', ';
							}

							joinersList += user.username();
						}

						if (joinerIds.length == 0) {
							var nooneMessage = messages.get('spaghetti_noone');
							y.sendMessage(function (error, message) {
								logger.info('spaghetti noone message OK: ' + message.id());

								th.setProperty('joiners', joinerIds);
								th.setProperty('status', 'closed');
								th.setProperty('charged', true);
								y.persistThread(th);
							}, nooneMessage, { 'reply_to' : th.messageId() });

						} else if (joinerIds.length < 5) {
							var notenoughMessage = messages.get('spaghetti_notenough');
							y.sendMessage(function (error, message) {
								logger.info('spaghetti notenough message OK: ' + message.id());

								th.setProperty('joiners', joinerIds);
								th.setProperty('status', 'closed');
								th.setProperty('charged', true);
								y.persistThread(th);
							}, notenoughMessage, { 'reply_to' : th.messageId() });

						} else {

							var closingMessage = messages.get('spaghetti_closing', {
								'count' : joiners.length,
								'joiners' : joinersList
							});

							y.sendMessage(function (error, message) {
								logger.info('spaghetti closing message OK: ' + message.id());

								th.setProperty('joiners', joinerIds);
								th.setProperty('status', 'closed');
								y.persistThread(th);
							}, closingMessage, { 'reply_to' : th.messageId() });

						}

					});
				}

			})(threadId);
		}
	});
};
<commit_msg>Messages<commit_after>var util = require('util');

exports.init = function (y, config, messages, cron, logger) {
	messages.add('spaghetti_opening', "Spaghetti for lunch? Superzise? Like this message if you'd like to join.");
	messages.add('spaghetti_opening', "Spaghetti for lunch? Like this message if you'd like to join.");

	messages.add('spaghetti_closing', "Mamma mia ramba zamba! [count] hungry monkeys?? \nThe following are registered for lunch: [joiners]");
	messages.add('spaghetti_closing', "Ooooooohh! [count] hungry monkeys?? \nThe following are registered for lunch: [joiners]");

	messages.add('spaghetti_notenough', "Ooh, [count] is not enough. A minimum of 5 joiners is required to justify the effort of making spaghetti. There will be no spaghetti today. Sorry");
	messages.add('spaghetti_noone', "Noone?? Alright then... ;(");

	messages.add('spaghetti_chef', "[chef_name], [count] mouths to feed! Hurry!!");

	messages.add('spaghetti_threadclosed', "Sorry, you're to late.");

	var yammer_account = config.yammer[config.yammer_account];

	new cron.CronJob(config.spaghetti.cron_open, function () {
		var openingMessage = messages.get('spaghetti_opening');

		y.sendMessage(function (error, msg) {
			logger.info('spaghetti opening message OK: ' + msg.id());
			var thread = y.thread(msg.threadId());
			thread.setProperty('type', 'spaghetti');
			thread.setProperty('status', 'open');
			thread.setProperty('joiners', []);
			y.persistThread(thread);
		}, openingMessage);
	});

	new cron.CronJob(config.spaghetti.cron_close, function () {
		for (var threadId in y.threads()) {
			(function (thId) {
				var th = y.thread(thId);

				if (th.property('status') == 'open' && th.property('type') == 'spaghetti') {
					th.setProperty('status', 'closed');
					y.persistThread(th);

					y.updateThreadMessages(th, function (th) {
						var message = y.message(th.messageId());
						var joinersCount = message.likes();
						var joinerNames = message.likers();
						var joiners = [];
						var joinerIds = [];
						var joinersList = '';

						for (var i = 0; i < joinerNames.length; i++) {
							joiners.push(y.userByName(joinerNames[i]));
						}

						for (var i in joiners) {
							var user = joiners[i];
							joinerIds.push(user.id());

							if (i > 0) {
								joinersList += ', ';
							}

							joinersList += user.username();
						}

						if (joinerIds.length == 0) {
							var nooneMessage = messages.get('spaghetti_noone');
							y.sendMessage(function (error, message) {
								logger.info('spaghetti noone message OK: ' + message.id());

								th.setProperty('joiners', joinerIds);
								th.setProperty('status', 'closed');
								th.setProperty('charged', true);
								y.persistThread(th);
							}, nooneMessage, { 'reply_to' : th.messageId() });

						} else if (joinerIds.length < 5) {
							var notenoughMessage = messages.get('spaghetti_notenough', {
								'count' : joiners.length
							});
							y.sendMessage(function (error, message) {
								logger.info('spaghetti notenough message OK: ' + message.id());

								th.setProperty('joiners', joinerIds);
								th.setProperty('status', 'closed');
								th.setProperty('charged', true);
								y.persistThread(th);
							}, notenoughMessage, { 'reply_to' : th.messageId() });

						} else {

							var closingMessage = messages.get('spaghetti_closing', {
								'count' : joiners.length,
								'joiners' : joinersList
							});

							y.sendMessage(function (error, message) {
								logger.info('spaghetti closing message OK: ' + message.id());

								th.setProperty('joiners', joinerIds);
								th.setProperty('status', 'closed');
								y.persistThread(th);
							}, closingMessage, { 'reply_to' : th.messageId() });

						}

					});
				}

			})(threadId);
		}
	});
};
<|endoftext|>


<commit_before>function hijackConnection(original, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(args.length) {
      var callback = args[args.length - 1];
      if(typeof callback === 'function') {
        var ownerInfo = {
          type: type,
          name: args[0],
          args: args.slice(1, args.length - 1)
        };
        args[args.length - 1] = zone.bind(callback, false, ownerInfo, pickAllArgs);
      }
    }
    return original.apply(this, args);
  }
}

function hijackSubscribe(originalFunction, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(args.length) {
      var callback = args[args.length - 1];
      if(typeof callback === 'function') {
        var ownerInfo = {
          type: type,
          name: args[0],
          args: args.slice(1, args.length - 1)
        };
        args[args.length - 1] = zone.bind(callback, false, ownerInfo, pickAllArgs);
      } else if(callback) {
        ['onReady', 'onError'].forEach(function (funName) {
          var ownerInfo = {
            type: type,
            name: args[0],
            args: args.slice(1, args.length - 1),
            callbackType: funName
          };
          if(typeof callback[funName] === "function") {
            callback[funName] = zone.bind(callback[funName], false, ownerInfo, pickAllArgs);
          }
        })
      }
    }
    return originalFunction.apply(this, args);
  }
}

function hijackCursor(Cursor) {

  hijackFunction('observe', [
    'added', 'addedAt', 'changed', 'changedAt',
    'removed', 'removedAt', 'movedTo'
  ]);

  hijackFunction('observeChanges', [
    'added', 'addedBefore', 'changed',
    'removed', 'movedBefore'
  ]);

  function hijackFunction(type, callbacks) {
    var original = Cursor[type];
    Cursor[type] = function (options) {
      var self = this;
      if(options) {
        callbacks.forEach(function (funName) {
          var ownerInfo = {
            type: 'MongoCursor.' + type,
            callbackType: funName,
            collection: self.collection.name
          };

          if(typeof options[funName] === 'function') {
            options[funName] = zone.bind(options[funName], false, ownerInfo, pickAllArgs);
          }
        });
      }
      return original.call(this, options);
    };
  }
}

function hijackComponentEvents(original) {
  return function (dict) {
    var self = this;
    var name = this.kind.split('_')[1];
    _.each(dict, function(handler, target) {
      dict[target] = function () {
        var args = Array.prototype.slice.call(arguments);
        zone.owner = {
          type: 'Template.event',
          event: target,
          template: name
        };
        handler.apply(self, args);
      }
    });
    return original.call(this, dict);
  }
}

function hijackTemplateRendered(original, name) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    zone.owner = {type: 'Template.rendered', template: name};
    return original.apply(this, args);
  }
}

var originalFunctions = [];
function backupOriginals(obj, methodNames) {
  if(obj && Array.isArray(methodNames)) {
    var backup = {obj: obj};
    backup.methods = {};
    methodNames.forEach(function (name) {
      backup.methods[name] = obj[name];
    });
    originalFunctions.push(backup);
  };
}

function restoreOriginals() {
  originalFunctions.forEach(function (backup) {
    for(var name in backup.methods) {
      backup.obj[name] = backup.methods[name];
    };
  });
}

function pickAllArgs(context, args) {
  return args;
}
<commit_msg>Use js methods instead of underscore<commit_after>function hijackConnection(original, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(args.length) {
      var callback = args[args.length - 1];
      if(typeof callback === 'function') {
        var ownerInfo = {
          type: type,
          name: args[0],
          args: args.slice(1, args.length - 1)
        };
        args[args.length - 1] = zone.bind(callback, false, ownerInfo, pickAllArgs);
      }
    }
    return original.apply(this, args);
  }
}

function hijackSubscribe(originalFunction, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(args.length) {
      var callback = args[args.length - 1];
      if(typeof callback === 'function') {
        var ownerInfo = {
          type: type,
          name: args[0],
          args: args.slice(1, args.length - 1)
        };
        args[args.length - 1] = zone.bind(callback, false, ownerInfo, pickAllArgs);
      } else if(callback) {
        ['onReady', 'onError'].forEach(function (funName) {
          var ownerInfo = {
            type: type,
            name: args[0],
            args: args.slice(1, args.length - 1),
            callbackType: funName
          };
          if(typeof callback[funName] === "function") {
            callback[funName] = zone.bind(callback[funName], false, ownerInfo, pickAllArgs);
          }
        })
      }
    }
    return originalFunction.apply(this, args);
  }
}

function hijackCursor(Cursor) {

  hijackFunction('observe', [
    'added', 'addedAt', 'changed', 'changedAt',
    'removed', 'removedAt', 'movedTo'
  ]);

  hijackFunction('observeChanges', [
    'added', 'addedBefore', 'changed',
    'removed', 'movedBefore'
  ]);

  function hijackFunction(type, callbacks) {
    var original = Cursor[type];
    Cursor[type] = function (options) {
      var self = this;
      if(options) {
        callbacks.forEach(function (funName) {
          var ownerInfo = {
            type: 'MongoCursor.' + type,
            callbackType: funName,
            collection: self.collection.name
          };

          if(typeof options[funName] === 'function') {
            options[funName] = zone.bind(options[funName], false, ownerInfo, pickAllArgs);
          }
        });
      }
      return original.call(this, options);
    };
  }
}

function hijackComponentEvents(original) {
  return function (dict) {
    var self = this;
    var name = this.kind.split('_')[1];
    for (var target in dict) {
      dict[target] = prepareHandler(dict[target], target);
    }

    return original.call(this, dict);

    function prepareHandler(handler, target) {
      return function () {
        var args = Array.prototype.slice.call(arguments);
        zone.owner = {
          type: 'Template.event',
          event: target,
          template: name
        };
        handler.apply(self, args);
      };
    }

  }
}

function hijackTemplateRendered(original, name) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    zone.owner = {type: 'Template.rendered', template: name};
    return original.apply(this, args);
  }
}

var originalFunctions = [];
function backupOriginals(obj, methodNames) {
  if(obj && Array.isArray(methodNames)) {
    var backup = {obj: obj};
    backup.methods = {};
    methodNames.forEach(function (name) {
      backup.methods[name] = obj[name];
    });
    originalFunctions.push(backup);
  };
}

function restoreOriginals() {
  originalFunctions.forEach(function (backup) {
    for(var name in backup.methods) {
      backup.obj[name] = backup.methods[name];
    };
  });
}

function pickAllArgs(context, args) {
  return args;
}
<|endoftext|>


<commit_before>module.exports = Register;

function Register(pluginPath) {

    electron = require('electron')
    const app = electron.app

    const isWindows = process.platform === 'win32';

    var ppapiPath = '';
    if (isWindows) {
        if (process.arch = 'x64')
            ppapiPath = __dirname + '\\..\\bin\\x64\\PepperPlugin.dll';
        else
            ppapiPath = __dirname + '\\..\\bin\\Win32\\PepperPlugin.dll';
    }
    if (pluginPath)
        ppapiPath = pluginPath + '\\PepperPlugin.dll';
    //console.log('PPAPI path ' + ppapiPath + ';application/electron-dotnet');
    app.commandLine.appendSwitch('register-pepper-plugins', ppapiPath + ';application/electron-dotnet');

}<commit_msg>Add Mac support to Node module 'electron-dotnet' register<commit_after>module.exports = Register;

function Register(pluginPath) {

    electron = require('electron')
    const app = electron.app

    const isWindows = process.platform === 'win32';
    const isMac = process.platform === 'darwin';

    var ppapiPath = '';
    if (isWindows) {
        if (process.arch = 'x64')
            ppapiPath = __dirname + '\\..\\bin\\x64\\PepperPlugin.dll';
        else
            ppapiPath = __dirname + '\\..\\bin\\Win32\\PepperPlugin.dll';
    }
    if (isMac) {
        if (process.arch = 'x64')
            ppapiPath = __dirname + '\\..\\bin\\mac\\PepperPlugin.dll';
        else
            ppapiPath = __dirname + '\\..\\bin\\mac\\PepperPlugin.dll';
    }
    if (pluginPath)
        ppapiPath = pluginPath + '\\PepperPlugin.dll';
    //console.log('PPAPI path ' + ppapiPath + ';application/electron-dotnet');
    app.commandLine.appendSwitch('register-pepper-plugins', ppapiPath + ';application/electron-dotnet');

}<|endoftext|>


<commit_before>const ROOM_NAME = "Shadow Ban Room";
var room = Rooms.get(toId(ROOM_NAME));
if (!room) {
	Rooms.global.addChatRoom(ROOM_NAME);
	room = Rooms.get(toId(ROOM_NAME));
	room.isPrivate = true;
	room.staffRoom = true;
	if (room.chatRoomData) {
		room.chatRoomData.isPrivate = true;
		room.chatRoomData.staffRoom = true;
		room.addedUsers = room.chatRoomData.addedUsers = {};
		Rooms.global.writeChatRoomData();
	} else {
		room.addedUsers = {};
	}
}
if (Object.size(room.addedUsers) > 0) {
	setImmediate(room.add.bind(room, "||Loaded user list: " + Object.keys(room.addedUsers).sort().join(", ")));
}
exports.room = room;

function getAllAlts(user) {
	var targets = {};
	if (typeof user === 'string') {
		targets[toId(user)] = 1;
	} else {
		user.getAlts().concat(user.name).forEach(function (alt) {
			targets[toId(alt)] = 1;
			Object.keys(Users.get(alt).prevNames).forEach(function (name) {
				targets[toId(name)] = 1;
			});
		});
	}
	return targets;
}

exports.addUser = function (user) {
	var targets = getAllAlts(user);
	for (var u in targets) {
		if (room.addedUsers[u]) {
			delete targets[u];
		} else {
			room.addedUsers[u] = 1;
		}
	}
	Rooms.global.writeChatRoomData();

	targets = Object.keys(targets).sort();
	if (targets.length > 0) {
		room.add("||Added users: " + targets.join(", "));
	}
	return targets;
};

exports.removeUser = function (user) {
	var targets = getAllAlts(user);
	for (var u in targets) {
		if (!room.addedUsers[u]) {
			delete targets[u];
		} else {
			delete room.addedUsers[u];
		}
	}
	Rooms.global.writeChatRoomData();

	targets = Object.keys(targets).sort();
	if (targets.length > 0) {
		room.add("||Removed users: " + targets.join(", "));
	}
	return targets;
};

exports.isShadowBanned = function (user) {
	var targets = getAllAlts(user);
	if (Object.keys(targets).intersect(Object.keys(room.addedUsers)).length === 0) return false;

	var addedUsers = {};
	Array.prototype.exclude.apply(Object.keys(targets), Object.keys(room.addedUsers)).forEach(function (user) {
		if (room.addedUsers[user]) return;
		room.addedUsers[user] = addedUsers[user] = 1;
	});

	if (Object.size(addedUsers) > 0) {
		Rooms.global.writeChatRoomData();
		room.add("||Alts automatically added: " + Object.keys(addedUsers).sort().join(", "));
	}

	return true;
};
<commit_msg>updates to sban<commit_after>const ROOM_NAME = "Shadow Ban Room";
var room = Rooms.get(toId(ROOM_NAME));
if (!room) {
	Rooms.global.addChatRoom(ROOM_NAME);
	room = Rooms.get(toId(ROOM_NAME));
	room.isPrivate = true;
	room.staffRoom = true;
	if (room.chatRoomData) {
		room.chatRoomData.isPrivate = true;
		room.chatRoomData.staffRoom = true;
		room.addedUsers = room.chatRoomData.addedUsers = {};
		Rooms.global.writeChatRoomData();
	} else {
		room.addedUsers = {};
	}
}
if (Object.size(room.addedUsers) > 0) {
	setImmediate(room.add.bind(room, "||Loaded user list: " + Object.keys(room.addedUsers).sort().join(", ")));
}
exports.room = room;

function getAllAlts(user) {
	var targets = {};
	if (typeof user === 'string') {
		targets[toId(user)] = 1;
	} else {
		user.getAlts().concat(user.name).forEach(function (alt) {
			targets[toId(alt)] = 1;
			Object.keys(Users.get(alt).prevNames).forEach(function (name) {
				targets[toId(name)] = 1;
			});
		});
	}
	return targets;
}

exports.addUser = function (user) {
	var targets = getAllAlts(user);
	for (var u in targets) {
		if (room.addedUsers[u]) {
			delete targets[u];
		} else {
			room.addedUsers[u] = 1;
		}
	}
	Rooms.global.writeChatRoomData();

	targets = Object.keys(targets).sort();
	if (targets.length > 0) {
		room.add("||Added users: " + targets.join(", "));
		room.update();
	}
	return targets;
};

exports.removeUser = function (user) {
	var targets = getAllAlts(user);
	for (var u in targets) {
		if (!room.addedUsers[u]) {
			delete targets[u];
		} else {
			delete room.addedUsers[u];
		}
	}
	Rooms.global.writeChatRoomData();

	targets = Object.keys(targets).sort();
	if (targets.length > 0) {
		room.add("||Removed users: " + targets.join(", "));
		room.update();
	}
	return targets;
};

exports.isShadowBanned = function (user) {
	var targets = getAllAlts(user);
	if (Object.keys(targets).intersect(Object.keys(room.addedUsers)).length === 0) return false;

	var addedUsers = {};
	Array.prototype.exclude.apply(Object.keys(targets), Object.keys(room.addedUsers)).forEach(function (user) {
		if (room.addedUsers[user]) return;
		room.addedUsers[user] = addedUsers[user] = 1;
	});

	if (Object.size(addedUsers) > 0) {
		Rooms.global.writeChatRoomData();
		room.add("||Alts automatically added: " + Object.keys(addedUsers).sort().join(", "));
		room.update();
	}

	return true;
};
<|endoftext|>


<commit_before><commit_msg>lint issue<commit_after><|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// NotebookList
//============================================================================

var IPython = (function (IPython) {
    "use strict";

    var utils = IPython.utils;

    var NotebookList = function (selector) {
        this.selector = selector;
        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
        this.notebooks_list = [];
        this.sessions = {};
    };

    NotebookList.prototype.baseProjectUrl = function () {
        return $('body').data('baseProjectUrl');
    };

    NotebookList.prototype.notebookPath = function() {
        return $('body').data('notebookPath');
    };

    NotebookList.prototype.style = function () {
        $('#notebook_toolbar').addClass('list_toolbar');
        $('#drag_info').addClass('toolbar_info');
        $('#notebook_buttons').addClass('toolbar_buttons');
        $('#notebook_list_header').addClass('list_header');
        this.element.addClass("list_container");
    };

    NotebookList.prototype.bind_events = function () {
        var that = this;
        $('#refresh_notebook_list').click(function () {
            that.load_list();
        });
        this.element.bind('dragover', function () {
            return false;
        });
        this.element.bind('drop', function(event){
            that.handelFilesUpload(event,'drop');
            return false;
        });
    };

    NotebookList.prototype.handelFilesUpload =  function(event, dropOrForm) {
        var that = this;
        var files;
        if(dropOrForm =='drop'){
            files = event.originalEvent.dataTransfer.files;
        } else
        {
            files = event.originalEvent.target.files;
        }
        for (var i = 0; i < files.length; i++) {
            var f = files[i];
            var reader = new FileReader();
            reader.readAsText(f);
            var name_and_ext = utils.splitext(f.name);
            var nbname = name_and_ext[0];
            var file_ext = name_and_ext[1];
            if (file_ext === '.ipynb') {
                var item = that.new_notebook_item(0);
                that.add_name_input(nbname, item);
                // Store the notebook item in the reader so we can use it later
                // to know which item it belongs to.
                $(reader).data('item', item);
                reader.onload = function (event) {
                    var nbitem = $(event.target).data('item');
                    that.add_notebook_data(event.target.result, nbitem);
                    that.add_upload_button(nbitem);
                };
            } else {
                var dialog = 'Uploaded notebooks must be .ipynb files';
                IPython.dialog.modal({
                    title : 'Invalid file type',
                    body : dialog,
                    buttons : {'OK' : {'class' : 'btn-primary'}}
                });
            }
        }
        return false;
    };

    NotebookList.prototype.clear_list = function () {
        this.element.children('.list_item').remove();
    };

    NotebookList.prototype.load_sessions = function(){
        var that = this;
        var settings = {
            processData : false,
            cache : false,
            type : "GET",
            dataType : "json",
            success : $.proxy(that.sessions_loaded, this)
        };
        var url = this.baseProjectUrl() + 'api/sessions';
        $.ajax(url,settings);
    };

    NotebookList.prototype.sessions_loaded = function(data){
        this.sessions = {};
        var len = data.length;
        if (len > 0) {
            for (var i=0; i<len; i++) {
                var nb_path;
                if (!data[i].notebook.path) {
                    nb_path = data[i].notebook.name;
                }
                else {
                    nb_path = utils.url_path_join(
                        data[i].notebook.path,
                        data[i].notebook.name
                    );
                }
                this.sessions[nb_path] = data[i].id;
            }
        }
        this.load_list();
    };

    NotebookList.prototype.load_list = function () {
        var that = this;
        var settings = {
            processData : false,
            cache : false,
            type : "GET",
            dataType : "json",
            success : $.proxy(this.list_loaded, this),
            error : $.proxy( function(){
                that.list_loaded([], null, null, {msg:"Error connecting to server."});
                             },this)
        };

        var url = utils.url_join_encode(
                this.baseProjectUrl(),
                'api',
                'notebooks',
                this.notebookPath()
        );
        $.ajax(url, settings);
    };

    NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
        var message = 'Notebook list empty.';
        if (param !== undefined && param.msg) {
            message = param.msg;
        }
        var len = data.length;
        this.clear_list();
        if (len === 0) {
            $(this.new_notebook_item(0))
                .append(
                    $('<div style="margin:auto;text-align:center;color:grey"/>')
                    .text(message)
                );
        }
        for (var i=0; i<len; i++) {
            var name = data[i].name;
            var path = this.notebookPath();
            var nbname = utils.splitext(name)[0];
            var item = this.new_notebook_item(i);
            this.add_link(path, nbname, item);
            name = utils.url_path_join(path, name);
            if(this.sessions[name] === undefined){
                this.add_delete_button(item);
            } else {
                this.add_shutdown_button(item,this.sessions[name]);
            }
        }
    };

    NotebookList.prototype.new_notebook_item = function (index) {
        var item = $('<div/>').addClass("list_item").addClass("row-fluid");
        // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
        // item.css('border-top-style','none');
        item.append($("<div/>").addClass("span12").append(
            $("<a/>").addClass("item_link").append(
                $("<span/>").addClass("item_name")
            )
        ).append(
            $('<div/>').addClass("item_buttons btn-group pull-right")
        ));

        if (index === -1) {
            this.element.append(item);
        } else {
            this.element.children().eq(index).after(item);
        }
        return item;
    };

    NotebookList.prototype.add_link = function (path, nbname, item) {
        item.data('nbname', nbname);
        item.data('path', path);
        item.find(".item_name").text(nbname);
        item.find("a.item_link")
            .attr('href',
                utils.url_join_encode(
                    this.baseProjectUrl(),
                    "notebooks",
                    path,
                    nbname + ".ipynb"
                )
            ).attr('target','_blank');
    };

    NotebookList.prototype.add_name_input = function (nbname, item) {
        item.data('nbname', nbname);
        item.find(".item_name").empty().append(
            $('<input/>')
            .addClass("nbname_input")
            .attr('value', nbname)
            .attr('size', '30')
            .attr('type', 'text')
        );
    };

    NotebookList.prototype.add_notebook_data = function (data, item) {
        item.data('nbdata', data);
    };

    NotebookList.prototype.add_shutdown_button = function (item, session) {
        var that = this;
        var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-mini").
            click(function (e) {
                var settings = {
                    processData : false,
                    cache : false,
                    type : "DELETE",
                    dataType : "json",
                    success : function () {
                        that.load_sessions();
                    }
                };
                var url = utils.url_join_encode(
                    that.baseProjectUrl(),
                    'api/sessions',
                    session
                );
                $.ajax(url, settings);
                return false;
            });
        // var new_buttons = item.find('a'); // shutdown_button;
        item.find(".item_buttons").text("").append(shutdown_button);
    };

    NotebookList.prototype.add_delete_button = function (item) {
        var new_buttons = $('<span/>').addClass("btn-group pull-right");
        var notebooklist = this;
        var delete_button = $("<button/>").text("Delete").addClass("btn btn-mini").
            click(function (e) {
                // $(this) is the button that was clicked.
                var that = $(this);
                // We use the nbname and notebook_id from the parent notebook_item element's
                // data because the outer scopes values change as we iterate through the loop.
                var parent_item = that.parents('div.list_item');
                var nbname = parent_item.data('nbname');
                var message = 'Are you sure you want to permanently delete the notebook: ' + nbname + '?';
                IPython.dialog.modal({
                    title : "Delete notebook",
                    body : message,
                    buttons : {
                        Delete : {
                            class: "btn-danger",
                            click: function() {
                                var settings = {
                                    processData : false,
                                    cache : false,
                                    type : "DELETE",
                                    dataType : "json",
                                    success : function (data, status, xhr) {
                                        parent_item.remove();
                                    }
                                };
                                var url = utils.url_join_encode(
                                    notebooklist.baseProjectUrl(),
                                    'api/notebooks',
                                    notebooklist.notebookPath(),
                                    nbname + '.ipynb'
                                );
                                $.ajax(url, settings);
                            }
                        },
                        Cancel : {}
                    }
                });
                return false;
            });
        item.find(".item_buttons").text("").append(delete_button);
    };

    NotebookList.prototype.add_upload_button = function (item) {
        var that = this;
        var upload_button = $('<button/>').text("Upload")
            .addClass('btn btn-primary btn-mini upload_button')
            .click(function (e) {
                var nbname = item.find('.item_name > input').val();
                var path = that.notebookPath();
                var nbdata = item.data('nbdata');
                var content_type = 'application/json';
                var model = {
                    content : JSON.parse(nbdata),
                };
                var settings = {
                    processData : false,
                    cache : false,
                    type : 'PUT',
                    dataType : 'json',
                    data : JSON.stringify(model),
                    headers : {'Content-Type': content_type},
                    success : function (data, status, xhr) {
                        that.add_link(path, nbname, item);
                        that.add_delete_button(item);
                    },
                    error : function (data, status, xhr) {
                        console.log(data, status);
                    }
                };

                var url = utils.url_join_encode(
                    that.baseProjectUrl(),
                    'api/notebooks',
                    that.notebookPath(),
                    nbname + '.ipynb'
                );
                $.ajax(url, settings);
                return false;
            });
        var cancel_button = $('<button/>').text("Cancel")
            .addClass("btn btn-mini")
            .click(function (e) {
                console.log('cancel click');
                item.remove();
                return false;
            });
        item.find(".item_buttons").empty()
            .append(upload_button)
            .append(cancel_button);
    };

    NotebookList.prototype.new_notebook = function(){
        var path = this.notebookPath();
        var base_project_url = this.baseProjectUrl();
        var settings = {
            processData : false,
            cache : false,
            type : "POST",
            dataType : "json",
            async : false,
            success : function (data, status, xhr) {
                var notebook_name = data.name;
                window.open(
                    utils.url_join_encode(
                        base_project_url,
                        'notebooks',
                        path,
                        notebook_name),
                    '_blank'
                );
            }
        };
        var url = utils.url_join_encode(
            base_project_url,
            'api/notebooks',
            path
        );
        $.ajax(url, settings);
    };

    IPython.NotebookList = NotebookList;

    return IPython;

}(IPython));
<commit_msg>Reset file upload form after an upload.<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// NotebookList
//============================================================================

var IPython = (function (IPython) {
    "use strict";

    var utils = IPython.utils;

    var NotebookList = function (selector) {
        this.selector = selector;
        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
        this.notebooks_list = [];
        this.sessions = {};
    };

    NotebookList.prototype.baseProjectUrl = function () {
        return $('body').data('baseProjectUrl');
    };

    NotebookList.prototype.notebookPath = function() {
        return $('body').data('notebookPath');
    };

    NotebookList.prototype.style = function () {
        $('#notebook_toolbar').addClass('list_toolbar');
        $('#drag_info').addClass('toolbar_info');
        $('#notebook_buttons').addClass('toolbar_buttons');
        $('#notebook_list_header').addClass('list_header');
        this.element.addClass("list_container");
    };

    NotebookList.prototype.bind_events = function () {
        var that = this;
        $('#refresh_notebook_list').click(function () {
            that.load_list();
        });
        this.element.bind('dragover', function () {
            return false;
        });
        this.element.bind('drop', function(event){
            that.handelFilesUpload(event,'drop');
            return false;
        });
    };

    NotebookList.prototype.handelFilesUpload =  function(event, dropOrForm) {
        var that = this;
        var files;
        if(dropOrForm =='drop'){
            files = event.originalEvent.dataTransfer.files;
        } else
        {
            files = event.originalEvent.target.files;
        }
        for (var i = 0; i < files.length; i++) {
            var f = files[i];
            var reader = new FileReader();
            reader.readAsText(f);
            var name_and_ext = utils.splitext(f.name);
            var nbname = name_and_ext[0];
            var file_ext = name_and_ext[1];
            if (file_ext === '.ipynb') {
                var item = that.new_notebook_item(0);
                that.add_name_input(nbname, item);
                // Store the notebook item in the reader so we can use it later
                // to know which item it belongs to.
                $(reader).data('item', item);
                reader.onload = function (event) {
                    var nbitem = $(event.target).data('item');
                    that.add_notebook_data(event.target.result, nbitem);
                    that.add_upload_button(nbitem);
                };
            } else {
                var dialog = 'Uploaded notebooks must be .ipynb files';
                IPython.dialog.modal({
                    title : 'Invalid file type',
                    body : dialog,
                    buttons : {'OK' : {'class' : 'btn-primary'}}
                });
            }
        }
        // Replace the file input form wth a clone of itself. This is required to
        // reset the form. Otherwise, if you upload a file, delete it and try to
        // upload it again, the changed event won't fire.
        var form = $('input.fileinput');
        form.replaceWith(form.clone(true));
        return false;
    };

    NotebookList.prototype.clear_list = function () {
        this.element.children('.list_item').remove();
    };

    NotebookList.prototype.load_sessions = function(){
        var that = this;
        var settings = {
            processData : false,
            cache : false,
            type : "GET",
            dataType : "json",
            success : $.proxy(that.sessions_loaded, this)
        };
        var url = this.baseProjectUrl() + 'api/sessions';
        $.ajax(url,settings);
    };

    NotebookList.prototype.sessions_loaded = function(data){
        this.sessions = {};
        var len = data.length;
        if (len > 0) {
            for (var i=0; i<len; i++) {
                var nb_path;
                if (!data[i].notebook.path) {
                    nb_path = data[i].notebook.name;
                }
                else {
                    nb_path = utils.url_path_join(
                        data[i].notebook.path,
                        data[i].notebook.name
                    );
                }
                this.sessions[nb_path] = data[i].id;
            }
        }
        this.load_list();
    };

    NotebookList.prototype.load_list = function () {
        var that = this;
        var settings = {
            processData : false,
            cache : false,
            type : "GET",
            dataType : "json",
            success : $.proxy(this.list_loaded, this),
            error : $.proxy( function(){
                that.list_loaded([], null, null, {msg:"Error connecting to server."});
                             },this)
        };

        var url = utils.url_join_encode(
                this.baseProjectUrl(),
                'api',
                'notebooks',
                this.notebookPath()
        );
        $.ajax(url, settings);
    };

    NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
        var message = 'Notebook list empty.';
        if (param !== undefined && param.msg) {
            message = param.msg;
        }
        var len = data.length;
        this.clear_list();
        if (len === 0) {
            $(this.new_notebook_item(0))
                .append(
                    $('<div style="margin:auto;text-align:center;color:grey"/>')
                    .text(message)
                );
        }
        for (var i=0; i<len; i++) {
            var name = data[i].name;
            var path = this.notebookPath();
            var nbname = utils.splitext(name)[0];
            var item = this.new_notebook_item(i);
            this.add_link(path, nbname, item);
            name = utils.url_path_join(path, name);
            if(this.sessions[name] === undefined){
                this.add_delete_button(item);
            } else {
                this.add_shutdown_button(item,this.sessions[name]);
            }
        }
    };

    NotebookList.prototype.new_notebook_item = function (index) {
        var item = $('<div/>').addClass("list_item").addClass("row-fluid");
        // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
        // item.css('border-top-style','none');
        item.append($("<div/>").addClass("span12").append(
            $("<a/>").addClass("item_link").append(
                $("<span/>").addClass("item_name")
            )
        ).append(
            $('<div/>').addClass("item_buttons btn-group pull-right")
        ));

        if (index === -1) {
            this.element.append(item);
        } else {
            this.element.children().eq(index).after(item);
        }
        return item;
    };

    NotebookList.prototype.add_link = function (path, nbname, item) {
        item.data('nbname', nbname);
        item.data('path', path);
        item.find(".item_name").text(nbname);
        item.find("a.item_link")
            .attr('href',
                utils.url_join_encode(
                    this.baseProjectUrl(),
                    "notebooks",
                    path,
                    nbname + ".ipynb"
                )
            ).attr('target','_blank');
    };

    NotebookList.prototype.add_name_input = function (nbname, item) {
        item.data('nbname', nbname);
        item.find(".item_name").empty().append(
            $('<input/>')
            .addClass("nbname_input")
            .attr('value', nbname)
            .attr('size', '30')
            .attr('type', 'text')
        );
    };

    NotebookList.prototype.add_notebook_data = function (data, item) {
        item.data('nbdata', data);
    };

    NotebookList.prototype.add_shutdown_button = function (item, session) {
        var that = this;
        var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-mini").
            click(function (e) {
                var settings = {
                    processData : false,
                    cache : false,
                    type : "DELETE",
                    dataType : "json",
                    success : function () {
                        that.load_sessions();
                    }
                };
                var url = utils.url_join_encode(
                    that.baseProjectUrl(),
                    'api/sessions',
                    session
                );
                $.ajax(url, settings);
                return false;
            });
        // var new_buttons = item.find('a'); // shutdown_button;
        item.find(".item_buttons").text("").append(shutdown_button);
    };

    NotebookList.prototype.add_delete_button = function (item) {
        var new_buttons = $('<span/>').addClass("btn-group pull-right");
        var notebooklist = this;
        var delete_button = $("<button/>").text("Delete").addClass("btn btn-mini").
            click(function (e) {
                // $(this) is the button that was clicked.
                var that = $(this);
                // We use the nbname and notebook_id from the parent notebook_item element's
                // data because the outer scopes values change as we iterate through the loop.
                var parent_item = that.parents('div.list_item');
                var nbname = parent_item.data('nbname');
                var message = 'Are you sure you want to permanently delete the notebook: ' + nbname + '?';
                IPython.dialog.modal({
                    title : "Delete notebook",
                    body : message,
                    buttons : {
                        Delete : {
                            class: "btn-danger",
                            click: function() {
                                var settings = {
                                    processData : false,
                                    cache : false,
                                    type : "DELETE",
                                    dataType : "json",
                                    success : function (data, status, xhr) {
                                        parent_item.remove();
                                    }
                                };
                                var url = utils.url_join_encode(
                                    notebooklist.baseProjectUrl(),
                                    'api/notebooks',
                                    notebooklist.notebookPath(),
                                    nbname + '.ipynb'
                                );
                                $.ajax(url, settings);
                            }
                        },
                        Cancel : {}
                    }
                });
                return false;
            });
        item.find(".item_buttons").text("").append(delete_button);
    };

    NotebookList.prototype.add_upload_button = function (item) {
        var that = this;
        var upload_button = $('<button/>').text("Upload")
            .addClass('btn btn-primary btn-mini upload_button')
            .click(function (e) {
                var nbname = item.find('.item_name > input').val();
                var path = that.notebookPath();
                var nbdata = item.data('nbdata');
                var content_type = 'application/json';
                var model = {
                    content : JSON.parse(nbdata),
                };
                var settings = {
                    processData : false,
                    cache : false,
                    type : 'PUT',
                    dataType : 'json',
                    data : JSON.stringify(model),
                    headers : {'Content-Type': content_type},
                    success : function (data, status, xhr) {
                        that.add_link(path, nbname, item);
                        that.add_delete_button(item);
                    },
                    error : function (data, status, xhr) {
                        console.log(data, status);
                    }
                };

                var url = utils.url_join_encode(
                    that.baseProjectUrl(),
                    'api/notebooks',
                    that.notebookPath(),
                    nbname + '.ipynb'
                );
                $.ajax(url, settings);
                return false;
            });
        var cancel_button = $('<button/>').text("Cancel")
            .addClass("btn btn-mini")
            .click(function (e) {
                console.log('cancel click');
                item.remove();
                return false;
            });
        item.find(".item_buttons").empty()
            .append(upload_button)
            .append(cancel_button);
    };

    NotebookList.prototype.new_notebook = function(){
        var path = this.notebookPath();
        var base_project_url = this.baseProjectUrl();
        var settings = {
            processData : false,
            cache : false,
            type : "POST",
            dataType : "json",
            async : false,
            success : function (data, status, xhr) {
                var notebook_name = data.name;
                window.open(
                    utils.url_join_encode(
                        base_project_url,
                        'notebooks',
                        path,
                        notebook_name),
                    '_blank'
                );
            }
        };
        var url = utils.url_join_encode(
            base_project_url,
            'api/notebooks',
            path
        );
        $.ajax(url, settings);
    };

    IPython.NotebookList = NotebookList;

    return IPython;

}(IPython));
<|endoftext|>


<commit_before>var $ = require('jquery');

var UniversalDApp = require('../universal-dapp.js');

var utils = require('./utils');

function Renderer (editor, executionContext, updateFiles, transactionDebugger) {
  var detailsOpen = {};

  function renderError (message, container, noAnnotations) {
    var type = utils.errortype(message);
    var $pre = $('
').text(message);
    var $error = $('

').prepend($pre);
    if (container === undefined) {
      container = $('#output');
    }
    container.append($error);
    var err = message.match(/^([^:]*):([0-9]*):(([0-9]*):)? /);
    if (err) {
      var errFile = err[1];
      var errLine = parseInt(err[2], 10) - 1;
      var errCol = err[4] ? parseInt(err[4], 10) : 0;
      if (!noAnnotations && (errFile === '' || errFile === utils.fileNameFromKey(editor.getCacheFile()))) {
        editor.addAnnotation({
          row: errLine,
          column: errCol,
          text: message,
          type: type
        });
      }
      $error.click(function (ev) {
        if (errFile !== '' && errFile !== utils.fileNameFromKey(editor.getCacheFile()) && editor.hasFile(errFile)) {
          // Switch to file
          editor.setCacheFile(utils.fileKey(errFile));
          updateFiles();
        // @TODO could show some error icon in files with errors
        }
        editor.handleErrorClick(errLine, errCol);
      });
      $error.find('.close').click(function (ev) {
        ev.preventDefault();
        $error.remove();
        return false;
      });
    }
  }
  this.error = renderError;

  var combined = function (contractName, jsonInterface, bytecode) {
    return JSON.stringify([{ name: contractName, interface: jsonInterface, bytecode: bytecode }]);
  };

  function renderContracts (data, source) {
    var udappContracts = [];
    for (var contractName in data.contracts) {
      var contract = data.contracts[contractName];
      udappContracts.push({
        name: contractName,
        interface: contract['interface'],
        bytecode: contract.bytecode
      });
    }

    var dapp = new UniversalDApp(udappContracts, {
      mode: executionContext.isVM() ? 'vm' : 'web3',
      web3: executionContext.web3(),
      removable: false,
      getAddress: function () { return $('#txorigin').val(); },
      getValue: function () {
        var comp = $('#value').val().split(' ');
        return executionContext.web3().toWei(comp[0], comp.slice(1).join(' '));
      },
      getGasLimit: function () { return $('#gasLimit').val(); },
      removable_instances: true,
      renderOutputModifier: function (contractName, $contractOutput) {
        var contract = data.contracts[contractName];
        if (contract.bytecode) {
          $contractOutput.append(textRow('Bytecode', contract.bytecode));
        }
        $contractOutput.append(textRow('Interface', contract['interface']));
        if (contract.bytecode) {
          $contractOutput.append(textRow('Web3 deploy', gethDeploy(contractName.toLowerCase(), contract['interface'], contract.bytecode), 'deploy'));
          $contractOutput.append(textRow('uDApp', combined(contractName, contract['interface'], contract.bytecode), 'deploy'));
        }
        return $contractOutput.append(getDetails(contract, source, contractName));
      }
    }, transactionDebugger);

    var $contractOutput = dapp.render();

    var $txOrigin = $('#txorigin');

    function renderAccounts (err, accounts) {
      if (err) {
        renderError(err.message);
      }
      if (accounts && accounts[0]) {
        $txOrigin.empty();
        for (var a in accounts) { $txOrigin.append($('<option />').val(accounts[a]).text(accounts[a])); }
        $txOrigin.val(accounts[0]);
      } else {
        $txOrigin.val('unknown');
      }
    }

    dapp.getAccounts(renderAccounts);

    $contractOutput.find('.title').click(function (ev) { $(this).closest('.contract').toggleClass('hide'); });
    $('#output').append($contractOutput);
    $('.col2 input,textarea').click(function () { this.select(); });
  }
  this.contracts = renderContracts;

  var tableRowItems = function (first, second, cls) {
    return $('
')
      .addClass(cls)
      .append($('
').append(first))
      .append($('
').append(second));
  };
  var tableRow = function (description, data) {
    return tableRowItems(
      $('').text(description),
      $('<input readonly="readonly"/>').val(data));
  };
  var textRow = function (description, data, cls) {
    return tableRowItems(
      $('').text(description),
      $('<textarea readonly="readonly" class="gethDeployText"/>').val(data),
      cls);
  };

  var getDetails = function (contract, source, contractName) {
    var button = $('<button>Toggle Details</button>');
    var details = $('
')
      .append(tableRow('Solidity Interface', contract.solidity_interface));
    if (contract.opcodes !== '') {
      details.append(tableRow('Opcodes', contract.opcodes));
    }
    var funHashes = '';
    for (var fun in contract.functionHashes) {
      funHashes += contract.functionHashes[fun] + ' ' + fun + '\n';
    }
    details.append($('Functions'));
    details.append($('
').text(funHashes));
    var gasEstimates = formatGasEstimates(contract.gasEstimates);
    if (gasEstimates) {
      details.append($('Gas Estimates'));
      details.append($('
').text(gasEstimates));
    }
    if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0) {
      details.append(tableRow('Runtime Bytecode', contract.runtimeBytecode));
    }
    if (contract.assembly !== null) {
      details.append($('Assembly'));
      var assembly = $('
').text(formatAssemblyText(contract.assembly, '', source));
      details.append(assembly);
    }
    button.click(function () { detailsOpen[contractName] = !detailsOpen[contractName]; details.toggle(); });
    if (detailsOpen[contractName]) {
      details.show();
    }
    return $('
').append(button).append(details);
  };

  var formatGasEstimates = function (data) {
    // FIXME: the whole gasEstimates object should be nil instead
    if (data.creation === undefined && data.external === undefined && data.internal === undefined) {
      return;
    }
    var gasToText = function (g) { return g === null ? 'unknown' : g; };
    var text = '';
    var fun;
    if ('creation' in data) {
      text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n';
    }

    if ('external' in data) {
      text += 'External:\n';
      for (fun in data.external) {
        text += '  ' + fun + ': ' + gasToText(data.external[fun]) + '\n';
      }
    }

    if ('internal' in data) {
      text += 'Internal:\n';
      for (fun in data.internal) {
        text += '  ' + fun + ': ' + gasToText(data.internal[fun]) + '\n';
      }
    }

    return text;
  };

  var formatAssemblyText = function (asm, prefix, source) {
    if (typeof asm === typeof '' || asm === null || asm === undefined) {
      return prefix + asm + '\n';
    }
    var text = prefix + '.code\n';
    $.each(asm['.code'], function (i, item) {
      var v = item.value === undefined ? '' : item.value;
      var src = '';
      if (item.begin !== undefined && item.end !== undefined) {
        src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g');
      }
      if (src.length > 30) {
        src = src.slice(0, 30) + '...';
      }
      if (item.name !== 'tag') {
        text += '  ';
      }
      text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
    });
    text += prefix + '.data\n';
    if (asm['.data']) {
      $.each(asm['.data'], function (i, item) {
        text += '  ' + prefix + '' + i + ':\n';
        text += formatAssemblyText(item, prefix + '    ', source);
      });
    }

    return text;
  };

  function gethDeploy (contractName, jsonInterface, bytecode) {
    var code = '';
    var funABI = getConstructorInterface(JSON.parse(jsonInterface));

    funABI.inputs.forEach(function (inp) {
      code += 'var ' + inp.name + ' = /* var of type ' + inp.type + ' here */ ;\n';
    });

    code += 'var ' + contractName + 'Contract = web3.eth.contract(' + jsonInterface.replace('\n', '') + ');' +
      '\nvar ' + contractName + ' = ' + contractName + 'Contract.new(';

    funABI.inputs.forEach(function (inp) {
      code += '\n   ' + inp.name + ',';
    });

    code += '\n   {' +
      '\n     from: web3.eth.accounts[0], ' +
      '\n     data: \'' + bytecode + '\', ' +
      '\n     gas: 4700000' +
      '\n   }, function (e, contract){' +
      '\n    console.log(e, contract);' +
      '\n    if (typeof contract.address !== \'undefined\') {' +
      '\n         console.log(\'Contract mined! address: \' + contract.address + \' transactionHash: \' + contract.transactionHash);' +
      '\n    }' +
      '\n })';

    return code;
  }

  function getConstructorInterface (abi) {
    var funABI = { 'name': '', 'inputs': [], 'type': 'constructor', 'outputs': [] };
    for (var i = 0; i < abi.length; i++) {
      if (abi[i].type === 'constructor') {
        funABI.inputs = abi[i].inputs || [];
        break;
      }
    }
    return funABI;
  }
}

module.exports = Renderer;
<commit_msg>Space the rendering source code for readability<commit_after>var $ = require('jquery');

var UniversalDApp = require('../universal-dapp.js');

var utils = require('./utils');

function Renderer (editor, executionContext, updateFiles, transactionDebugger) {
  var detailsOpen = {};

  function renderError (message, container, noAnnotations) {
    var type = utils.errortype(message);
    var $pre = $('
').text(message);
    var $error = $('

').prepend($pre);
    if (container === undefined) {
      container = $('#output');
    }
    container.append($error);
    var err = message.match(/^([^:]*):([0-9]*):(([0-9]*):)? /);
    if (err) {
      var errFile = err[1];
      var errLine = parseInt(err[2], 10) - 1;
      var errCol = err[4] ? parseInt(err[4], 10) : 0;
      if (!noAnnotations && (errFile === '' || errFile === utils.fileNameFromKey(editor.getCacheFile()))) {
        editor.addAnnotation({
          row: errLine,
          column: errCol,
          text: message,
          type: type
        });
      }
      $error.click(function (ev) {
        if (errFile !== '' && errFile !== utils.fileNameFromKey(editor.getCacheFile()) && editor.hasFile(errFile)) {
          // Switch to file
          editor.setCacheFile(utils.fileKey(errFile));
          updateFiles();
        // @TODO could show some error icon in files with errors
        }
        editor.handleErrorClick(errLine, errCol);
      });
      $error.find('.close').click(function (ev) {
        ev.preventDefault();
        $error.remove();
        return false;
      });
    }
  }
  this.error = renderError;

  var combined = function (contractName, jsonInterface, bytecode) {
    return JSON.stringify([{ name: contractName, interface: jsonInterface, bytecode: bytecode }]);
  };

  function renderContracts (data, source) {
    var udappContracts = [];
    for (var contractName in data.contracts) {
      var contract = data.contracts[contractName];
      udappContracts.push({
        name: contractName,
        interface: contract['interface'],
        bytecode: contract.bytecode
      });
    }

    var dapp = new UniversalDApp(udappContracts, {
      mode: executionContext.isVM() ? 'vm' : 'web3',
      web3: executionContext.web3(),
      removable: false,
      getAddress: function () { return $('#txorigin').val(); },
      getValue: function () {
        var comp = $('#value').val().split(' ');
        return executionContext.web3().toWei(comp[0], comp.slice(1).join(' '));
      },
      getGasLimit: function () { return $('#gasLimit').val(); },
      removable_instances: true,
      renderOutputModifier: function (contractName, $contractOutput) {
        var contract = data.contracts[contractName];
        if (contract.bytecode) {
          $contractOutput.append(textRow('Bytecode', contract.bytecode));
        }

        $contractOutput.append(textRow('Interface', contract['interface']));

        if (contract.bytecode) {
          $contractOutput.append(textRow('Web3 deploy', gethDeploy(contractName.toLowerCase(), contract['interface'], contract.bytecode), 'deploy'));
          $contractOutput.append(textRow('uDApp', combined(contractName, contract['interface'], contract.bytecode), 'deploy'));
        }
        return $contractOutput.append(getDetails(contract, source, contractName));
      }
    }, transactionDebugger);

    var $contractOutput = dapp.render();

    var $txOrigin = $('#txorigin');

    function renderAccounts (err, accounts) {
      if (err) {
        renderError(err.message);
      }
      if (accounts && accounts[0]) {
        $txOrigin.empty();
        for (var a in accounts) { $txOrigin.append($('<option />').val(accounts[a]).text(accounts[a])); }
        $txOrigin.val(accounts[0]);
      } else {
        $txOrigin.val('unknown');
      }
    }

    dapp.getAccounts(renderAccounts);

    $contractOutput.find('.title').click(function (ev) { $(this).closest('.contract').toggleClass('hide'); });
    $('#output').append($contractOutput);
    $('.col2 input,textarea').click(function () { this.select(); });
  }
  this.contracts = renderContracts;

  var tableRowItems = function (first, second, cls) {
    return $('
')
      .addClass(cls)
      .append($('
').append(first))
      .append($('
').append(second));
  };
  var tableRow = function (description, data) {
    return tableRowItems(
      $('').text(description),
      $('<input readonly="readonly"/>').val(data));
  };
  var textRow = function (description, data, cls) {
    return tableRowItems(
      $('').text(description),
      $('<textarea readonly="readonly" class="gethDeployText"/>').val(data),
      cls);
  };

  var getDetails = function (contract, source, contractName) {
    var button = $('<button>Toggle Details</button>');
    var details = $('
')
      .append(tableRow('Solidity Interface', contract.solidity_interface));

    if (contract.opcodes !== '') {
      details.append(tableRow('Opcodes', contract.opcodes));
    }

    var funHashes = '';
    for (var fun in contract.functionHashes) {
      funHashes += contract.functionHashes[fun] + ' ' + fun + '\n';
    }
    details.append($('Functions'));
    details.append($('
').text(funHashes));

    var gasEstimates = formatGasEstimates(contract.gasEstimates);
    if (gasEstimates) {
      details.append($('Gas Estimates'));
      details.append($('
').text(gasEstimates));
    }

    if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0) {
      details.append(tableRow('Runtime Bytecode', contract.runtimeBytecode));
    }

    if (contract.assembly !== null) {
      details.append($('Assembly'));
      var assembly = $('
').text(formatAssemblyText(contract.assembly, '', source));
      details.append(assembly);
    }

    button.click(function () { detailsOpen[contractName] = !detailsOpen[contractName]; details.toggle(); });
    if (detailsOpen[contractName]) {
      details.show();
    }
    return $('
').append(button).append(details);
  };

  var formatGasEstimates = function (data) {
    // FIXME: the whole gasEstimates object should be nil instead
    if (data.creation === undefined && data.external === undefined && data.internal === undefined) {
      return;
    }
    var gasToText = function (g) { return g === null ? 'unknown' : g; };
    var text = '';
    var fun;
    if ('creation' in data) {
      text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n';
    }

    if ('external' in data) {
      text += 'External:\n';
      for (fun in data.external) {
        text += '  ' + fun + ': ' + gasToText(data.external[fun]) + '\n';
      }
    }

    if ('internal' in data) {
      text += 'Internal:\n';
      for (fun in data.internal) {
        text += '  ' + fun + ': ' + gasToText(data.internal[fun]) + '\n';
      }
    }

    return text;
  };

  var formatAssemblyText = function (asm, prefix, source) {
    if (typeof asm === typeof '' || asm === null || asm === undefined) {
      return prefix + asm + '\n';
    }
    var text = prefix + '.code\n';
    $.each(asm['.code'], function (i, item) {
      var v = item.value === undefined ? '' : item.value;
      var src = '';
      if (item.begin !== undefined && item.end !== undefined) {
        src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g');
      }
      if (src.length > 30) {
        src = src.slice(0, 30) + '...';
      }
      if (item.name !== 'tag') {
        text += '  ';
      }
      text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
    });
    text += prefix + '.data\n';
    if (asm['.data']) {
      $.each(asm['.data'], function (i, item) {
        text += '  ' + prefix + '' + i + ':\n';
        text += formatAssemblyText(item, prefix + '    ', source);
      });
    }

    return text;
  };

  function gethDeploy (contractName, jsonInterface, bytecode) {
    var code = '';
    var funABI = getConstructorInterface(JSON.parse(jsonInterface));

    funABI.inputs.forEach(function (inp) {
      code += 'var ' + inp.name + ' = /* var of type ' + inp.type + ' here */ ;\n';
    });

    code += 'var ' + contractName + 'Contract = web3.eth.contract(' + jsonInterface.replace('\n', '') + ');' +
      '\nvar ' + contractName + ' = ' + contractName + 'Contract.new(';

    funABI.inputs.forEach(function (inp) {
      code += '\n   ' + inp.name + ',';
    });

    code += '\n   {' +
      '\n     from: web3.eth.accounts[0], ' +
      '\n     data: \'' + bytecode + '\', ' +
      '\n     gas: 4700000' +
      '\n   }, function (e, contract){' +
      '\n    console.log(e, contract);' +
      '\n    if (typeof contract.address !== \'undefined\') {' +
      '\n         console.log(\'Contract mined! address: \' + contract.address + \' transactionHash: \' + contract.transactionHash);' +
      '\n    }' +
      '\n })';

    return code;
  }

  function getConstructorInterface (abi) {
    var funABI = { 'name': '', 'inputs': [], 'type': 'constructor', 'outputs': [] };
    for (var i = 0; i < abi.length; i++) {
      if (abi[i].type === 'constructor') {
        funABI.inputs = abi[i].inputs || [];
        break;
      }
    }
    return funABI;
  }
}

module.exports = Renderer;
<|endoftext|>


<commit_before><commit_msg>js改修#126<commit_after><|endoftext|>